
Getty 分层设计
Aliware

Getty 网络端数据流程
Aliware
优化
Aliware
client.Close() 接口把连接池关闭掉。如果上层用户没有调用这个接口把连接池关闭掉,client 就认为对端地址还有效,就会不断尝试发起重连,维护连接池。
-
旧 session 关闭 网络接收 goroutine; -
旧 session 网络发送 goroutine探测到网络接收 goroutine退出后终止网络发送,进行资源回收后设定当前 session 无效; -
client 的轮询 goroutine 检测到无效 session 后把它从 session 连接池删除; -
client 的轮询 goroutine 检测到有效 session 数目少于 getty 上层使用者设定的数目 且 getty 上层使用者没有通过 client.Close()接口关闭连接池时,就调用连接接口发起新连接。
网络发送 goroutine 进行 “废物利用”,在这个 goroutine 标记当前 session 无效的逻辑步骤之后再加上一个逻辑:
-
如果当前 session 的维护者是一个 client【因为 session 的使用者也可能是 server】; -
且如果其当前 session pool 的 session 数量少于上层使用者设定的 session number; -
且如果上层使用者还没有通过 client.Close()设定当前 session pool 无效【即当前 session pool 有效,或者说是对端 server 有效】 -
满足上面三个条件, 网络发送 goroutine执行连接重连即可; -
新网络连接 session 建立成功且被加入 client 的 session pool 后, 网络发送 goroutine使命完成直接退出。
lazy reconnect,网络发送 goroutine 在其生命周期的最后阶段应该被称之为 网络重连 goroutine。通过 lazy reconnect这种方式,上述重连步骤 3 和 步骤 4 的逻辑被合入了步骤 2,client 当然也就没必要再启动一个额外的 goroutine 通过定时轮询的方式维护其 session pool 了。
lazy reconnect 整体流程图如上。如果对相关代码流程感兴趣,请移步 "参考 13" 给出的链接,很容易自行分析出来。
-
一个 goroutine 进行网络字节流的接收、调用 Reader 接口拆解出网络包 (package) -
第二个 goroutine 调用 EventListener.OnMessage()接口进行逻辑处理
-
第三个 goroutine 负责发送网络字节流、调用 EventListener.OnCron()执行定时逻辑以及lazy reconnect
timer wheel(链接见参考 10),兼容 Go 的 timer 所有原生接口,其优点是所有时间任务都在一个 goroutine 内执行。2020 年 12 月把它引入 getty 后,getty 所有的EventListener.OnCron() 定时处理任务均交由 timer wheel 处理,第三个 goroutine 就可以完美地消失了【后续:两个月后发现 timer 库被另一个擅长拉 star 的 rpc 项目 “借鉴” 走了^+^】。
lazy reconnect。当第三个 goroutine 不存在后,这个任务完全可以放入第一个 goroutine:在当网络字节流接收 goroutine 检测到网络错误退出前的最后一个步骤,执行 lazy reconnect。
-
一个 goroutine 进行网络字节流的接收、调用 Reader 接口拆解出网络包 (package)、 lazy reconnect -
第二个 goroutine 调用 EventListener.OnMessage()接口进行逻辑处理、发送网络字节流
发展 timeline
Aliware
-
1 https://github.com/alexstocks/goext/blob/master/container/xorlist/xorlist.go -
2 兼容tcp和websocket的一个简洁网络框架 getty https://gocn.vip/topics/8229 -
3 字节跳动在 Go 网络库上的实践 https://juejin.cn/post/6844904153173458958 -
4 字节跳动 Go RPC 框架 KiteX 性能优化实践 https://mp.weixin.qq.com/s/Xoaoiotl7ZQoG2iXo9_DWg -
5 2021年Go生态圈rpc框架benchmark https://colobu.com/2021/08/01/benchmark-of-rpc-frameworks/ -
6 分布式事务框架 seata-golang 通信模型 https://mp.weixin.qq.com/s/7xoshM4lzqHX9WqANbHAJQ -
7 gr pool https://github.com/dubbogo/gost/blob/master/sync/task_pool.go -
8 A Million WebSockets and Go https://www.freecodecamp.org/news/million-websockets-and-go-cc58418460bb/ -
9 task pool https://github.com/dubbogo/gost/blob/master/sync/base_worker_pool.go -
10 timer wheel https://github.com/dubbogo/gost/blob/master/time/timer.go -
11 getty benchmark https://github.com/apache/dubbo-getty/tree/master/benchmark -
12 benmark result https://github.com/apache/dubbo-getty/pull/61#issuecomment-865698715 -
13 lazy connection https://github.com/AlexStocks/getty/blob/73b0928b957ab6b6773f6cfe95c909ae39001687/transport/client.go#L412

