去年的时候,测试1W条路由的收敛性能,大概需要5s以上,这个成绩比较差,当时分析了一下,认为是路由管理模块不支持路由更新的操作导致的,这样会浪费1倍的消息处理。今年这个问题又重新提起,由于这次有着比较明确的优化目标,因此不再像去年那样纯粹的看代码猜测。
首先,使用perf + 火焰图查看了本进程的热点函数,关掉了一些浪费性能的日志,优化了一些热点,并提供了路由更新的 发功能,现性能从5s到了1.6s。看起来数据很漂亮,但是仔细分析,更新提供的性能提升也就不到1s,热点优化也提供的不多,最大的提升居然是一个2s的定时器!把定时器改为了20ms,节约了大约2s的时间。而这个2s的定时器实际上是不需要这么久的。当时设为2s只是当年的维护人员不熟悉业务逻辑导致的。
由于还没有达到目标,继续优化,此时通过火焰图已经看不出什么东西了。这个时候通过打点,记录关键时间,根据火焰图中的热点函数打了一些点,发现路由管理模块占用了1.3s的时间。进一步分析,发现是上游业务在发送路由时,最后一个消息总是比前面的消息慢了900ms左右时间,经过代码分析,发现又是一个1s的定时器导致的。为了提升消息性能,聚合多个路由消息一起发送,但当消息缓存不满时,设置了1s的定时器。这个定时器直接导致路由管理浪费了1s的时间。修改后,发现路由管理1w条路由只需要 400ms左右的时间,这部分已经接近硬件设备的性能了。
但……总时间仍然是1.6s!继续分析,发现通往转发的表项整合模块有性能瓶颈。前面的1s定时器掩盖了他的瓶颈,取消后暴露了出来。由于这部分是GO编写的,也只能靠打点。这个时候,涉及到GO内部处理的一些东西就不好掌控了(比如内存申请、释放),此时只能感叹还是需要C。