Open jinhailang opened 5 years ago
通过 kafka 消息对规则引擎(as-rule-engine
)处理流程进行压测,计算最大 QPS,查找程序瓶颈,以及可优化的点。
核心处理流程图:
压测的重点是上图中的 rule engine
模块,该模块是规则引擎核心模块,执行规则的匹配和结果计算。为了达到压测核心模块的目的,对入库(写 mysql)模块进行弱化,避免入库成为瓶颈。
Linux test-ccd-1.hz.163.org 4.9.0-7-amd64 #1 SMP Debian 4.9.110-1 (2018-07-05) x86_64 GNU/Linux
Kafka
3 台 Brokers: 10.130.49.21,10.130.49.22,10.130.49.23
2 个 topics: anti.spider.business.uri.ip.onlinejd,anti.spider.business.ip.onlinejd
首先,通过调节生产者生产消息速率,来间接控制规则引擎程序消息处理速率,从而到达分组压测目的。
rule engine
模块并发度可设置,通过设置不同的并发度,进行压测,压测分成四组:
测试步骤:
as-rule-engine
;测试结果:
序号 | 进程数 | 并发数 | 最大 QPS(k) |
---|---|---|---|
1 | 1 | 1 | 1.7 |
2 | 1 | 5 | 1.8 |
3 | 1 | 10 | 1.8 |
4 | 2 | 1 | 3.5 |
首先,从测试结果可以发现,程序单机最大 QPS 在 1.8k 左右,而且核心模块的并发数对整个程序的性能影响很小。这就说明,程序测性能瓶颈不在核心模块,并且结合上面的流程图,可以推测,瓶颈在 kafka 消息处理(consumer) 模块。
其实,在第 4 组的测试时,在两个不同机器启动规则引擎程序,最大 QPS 结果约等于单进程时的 2 倍,就可以说明 QPS 与 消费者数量成正比。
为了进一步证明,通过 go pprof
工具获取规则引擎压测时的 CPU 火焰图。
可以发现,在不考虑系统调用(runtime
)的情况下,核心模块(Handle.func1
)明显低于 consumer
模块耗费 CPU 时间。
PS: 上面的系统调用(runtime
)占比也过高,应该主要是因为程序内使用了太多次锁,加解锁耗费了大量 CPU 时间。
end.
Go 程序性能分析
性能分析的目的是发现程序瓶颈,为代码优化提供指导,以及对优化结果进行量化验证。主要从内存和 CPU 使用两个维度进行分析。 Go 官方提供了功能强大的包和工具
pprof
。使用过程大致分成两步:pprof
文件;go tool pprof
解析pprof
文件,进行分析;下面将详细阐述。
指标收集
有三种实践方式,前两种是在程序内(一般是 main 函数内)导入包 net/http/pprof,或者使用 runtime/pprof 包。 区别是前者提供 HTTP API 接口,可以直接在 Web 页面查看,而后者是在将运行数据写入到本地文件保存。一般都选择使用前者,因为使用更简单,使用 Web 交互也更方便,还可实时查看。
浏览器访问
http://127.0.0.1:6060/debug/pprof/
,可以看到如下内容:需要注意的是,可以指定请求参数
seconds
来收集指定时间内的数据,例如 CPU profile:go tool pprof http://127.0.0.1:6060/debug/pprof/profile?seconds=30
。 我们知道,这样生成的数据文件进行数据分析才更有意义,因为一般我们都是期望对程序某个运行时间段内进行分析。还有一种方式是使用
go test
做性能测试,直接导出pprof
文件:go test -cpuprofile cpu.prof -memprofile mem.prof -bench .
很明显,这种方式更适合对程序某个模块(函数)做性能分析,上面两种方式用来做程序整体的性能分析。
数据分析
生成
pprof
文件后,有两种分析方式:命令交互式和 Web 图形式。两种方式都是使用命令工具go tool pprof
。go tool pprof ./profile
进入交互模式,可以查看 top, 生成图片(需要安装 Graphviz 支持)或生成 DOT 格式图片(需要使用 Graphviz 转换成常见图片格式)等;pprof -http=":8081" [binary] ./profile
创建 Web 服务,可以直接在 Web 页面查看调用图,火焰图甚至源代码等,非常方便,直观;结合前面“指标收集”阶段,可以使用 API 方式获取
pprof
数据,这里还可以直接使用 url 请求来分析,以分析 5 分钟内 CPU 使用情况为例:go tool pprof -http="127.0.0.1:8081" main.go http://127.0.0.1:6060/debug/pprof/profile?seconds=300
这么做的好处是可以实时对 CPU,内存等维度进行分析,且可以任意切换维度。
火焰图
火焰图是常用的性能分析工具,非常直观。对于很多语言来说(比如 Lua)生成火焰图的过程是很繁琐的,要借助一堆工具。在 Go 1.11 之前一般也是借助开源工具 go-torch,不过 Go 1.11 对
go tool pprof
进行了功能增强,可以直接生成火焰图等图形,因此,go-torch 项目也已经废弃了。火焰图就是看顶层的哪个函数占据的宽度最大。只要有"平顶"(plateaus),就表示该函数可能存在性能问题。
小结
前面介绍了 Go 程序性能分析的过程,需要主要的是,只有对程序进行压测(程序达到瓶颈)的情况下,进行性能分析才有意义。 下面是工作中的一次实践过程 --- 程序压测与性能分析总结报告,作为参考。
参考
附:常用命令
top
查看进程 CPU,内存等使用情况free
查看系统内存使用情况uname -a
查看系统内核信息cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
CPU 个数cat /proc/cpuinfo| grep "cpu cores"| uniq
CPU 核数