经过半年改进,dubbo-getty 发布了 v1.5.0 版本,致力于提升稳定性,并修复已知问题,为用户提供更可靠的网络通信服务。
如昔,依然坚持 "Getty 只考虑使用 Go 语言原生的网络接口,如果遇到网络性能瓶颈也只会在自身层面寻找优化突破点" Go 语言网络库 getty 的那些事 。
1. 限制 TCP 客户端重连行为
Getty 支持 TCP lazy reconnect,所谓 lazy reconnect,Go 语言网络库 getty 的那些事 有详细描述。
lazy reconnect 整体流程图如上。
近期社区 No-SilverBullet 筒子觉得:服务端的连接数是动态的,所以我觉得 getty 还是应该有一个兜底的逻辑,而不是 "无脑的" 一直去重连,可以 "添加一个最多重来次数或者重连时间限制":
-
- 客户端在 read EOF 时,停止重连维护连接池的行为
-
- reconnect 增加最大次数,当重连次数超过设定的连接数时,退出
具体改进是:
-
- session 增加了新的 attribute(ignoreReconnectKey),用于标识是否重连
-
- 最大重连次数设定为用户设定的连接数
相关 PR 是 https://github.com/apache/dubbo-getty/pull/117。
2. 修复 WebSocket 并行安全问题
Getty WebSocket 通信依赖于 gorilla/websocket 这个包,进行 WebSocket 网络通信时只能 "支持一个并发 reader 和一个并发 writer"。
Connections support one concurrent reader and one concurrent writer.
Applications are responsible for ensuring that no more than one goroutine calls the write methods (NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and that no more than one goroutine calls the read methods (NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler) concurrently.
The Close and WriteControl methods can be called concurrently with all other methods.
-- from https://pkg.go.dev/github.com/gorilla/websocket#hdr-Concurrency
Getty WebSocket 以往没有注意到这个规则,近期有人在 [issue 120] 中报出了这个 bug,社区筒子立即响应,添加了 gettyWSConn:threadSafeWriteMessage
和 gettyWSConn:threadSafeReadMessage 这两个接口以解决并行通信的 data race 问题,相关代码详见 PR 121 和 PR 123。
相关 PR 是:
https://github.com/apache/dubbo-getty/pull/121
https://github.com/apache/dubbo-getty/pull/123
在 PR 121 中我们顺便解决了 [issue 103] 描述的 session 异常关闭问题。
3 致谢
感谢所有为 Dubbo-Getty 1.5.0 做出贡献的社区成员,包括 issue/PR 提交者、代码 reviewer 以及文章作者【排名不分先后,依据字母序列】:
- chenbaoding2818
- FoghostCn
- Lvnszn
- No-SilverBullet
- seven-ali
alexstocks/getty 作为 dubbo-getty 的上游仓库,已在 alexstocks/gettyv1.5.0 中吸收了本次更新。
另外,我们搜到一些第三方作者对 getty 的解析文章,代表社区向这些传播 getty 的文章作者致敬:
- 用golang实现的dubbo-getty是怎么进行tcp通信的?客户端篇
- 用golang实现的dubbo-getty是怎么进行tcp通信的?服务篇