網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
一、背景
本文描述的是客戶端接收心跳信息的超時(shí)實(shí)現(xiàn)。心跳超時(shí),或者接受信息超過限定時(shí)間在分布式系統(tǒng)中出現(xiàn)的次數(shù)比較多。常見的就有hadoop中節(jié)點(diǎn)超時(shí),或者日志中出現(xiàn)timeout的字樣。
在學(xué)習(xí)go語(yǔ)言中,我也根據(jù)go語(yǔ)言的機(jī)制實(shí)現(xiàn)了心跳超時(shí)的這個(gè)問題。踩過坑,趟過水。
二、心跳超時(shí)的實(shí)現(xiàn)
2.1 通過select case (設(shè)計(jì)概念比較多)
這種方法實(shí)現(xiàn)心跳,需要對(duì)go語(yǔ)言中的channel和select case 機(jī)制有所了解。select代碼段中沒有包含default條件時(shí),會(huì)一直阻塞到有通道操作。
需要注意的是!!!! select語(yǔ)言只會(huì)阻塞一次,且執(zhí)行一次。如果需要多次判斷,或者可能有多個(gè)case條件需要滿足,那就需要增加for語(yǔ)句。
首先需要知道的是select是專為channel設(shè)計(jì)的,所以說每個(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 通過time.sleep(簡(jiǎn)單有效)
通過time.sleep()實(shí)現(xiàn)超時(shí)操作,是比較巧妙的。一般來說心跳超時(shí)是一個(gè)雙方交互的行為。
下面畫一個(gè)圖來描述一下。
?為了方便理解,定義雙方都使用共同時(shí)間。
下面是代碼。
基本的邏輯是:
? ? ? ? 1、先給客戶端設(shè)置一個(gè)下次超時(shí)的時(shí)間
? ? ? ? ?2、客戶端每次收到心跳的時(shí)候,更新這個(gè)時(shí)間
? ? ? ? ?3、開啟一個(gè)獨(dú)立的線程,一致判斷當(dāng)前客戶端是否超時(shí)。
ps:結(jié)合時(shí)效和性能,可以間隔一定的時(shí)間來進(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) } //開啟一個(gè)gp,每隔500ms判斷有沒有超時(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) } } } //客戶端收到以后,修改下次心跳超時(shí)時(shí)間 func (client *Client) receiveHeart() { client.freshTimeOutTime() } //開啟一個(gè)模擬ping 客戶端的線程 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沒有太多的??語(yǔ)言相關(guān)的語(yǔ)法和知識(shí),更容易理解和掌握。相對(duì)于channel來說,掌握需要了解channel的基本使用方法,一些常見的特性等。
原文鏈接:https://blog.csdn.net/alike_u/article/details/123763980
相關(guān)推薦
- 2022-04-08 Python裝飾器中@property使用詳解_python
- 2022-03-17 總結(jié)C#處理異常的方式_C#教程
- 2022-09-23 Windows?10搭建FTP服務(wù)器圖文教程_FTP服務(wù)器
- 2023-08-01 el-date-picker組件中渲染多余文字
- 2022-09-29 kotlin源碼結(jié)構(gòu)層次詳解_Android
- 2023-03-29 Python中命令行參數(shù)argparse模塊的使用_python
- 2024-04-04 multipartFile轉(zhuǎn)file類型方法
- 2022-07-02 C++精要分析decltype的作用及用法_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支