使用Go语言实现心跳机制

 更新时间:2024年01月31日 15:11:47   作者:banjming  
心跳最典型的应用场景是是探测服务是否存活,这篇文章主要来和大家介绍一下如何使用Go语言实现一个简单的心跳程序,感兴趣的可以了解下

Go 实现心跳

心跳最典型的应用场景是是探测服务是否存活,比如在 Zookeeper 中,会使用心跳探测服务是否存货,如果服务已经死亡,会将服务从注册表中删除,避免服务请求路由到一个已经宕机的服务中。

Go 中实现心跳机制可以通过 time.NewTimeTicker(), 配合 channel 使用,就可以实现一个简单的心跳程序:

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 {
		// 上报心跳包的逻辑,可以在这里实现
		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)
	}
}

执行结果如下:

=== 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

心跳程序

客户端发送心跳请求, 并通过重试机制。判断重试X次失败认为服务离线 服务端响应心跳请求,通过超时机制。超时X秒未收到心跳则判断客户端离线

package main

import (
	"fmt"
	"net"
	"time"
)

func main() {
	// 启动服务端
	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,定时发送心跳消息
	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
			}
		}
	}()

	// 循环读取客户端发送的消息
	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()

	//
}

到此这篇关于使用Go语言实现心跳机制的文章就介绍到这了,更多相关Go心跳内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • golang中按照结构体的某个字段排序实例代码

    golang中按照结构体的某个字段排序实例代码

    在任何编程语言中,关乎到数据的排序都会有对应的策略,下面这篇文章主要给大家介绍了关于golang中按照结构体的某个字段排序的相关资料,需要的朋友可以参考下
    2022-05-05
  • Go高级特性探究之协程池详解

    Go高级特性探究之协程池详解

    在并发编程中,协程是 Go 语言的核心特性之一,本文将介绍如何使用 Go 协程池构造一个协程池,并解决函数传参问题、优雅关闭协程池和保证协程安全的问题,感兴趣的可以了解一下
    2023-06-06
  • golang gc的内部优化详细介绍

    golang gc的内部优化详细介绍

    Go编译器在垃圾回收(GC)的扫描标记阶段,对存储无指针键值对的map进行了优化,即在GC扫描时不深入扫描map内部数据,只检查map本身是否需要回收,这一优化显著提升了GC扫描的速度,从而减少了GC对程序性能的影响
    2024-10-10
  • Golang连接Redis数据库的方法

    Golang连接Redis数据库的方法

    这篇文章主要介绍了Golang连接Redis数据库的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • golang程序进度条实现示例详解

    golang程序进度条实现示例详解

    这篇文章主要为大家介绍了golang程序实现进度条示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • GO语言实现简单的目录复制功能

    GO语言实现简单的目录复制功能

    这篇文章主要介绍了GO语言实现简单的目录复制功能,通过新建及复制内容等操作最终实现复制目录的功能效果,具有一定的参考借鉴价值,需要的朋友可以参考下
    2014-12-12
  • golang中字符串和数字转换方法

    golang中字符串和数字转换方法

    在Golang中,可以使用strconv包中的Itoa()和Atoi()函数进行字符串与数字之间的转换,Itoa()用于将数字转换为字符串,Atoi()则用于将字符串转换回数字,本文介绍golang中字符串和数字转换方法,感兴趣的朋友一起看看吧
    2024-09-09
  • beego获取ajax数据的实例

    beego获取ajax数据的实例

    下面小编就为大家分享一篇beego获取ajax数据的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • Go 使用xorm操作mysql详情

    Go 使用xorm操作mysql详情

    这篇文章主要介绍了Go 使用xorm操作mysql详情,golang orm 库 xorm 的使用和项目结构。更多详细neural,需要的小伙伴可以参考下面文章内容
    2022-01-01
  • 详解Golang中链表的创建和读取

    详解Golang中链表的创建和读取

    这篇文章主要为大家详细介绍了Golang中链表的创建和读取的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起了解下
    2023-12-12

最新评论