【Go 夜读】第 15 期 多路复用资源池组件剖析

yangwen13 · · 408 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

>文章来自于:https://reading.developerlearning.cn/reading/15-2018-08-23-pool-workshop-in-go/ ## 观看视频 https://youtu.be/CDfrRzgmR4E >2018-08-23 22:00:00 分享会之后的答疑。 ---- 源代码地址:[pool#workshop](https://github.com/henrylee2cn/goutil/blob/master/pool/workshop.go) 一个网友在分享会之后的个人理解:对是独占资源对象的复用,提升了最后的 qps,独占式方法 `TestChanPool()` 函数中使用了从资源池获取 worker 对象,执行完毕后再放回资源池,如果获取不到则阻塞等待,因此,100 000 请求,每个请求占用 10ms,可用 worker 对象 50 个,则最后 `100 000*10/50 =20s` ,视频中测试结果也显示 21s 符合预期。而 `TestWorkshop()` 函数中使用回调函数对 worker 进行加锁,每个线程使用的那一刻是 worker 对象是被独占的,而后续的 `do{sleep(10ms)}` 是并发执行的,并且根据每个 worker 同时执行的 do 的任务数,进行负载均衡,所以最后测试性能 QPS 能够有 20 倍的提升。 >workshop 中每个协程只在获得 worker 的那一刻是互斥的,且不会从池子中移除,通过状态统计达到资源的负载均衡。在业务上真正使用资源时其实是无锁状态,所以能被其他协程同时使用,进而吞吐量提升。业务逻辑耗时越长,相比独占式资源池的吞吐量优势越显著。本机测试 50 个资源 10ms 时可提升 20 倍。 ### 为什么不使用轮询使用资源,代码实现会更简单? >实际场景中每次业务逻辑耗时不相同,轮询并不能保证真的负载均衡。尤其是当突发异常时,可能导致负载失衡。 ### 为什么长连接异步通信不使用一条连接而是连接池? 说到长连接异步通信,为什么不使用一条连接而是连接池,其实涉及到多条连接抢占带宽和 TCP 丢包后速率下降的问题。这对于下载场景(迅雷就是这么做的)和使用共享云主机的场景比较有用。 具体可以看这篇文章:[为什么多 TCP 连接比单TCP连接传输快](https://segmentfault.com/a/1190000008803687) >以前在做加速的一项就是多线程下载,开启多个 tcp 连接,同时下载,比只有一个连接下载快多了。 ### workshop 的使用场景 使用 workshop 的前提就是该资源可以被同时使用,比如长连接的异步IO通信。 对于长连接异步通信时,如果使用了独占式连接池只会起到反效果,让它和同步通信没差别,还不如不用池子。workshop 就是适用于这个场景的。 ### 长连接:同步和异步方式。 同步方式下客户端所有请求共用同一连接,在获得连接后要对连接加锁,在读写结束后才解锁释放连接,性能低下,基本很少采用,唯一优点是实现极其简单。 异步方式下所有请求都带有消息ID,因此可以批量发送请求,异步接收回复,所有请求和回复的消息都共享同一连接,信道得到最大化利用,因此吞吐量最大。 这个时候接收端的处理能力也要求比较高,一般都是独立的一个(或者多个)收包线程(或者进程)防止内核缓冲区被填满影响网络吞吐量。缺点是实现复杂,需要异步状态机,需要增加负载均衡和连接健康度检测机制,等等。 workshop 就是实现了上述多条异步连接间的负载均衡,健康检测等。 ## 参考资料 1. [为什么多 TCP 连接比单TCP连接传输快](https://segmentfault.com/a/1190000008803687)

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

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

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