1 概述

Dubbo-Getty 1.4.10 版本带来了一些重要的改进和修复,旨在提高性能和稳定性,不过依然坚持 “Getty 只考虑使用 Go 语言原生的网络接口,如果遇到网络性能瓶颈也只会在自身层面寻找优化突破点” 【Go 语言网络库 getty 的那些事】。

以下是本次发布的主要亮点和更新。

2 主要更新

2.1 Timer 优化算法禁用

2016 年开始构建 getty 网络库时,当时 Go 语言的 timer 实现很低效,有一个有名的 “一把全局大锁” 的问题 (the global timers mutex),详见 issue https://github.com/golang/go/issues/15133 。Getty 借鉴当时 fasthttp 的实现,在使用 SetReadDeadline 和 SetWriteDeadline 两个函数时,有如下类似代码:

// Optimization: update read deadline only if more than 25%
    // of the last read deadline exceeded.
    // See https://github.com/golang/go/issues/15133 for details.
    currentTime = time.Now()
    if currentTime.Sub(t.rLastDeadline.Load()) > t.rTimeout.Load()>>2 {
        if err = t.conn.SetReadDeadline(currentTime.Add(t.rTimeout.Load())); err != nil {
            // just a timeout error
            return 0, perrors.WithStack(err)
        }
        t.rLastDeadline.Store(currentTime)
    }

2021 年拼多多的朋友发现这项 “优化” 会造成超时时间 “漂移” 问题,详见 https://github.com/AlexStocks/getty/issues/14#issuecomment-972583219。

近几年随着 Go Timer 的性能优化,Go 1.1x 版本能做到把每个 timer 绑定多核减小锁粒度,Go 1.2x 已经通过 “时间轮” 进一步优化,timer 已经没有了 CPU 使用率过高的问题,详见 https://github.com/golang/go/issues/15133#issuecomment-271571395 。

所以在 PR https://github.com/apache/dubbo-getty/pull/109 中禁用了 SetReadDeadline 和 SetWriteDeadline 优化算法。这个更改将有助于减少不必要的性能开销,并确保应用程序能够更高效地处理 I/O 操作。

2.2 Go 版本升级

PR https://github.com/apache/dubbo-getty/pull/112/files 将 Go 语言版本从 1.14 升级到 1.20。这个升级不仅带来了 Go 语言的新特性和改进,还提高了整体的安全性和稳定性:

  • 使用 os.ReadFile 替换了 ioutil.ReadFile
  • 使用 net.Timeout 替换了 net. Temporary

2.3 添加网络任务处理时先 check 连接是否关闭

当请求过多时,Getty 一直在调用 encode 或者 decode 逻辑导致 CPU 飙升,从消息和请求时间结合看的话,应该是请求过多。

在 PR https://github.com/apache/dubbo-getty/pull/108 中,在 conn close 的时候直接把相关过时的网络请求抛掉,不做这些耗 CPU 的逻辑。

2.4 修复 TLS 死循环 bug

Getty 支持 TCP/UDP/Websocket 三种通信协议,在 TCP 之上还提供了 TLS 安全通信,近期杭州一家公司的朋友在使用 TLS 时发现一个死循环 bug:把 demo/hello/tls/server/server.go 服务跑起来,然后用 telnet 127.0.0.1 8090服务端程序就会陷入死循环,把一个 CPU 打满。

其原因是 TLS 握手时没有设置超时时间。这位朋友在 PR https://github.com/apache/dubbo-getty/pull/115 中修复了该 bug。

3 贡献者

感谢以下贡献者对 Dubbo-Getty 1.4.10 版本的支持和贡献【排名不分先后,依据字母序列】:

  • DMwangnima
  • hongshengjie
  • Lvnszn

alexstocks/getty 作为 dubbo-getty 的上游仓库,已经在 PR https://github.com/AlexStocks/getty/pull/79 中吸收了本次更新,将要发布的 alexstocks/getty v1.3.3 中将会包含这些更新。