亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

go語(yǔ)言心跳超時(shí)的實(shí)現(xiàn)示例

 更新時(shí)間:2022年05月13日 11:46:19   作者:大錘愛(ài)編程  
本文主要介紹了go語(yǔ)言心跳超時(shí)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、背景

本文描述的是客戶(hù)端接收心跳信息的超時(shí)實(shí)現(xiàn)。心跳超時(shí),或者接受信息超過(guò)限定時(shí)間在分布式系統(tǒng)中出現(xiàn)的次數(shù)比較多。常見(jiàn)的就有hadoop中節(jié)點(diǎn)超時(shí),或者日志中出現(xiàn)timeout的字樣。

在學(xué)習(xí)go語(yǔ)言中,我也根據(jù)go語(yǔ)言的機(jī)制實(shí)現(xiàn)了心跳超時(shí)的這個(gè)問(wèn)題。踩過(guò)坑,趟過(guò)水。

二、心跳超時(shí)的實(shí)現(xiàn)

2.1 通過(guò)select case (設(shè)計(jì)概念比較多)

這種方法實(shí)現(xiàn)心跳,需要對(duì)go語(yǔ)言中的channel和select case 機(jī)制有所了解。select代碼段中沒(méi)有包含default條件時(shí),會(huì)一直阻塞到有通道操作。

需要注意的是?。。?! select語(yǔ)言只會(huì)阻塞一次,且執(zhí)行一次。如果需要多次判斷,或者可能有多個(gè)case條件需要滿足,那就需要增加for語(yǔ)句。

首先需要知道的是select是專(zhuān)為channel設(shè)計(jì)的,所以說(shuō)每個(gè)case表達(dá)式都必須是包含操作通道的表達(dá)式。下面這段代碼是描述了隨機(jī)抽取一個(gè)channel發(fā)消息,正常情況下,不會(huì)觸發(fā)超時(shí)。為了觸發(fā)超時(shí),注釋掉通道發(fā)送數(shù)據(jù)操作。超時(shí)五秒,則觸發(fā)超時(shí)。

package main
 
import (
    "fmt"
    "math/rand"
    "time"
)
 
func main() {
    // 準(zhǔn)備好三個(gè)通道。
    intChannels := [3]chan int{
        make(chan int, 1),
        make(chan int, 1),
        make(chan int, 1),
    }
    // 隨機(jī)選擇一個(gè)通道,并向它發(fā)送元素值。
    index := rand.Intn(3)
    fmt.Printf("The index: %d\n", index)
 
    //?? 取消這行代碼的注視,超時(shí)條件的選擇就會(huì)觸發(fā)。
    //intChannels[index] <- index
    // 哪一個(gè)通道中有可取的元素值,哪個(gè)對(duì)應(yīng)的分支就會(huì)被執(zhí)行。
    select {
    case <-intChannels[0]:
        fmt.Println("The first candidate case is selected.")
    case <-intChannels[1]:
        fmt.Println("The second candidate case is selected.")
    case elem := <-intChannels[2]:
        fmt.Printf("The third candidate case is selected, the element is %d.\n", elem)
    case <-time.After(5 * time.Second):
        fmt.Println("timed out")
    }
}

2.2 通過(guò)time.sleep(簡(jiǎn)單有效)

通過(guò)time.sleep()實(shí)現(xiàn)超時(shí)操作,是比較巧妙的。一般來(lái)說(shuō)心跳超時(shí)是一個(gè)雙方交互的行為。

下面畫(huà)一個(gè)圖來(lái)描述一下。

 為了方便理解,定義雙方都使用共同時(shí)間。

下面是代碼。

基本的邏輯是:

        1、先給客戶(hù)端設(shè)置一個(gè)下次超時(shí)的時(shí)間

         2、客戶(hù)端每次收到心跳的時(shí)候,更新這個(gè)時(shí)間

         3、開(kāi)啟一個(gè)獨(dú)立的線程,一致判斷當(dāng)前客戶(hù)端是否超時(shí)。

ps:結(jié)合時(shí)效和性能,可以間隔一定的時(shí)間來(lái)進(jìn)行判斷。

package main
 
import (
    "fmt"
    "sync"
    "time"
)
 
type Client struct {
    lock sync.Mutex //加鎖
    nextTimeOutTime time.Time //下次超時(shí)時(shí)間
}
 
const tenSec = 10
/**
刷新每次的心跳超時(shí)機(jī)制
 */
func (client *Client) freshTimeOutTime()  {
    client.lock.Lock()
    defer client.lock.Unlock()
    client.nextTimeOutTime =time.Now().Add(tenSec*time.Second)
}
 
//開(kāi)啟一個(gè)gp,每隔500ms判斷有沒(méi)有超時(shí)
func (client *Client) judgeTimeOut()  {
    for  {
        time.Sleep(500*time.Millisecond)
        fmt.Printf("%v 在判斷是否超時(shí)\n", client.nextTimeOutTime)
        if time.Now().After(client.nextTimeOutTime) {
            fmt.Printf("%v 超時(shí)了\n", client.nextTimeOutTime)
        }
    }
}
 
//客戶(hù)端收到以后,修改下次心跳超時(shí)時(shí)間
func (client *Client) receiveHeart()  {
    client.freshTimeOutTime()
}
 
//開(kāi)啟一個(gè)模擬ping 客戶(hù)端的線程
func pingClient(client *Client)  {
    for true {
        time.Sleep(11*time.Second)
        fmt.Printf("%v 請(qǐng)求發(fā)送時(shí)間\n", time.Now())
        client.receiveHeart()
    }
 
}
 
func main() {
    client := Client{
        lock:            sync.Mutex{},
        nextTimeOutTime: time.Time{},
    }
    //在當(dāng)前時(shí)刻,更新下次的超時(shí)時(shí)刻是10s中后
    client.freshTimeOutTime()
 
 
    go pingClient(&client)
 
 
    go client.judgeTimeOut()
 
    for true {
 
    }
}

三、個(gè)人的實(shí)現(xiàn)觀感

使用select case 和 time.sleep實(shí)現(xiàn)超時(shí)的最大區(qū)別在于,time.sleep沒(méi)有太多的??語(yǔ)言相關(guān)的語(yǔ)法和知識(shí),更容易理解和掌握。相對(duì)于channel來(lái)說(shuō),掌握需要了解channel的基本使用方法,一些常見(jiàn)的特性等。

到此這篇關(guān)于go語(yǔ)言心跳超時(shí)的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)go語(yǔ)言心跳超時(shí)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go-zero熔斷機(jī)制組件Breaker接口定義使用解析

    go-zero熔斷機(jī)制組件Breaker接口定義使用解析

    這篇文章主要為大家介紹了go-zero熔斷機(jī)制組件Breaker接口定義使用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • GO中sync包自由控制并發(fā)示例詳解

    GO中sync包自由控制并發(fā)示例詳解

    這篇文章主要為大家介紹了GO中sync包自由控制并發(fā)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Go語(yǔ)言中日期包(time包)的具體使用

    Go語(yǔ)言中日期包(time包)的具體使用

    本文主要介紹了Go語(yǔ)言中日期包的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 利用go-kit組件進(jìn)行服務(wù)注冊(cè)與發(fā)現(xiàn)和健康檢查的操作

    利用go-kit組件進(jìn)行服務(wù)注冊(cè)與發(fā)現(xiàn)和健康檢查的操作

    這篇文章主要介紹了利用go-kit組件進(jìn)行服務(wù)注冊(cè)與發(fā)現(xiàn)和健康檢查的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • Golang中的sync.WaitGroup用法實(shí)例

    Golang中的sync.WaitGroup用法實(shí)例

    這篇文章主要介紹了Golang中的sync.WaitGroup用法實(shí)例,WaitGroup的用途,它能夠一直等到所有的goroutine執(zhí)行完成,并且阻塞主線程的執(zhí)行,直到所有的goroutine執(zhí)行完成,需要的朋友可以參考下
    2015-07-07
  • Go gRPC環(huán)境安裝教程示例詳解

    Go gRPC環(huán)境安裝教程示例詳解

    這篇文章主要為大家介紹了Go gRPC環(huán)境安裝的教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 深入了解Golang中reflect反射基本原理

    深入了解Golang中reflect反射基本原理

    反射是這樣一種機(jī)制,它是可以讓我們?cè)诔绦蜻\(yùn)行時(shí)(runtime)訪問(wèn)、檢測(cè)和修改對(duì)象本身狀態(tài)或行為的一種能力。本文主要帶大家來(lái)看看Golang中reflect反射基本原理,需要的可以參考一下
    2023-01-01
  • Golang常用包使用介紹

    Golang常用包使用介紹

    標(biāo)準(zhǔn)的Go語(yǔ)言代碼庫(kù)中包含了大量的包,并且在安裝Go的時(shí)候多數(shù)會(huì)自動(dòng)安裝到系統(tǒng)中。我們可以在$GOROOT/src/pkg目錄中查看這些包。下面簡(jiǎn)單介紹一些我們開(kāi)發(fā)中常用的包
    2022-09-09
  • Go語(yǔ)言中接口組合的實(shí)現(xiàn)方法

    Go語(yǔ)言中接口組合的實(shí)現(xiàn)方法

    這篇文章主要介紹了Go語(yǔ)言中接口組合的實(shí)現(xiàn)方法,實(shí)例分析了接口中包含接口的實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-02-02
  • Go設(shè)計(jì)模式之策略模式講解和代碼示例

    Go設(shè)計(jì)模式之策略模式講解和代碼示例

    策略是一種行為設(shè)計(jì)模式,?它將一組行為轉(zhuǎn)換為對(duì)象,?并使其在原始上下文對(duì)象內(nèi)部能夠相互替換,本文就將通過(guò)代碼示例給大家詳細(xì)的介紹一下Go的策略模式,需要的朋友可以參考下
    2023-08-08

最新評(píng)論