Go 1.12最新特性 - 实际项目为背景的详解-LMLPHP

Go 1.12带来了正式的Go module支持、初步的TLS 1.3支持、runtime和标准库做了各项提高,工具也有所改进,trace方面引入minimum mutator utilization图的支持方便GC性能的调校。

本文通过近期发布的高性能分布式共识库Dragonboat为背景,从实际项目角度详解各新特性。

Go Module支持

上个Go发布版本的初步Go module支持是默认关闭的,这暗示了它留有很多实现问题,事实上当时replace的支持连module、package、import path三个最基本概念都是含混的。Go 1.12中这些问题都得到了解决,Go module的正式发布又关闭了一条无脑喷Go的路径,真正的Go用户可以更安心方便的使用Go。

Dragonboat为例,对普通用户,下列两行的一个go.mod就完整定义了Dragonboat库的依赖情况。

module [github.com/lni/dragonboat](http://github.com/lni/dragonboat)

require [github.com/golang/protobuf](http://github.com/golang/protobuf) v1.2.0

Dragopnboat所用的Monkey Test需要Drummer包,它的额外依赖中含有golang.org下的数个包。我们需要用位于github.com上的官方镜像来代替它们。Go module的replace支持可以通过在go.mod文件中增加下列替换条目,将受影响的import path进行替换。示例如下:

replace (
  golang.org/x/build => github.com/golang/build v0.0.0-20190215225244-0261b66eb045
  golang.org/x/text => github.com/golang/text v0.3.0
)

更低的STW延迟

Go 1.12版的STW停顿较1.11版又有明显的缩短。下图是Dragonboat在每秒处理超过800万次16字节的Proposals时由runtime.ReadMemStats报告的120个连续GC周期的STW停顿值,1.12与1.11对比,STW明显下降,由350微秒降至250微秒左右。

Go 1.12最新特性 - 实际项目为背景的详解-LMLPHP

Minimum Mutator Utilization图的支持

Mutator Utilization衡量的是GC耗费的资源外应用究竟获得了多少CPU资源。Minimum Mutator Utilization图则是在不同的时间窗口上呈现应用至少可以获得多少CPU资源。Go 1.12的trace工具加入了Minimum Mutator Utilization图的支持,它可以及其方便的发现GC性能受限的情况。

下图是Dragonboat在处理16字节的proposals时候的Minimum Mutator Utilization图。图上可见,在时间窗口小于250微秒的时候,应用最坏情况下得不到任何CPU,这是因为STW的长度基本就是250微秒。而当时间窗口不断放大,Minimum Mutator Utilization快速上升并趋向于100%并最后基本稳定于98%左右。这表示从整个trace的执行周期看(最大时间窗口),最坏情况下应用可以保证得到98%的CPU时间。可见,本例没有任何针对GC优化的价值了。

Go 1.12最新特性 - 实际项目为背景的详解-LMLPHP

Dragonboat在处理1024字节的proposals时候的Minimum Mutator Utilization图则展现了另外一个局面。在1.3毫秒内,应用最坏情况可以获得的CPU资源都是0,暗示此时STW比16字节时高一个数量级。而随着时间窗口的扩大,Minimum Mutator Utilization逐渐逼近并稳定于90%左右,从整个trace的执行周期看,最坏情况下应用可以保证得到90%的CPU时间。更高的STW、更多的GC所占用的CPU资源都清楚显示在此场景下继续做内存使用的优化是一定预期收益的,Minimum Mutator Utilization相当直观方便。

Go 1.12最新特性 - 实际项目为背景的详解-LMLPHP

初步的TLS 1.3支持

Go 1.12较为及时的提供了初步的TLS 1.3支持。TLS 1.3淘汰了DES、MD5、RC4、SHA1之类的博物馆级别的老旧且有明确安全隐患的算法,支持一个RTT完成所需准备建立安全链接。

Go 1.12内建的TLS 1.3性能跑分来看,TLS 1.3的跑分性能和1.2差别不大,未来也还有一定优化空间。有兴趣的可以在自己的目标服务器上测试跑分性能:

go test -v crypto/tls -run=$^ -bench BenchmarkThroughput

TLS 1.3的0-RTT特性尚未提供支持,该功能本身的安全隐患的讨论,与Go这种通用语言的标准库实现并无太大关系,这里不展开。

其它各项改进

Dragonboat这样的高性能、分布式系统库相关的一些改进还有:

  • Timer与Deadline的性能得到了优化,connection上的deadline设置的代价降低了
  • TCP KeepAlive默认启用
  • os包开始提供UserHomeDir函数,不再需要用第三方库来跨平台支持了
  • macOS的上调用File.Sync并不能确保实际落盘的问题得到了解决

具体所有的改进和变更可以看1.12文档

最后,感谢阅读,并请访问Dragonboat的github页面点star支持。谢谢!

02-23 08:30