分享
  1. 首页
  2. 文章

golang:使用timingwheel进行大量ticker的优化

moxiaopeng · · 4097 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Ticker

最近的项目用go实现的服务器需要挂载大量的socket连接。如何判断连接是否还存活就是我们需要考虑的一个问题了。

通常情况下面,socket如果被客户端正常close,服务器是能检测到的,但是如果客户端突然拔掉网线,或者是断电,那么socket的状态在服务器看来可能仍然是established。而实际上该socket已经不可用了。

为了判断连接是否可用,通常我们会用timer机制来定时检测,在go里面,这非常容易实现,如下:

ticker := time.NewTicker(60 * time.Second)
for {
 select {
 case <-ticker.C:
 if err := ping(); err != nil {
 close()
 }
 }
}

上面我们使用一个60s的ticker,定时去ping,如果ping失败了,证明连接已经断开了,这时候就需要close了。

这套机制比较简单,也运行的很好,直到我们的服务器连上了10w+的连接。因为每一个连接都有一个ticker,所以同时会有大量的ticker运行,cpu一直在30%左右徘徊,性能不能让人接受。

其实,我们只需要的是一套高效的超时通知机制。

Close channel to broadcast

在go里面,channel是一个很不错的东西,我们可以通过close channel来进行broadcast。如下:

ch := make(bool)
for i := 0; i < 10; i++ {
 go func() {
 println("begin")
 <-ch
 println("end")
 }
}
time.Sleep(10 * time.Second)
close(ch)

上面,我们启动了10个goroutine,它们都会因为等待ch的数据而block,10s之后close这个channel,那么所有等待该channel的goroutine就会继续往下执行。

TimingWheel

通过channel这种close broadcast机制,我们可以非常方便的实现一个timer,timer有一个channel ch,所有需要在某一个时间 "T" 收到通知的goroutine都可以尝试读该ch,当T到达时候,close该ch,那么所有的goroutine都能收到该事件了。

timingwheel的使用很简单,首先我们创建一个wheel

//这里我们创建了一个timingwheel,精度是1s,最大的超时等待时间为3600s
w := timingwheel.NewTimingWheel(1 * time.Second, 3600)
//等待10s
<-w.After(10 * time.Second)

因为timingwheel只有一个1s的ticker,并且只创建了3600个channel,系统开销很小。当我们程序换上timingwheel之后,10w+连接cpu开销在10%以下,达到了优化效果。

timingwheel的代码在这里

原文:http://blog.csdn.net/siddontang/article/details/18370541


有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:moxiaopeng

查看原文:golang:使用timingwheel进行大量ticker的优化

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
4097 次点击 ∙ 2 赞
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏