dubbo-go-hessian2 是一个用 Go 实现的 hessian 协议 v2.0 版本的序列化库。从项目名称里可以看到主要用在 dubbo-go 这个项目里。hessian 协议作为 dubbo 的默认协议,因此对性能有比较高的要求。
立项
譬如有网文 基于Go的马蜂窝旅游网分布式IM系统技术实践 把 dubbo-go 与其他 RPC 框架对比如下:
有鉴于此,社区便开始组织部分人力,启动了对 dubbo-go 性能优化【同时也欢迎上文作者到钉钉群 23331795 与我们社区交流】。考察 dubbo-go 的各个组件,大家不约而同地决定首先优化比较独立的 dubbo-go-hessian2。
起步
在最开始的时候,并没有太想清楚需要做什么,改哪个地方,要优化到何种程度,所以最简单的办法就是看看现状。
首先,写了一个简单的例子,把常见的类型到一个结构体里,然后测一下耗时。
type Mix struct {
A int
B string
CA time.Time
CB int64
CC string
CD []float64
D map[string]interface{}
}
m := Mix{A: int('a'), B: `hello`}
m.CD = []float64{1, 2, 3}
// 再加一层,使得数据显得复杂一些
m.D = map[string]interface{}{`floats`: m.CD, `A`: m.A, `m`: m}
看起来这个结构体跟真实环境里可能不太一样,但是用来分析瓶颈应该是足够了。
然后直接靠 Go Test 写个测试用例:
func BenchmarkEncode(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _ = encodeTarget(&m)
}
}
func BenchmarkDecode(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _ = NewDecoder(bytes).Decode()
}
}
go test -benchmem -run=^$ github.com/apache/dubbo-go-hessian2 -bench "^B" -vet=off -v
得到下面结果:
BenchmarkEncode-8 89461 11485 ns/op 3168 B/op 122 allocs/op
BenchmarkDecode-8 64914 19595 ns/op 7448 B/op 224 allocs/op
注:基于 MacBook Pro 2018【主频 Intel Core i7 2.6 GHz】测试。
不与同类库作横向比较,仅仅从这个测试结果里的数字上无法得出任何结论。对我们来说更重要的是:它到底慢在哪里。首先想到的手段便是:借助 pprof 生成火焰图,定位 CPU 消耗。
pprof 工具的用法可以参考