使用Go語言實(shí)現(xiàn)心跳機(jī)制
Go 實(shí)現(xiàn)心跳
心跳最典型的應(yīng)用場景是是探測服務(wù)是否存活,比如在 Zookeeper 中,會使用心跳探測服務(wù)是否存貨,如果服務(wù)已經(jīng)死亡,會將服務(wù)從注冊表中刪除,避免服務(wù)請求路由到一個已經(jīng)宕機(jī)的服務(wù)中。
Go 中實(shí)現(xiàn)心跳機(jī)制可以通過 time.NewTimeTicker(), 配合 channel 使用,就可以實(shí)現(xiàn)一個簡單的心跳程序:
import (
"code.byted.org/gopkg/logs"
"context"
"fmt"
"testing"
"time"
)
func sendHeartbeat(heartbeatChan chan<- time.Time) {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case t := <-ticker.C:
heartbeatChan <- t
}
}
}
func TestHeartbeat(t *testing.T) {
heartbeatChan := make(chan time.Time)
go doWork([]int{1, 2, 3, 5, 5}, heartbeatChan)
for t := range heartbeatChan {
// 上報(bào)心跳包的邏輯,可以在這里實(shí)現(xiàn)
fmt.Println("Received heartbeat at", t)
}
fmt.Println("heartbeat finished")
}
func doWork(nums []int, heartbeatChan chan time.Time) {
go sendHeartbeat(heartbeatChan)
defer func() {
close(heartbeatChan)
}()
for num := range nums {
time.Sleep(1 * time.Second)
fmt.Println(num)
}
}
執(zhí)行結(jié)果如下:
=== RUN TestHeartbeat
0
Received heartbeat at 2024-01-31 11:30:46.3363 +0800 CST m=+1.002830252
Received heartbeat at 2024-01-31 11:30:47.335975 +0800 CST m=+2.002513164
1
Received heartbeat at 2024-01-31 11:30:48.336252 +0800 CST m=+3.002795914
2
Received heartbeat at 2024-01-31 11:30:49.33622 +0800 CST m=+4.002768883
3
Received heartbeat at 2024-01-31 11:30:50.336222 +0800 CST m=+5.002775378
4
heartbeat finished
--- PASS: TestHeartbeat (5.00s)
PASS
心跳程序
客戶端發(fā)送心跳請求, 并通過重試機(jī)制。判斷重試X次失敗認(rèn)為服務(wù)離線 服務(wù)端響應(yīng)心跳請求,通過超時機(jī)制。超時X秒未收到心跳則判斷客戶端離線

package main
import (
"fmt"
"net"
"time"
)
func main() {
// 啟動服務(wù)端
go startServer()
// 啟動客戶端
go startClient()
// 保持 main goroutine 活躍,避免程序退出
select {}
}
func startServer() {
ln, err := net.Listen("tcp", ":8080")
if err != nil {
fmt.Println(err)
return
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
fmt.Println(err)
continue
}
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
// 使用 bufio 包中的 ReadWriter 類型,方便讀寫字符串
rw := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
// 啟動一個 goroutine,定時發(fā)送心跳消息
go func() {
for {
time.Sleep(time.Second)
if _, err := rw.WriteString("heartbeat\n"); err != nil {
fmt.Println(err)
return
}
if err := rw.Flush(); err != nil {
fmt.Println(err)
return
}
}
}()
// 循環(huán)讀取客戶端發(fā)送的消息
for {
line, err := rw.ReadString('\n')
if err != nil {
fmt.Println(err)
return
}
fmt.Println("received:", line)
}
}
func startClient() {
conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
fmt.Println(err)
return
}
defer conn.Close()
//
}
到此這篇關(guān)于使用Go語言實(shí)現(xiàn)心跳機(jī)制的文章就介紹到這了,更多相關(guān)Go心跳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
這些關(guān)于Go中interface{}的注意事項(xiàng)你都了解嗎
這篇文章主要為大家詳細(xì)介紹了學(xué)習(xí)Go語言時需要了解的interface{}注意事項(xiàng),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-03-03
GoLand 中設(shè)置默認(rèn)項(xiàng)目文件夾的實(shí)現(xiàn)
本文主要介紹了GoLand 中設(shè)置默認(rèn)項(xiàng)目文件夾的實(shí)現(xiàn),默認(rèn)項(xiàng)目文件夾會在你打開或新建項(xiàng)目時自動預(yù)選,避免每次都需要手動導(dǎo)航到目標(biāo)目錄,感興趣的可以了解一下2025-03-03
pytorch中的transforms.ToTensor和transforms.Normalize的實(shí)現(xiàn)
本文主要介紹了pytorch中的transforms.ToTensor和transforms.Normalize的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
Go中標(biāo)準(zhǔn)庫fmt包的使用小結(jié)
fmt包是Go語言處理輸入輸出的核心庫,提供Print/Scan系列函數(shù)及多樣格式化動詞(如%v、%d、%s等),支持字符串格式化、掃描、自定義輸出格式及錯誤處理,廣泛用于數(shù)據(jù)格式化與輸出控制,下面就來詳細(xì)的介紹一下2025-09-09
Golang并發(fā)繞不開的重要組件之Goroutine詳解
Goroutine、Channel、Context、Sync都是Golang并發(fā)編程中的幾個重要組件,這篇文中主要為大家介紹了Goroutine的相關(guān)知識,需要的可以參考一下2023-06-06
Go語言中reflect.DeepEqual函數(shù)的具體使用
本文主要介紹了Go語言中reflect.DeepEqual函數(shù)的具體使用,reflect.DeepEqual()函數(shù)是用來比較兩個值是否相等的方法,下面就來介紹一下,感興趣的可以了解一下2024-08-08

