文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

go语言心跳超时怎么实现

2023-06-30 13:43

关注

这篇文章主要介绍了go语言心跳超时怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇go语言心跳超时怎么实现文章都会有所收获,下面我们一起来看看吧。

一、背景

本文描述的是客户端接收心跳信息的超时实现。心跳超时,或者接受信息超过限定时间在分布式系统中出现的次数比较多。常见的就有hadoop中节点超时,或者日志中出现timeout的字样。

二、心跳超时的实现

2.1 通过select case (设计概念比较多)

这种方法实现心跳,需要对go语言中的channel和select case 机制有所了解。select代码段中没有包含default条件时,会一直阻塞到有通道操作。

需要注意的是!!!! select语言只会阻塞一次,且执行一次。如果需要多次判断,或者可能有多个case条件需要满足,那就需要增加for语句。

首先需要知道的是select是专为channel设计的,所以说每个case表达式都必须是包含操作通道的表达式。下面这段代码是描述了随机抽取一个channel发消息,正常情况下,不会触发超时。为了触发超时,注释掉通道发送数据操作。超时五秒,则触发超时。

package main import (    "fmt"    "math/rand"    "time") func main() {    // 准备好三个通道。    intChannels := [3]chan int{        make(chan int, 1),        make(chan int, 1),        make(chan int, 1),    }    // 随机选择一个通道,并向它发送元素值。    index := rand.Intn(3)    fmt.Printf("The index: %d\n", index)     //‼️ 取消这行代码的注视,超时条件的选择就会触发。    //intChannels[index] <- index    // 哪一个通道中有可取的元素值,哪个对应的分支就会被执行。    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(简单有效)

通过time.sleep()实现超时操作,是比较巧妙的。一般来说心跳超时是一个双方交互的行为。

下面画一个图来描述一下。

go语言心跳超时怎么实现

 为了方便理解,定义双方都使用共同时间。

下面是代码。

基本的逻辑是:

        1、先给客户端设置一个下次超时的时间

         2、客户端每次收到心跳的时候,更新这个时间

         3、开启一个独立的线程,一致判断当前客户端是否超时。

ps:结合时效和性能,可以间隔一定的时间来进行判断。

package main import (    "fmt"    "sync"    "time") type Client struct {    lock sync.Mutex //加锁    nextTimeOutTime time.Time //下次超时时间} const tenSec = 10func (client *Client) freshTimeOutTime()  {    client.lock.Lock()    defer client.lock.Unlock()    client.nextTimeOutTime =time.Now().Add(tenSec*time.Second)} //开启一个gp,每隔500ms判断有没有超时func (client *Client) judgeTimeOut()  {    for  {        time.Sleep(500*time.Millisecond)        fmt.Printf("%v 在判断是否超时\n", client.nextTimeOutTime)        if time.Now().After(client.nextTimeOutTime) {            fmt.Printf("%v 超时了\n", client.nextTimeOutTime)        }    }} //客户端收到以后,修改下次心跳超时时间func (client *Client) receiveHeart()  {    client.freshTimeOutTime()} //开启一个模拟ping 客户端的线程func pingClient(client *Client)  {    for true {        time.Sleep(11*time.Second)        fmt.Printf("%v 请求发送时间\n", time.Now())        client.receiveHeart()    } } func main() {    client := Client{        lock:            sync.Mutex{},        nextTimeOutTime: time.Time{},    }    //在当前时刻,更新下次的超时时刻是10s中后    client.freshTimeOutTime()      go pingClient(&client)      go client.judgeTimeOut()     for true {     }}

关于“go语言心跳超时怎么实现”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“go语言心跳超时怎么实现”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯