57

我是怎么一步步用go找出压测性能瓶颈

 5 years ago
source link: https://studygolang.com/articles/13849?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~

本文由 mariolu 发表于 云+社区专栏

序言:

​ 笔者要在线上服务器load日志并且重放来测一些机器性能指标。模拟机器资源比较少,相对的被模拟的线上机器日志量大,假设线上单机qps有1w,那么5台机器组成的集群5w个qps。模拟机器压测客户端需要比5w个qps更快,才有比较意义。

第一章:HTTP初体验

​ 正所谓“人生苦短,我用python”,python自带了urllib2、urllib3以及第三方的request。支持的代理访问、添加请求头基本满足功能需求。笔者用urllib2+multiprocessing库顺利了码完代码运行之,查看qps只有2k多,这显然远远低于需求。在加大进程数到cpu核数的数倍之多,也发现python仅能达到3k多。事出必有因,于是笔者便通过监控界面和shell小工具来找机器各种茬。

第二章:“中世纪黑暗期”

​ 中世纪是黑暗漫长的时期,你做了很多事情,但却输出很少,留下来的是尝试后的经验总结。从cpu、内存、硬盘、网络各方面数据看。cpu使用率90%多,内存用满、硬盘wa很低、网络千兆网卡满载。最首先的是把千兆网卡机器替换成万兆网卡机器。查看timewait的连接数达到1w3多。那就先优化下看起来是"瓶颈"的东西。配置tcp_timestamps=1, tcp_tw_reuse=1, tpc_tw_recycle=1。sysctl -p生效下最新的配置,timewait连接数没下去,并发数没上来。既然硬件该做的设置都完了,那为什么别人家的露娜那么秀,我家的就是一坨屎呢。

​ 再回过头来考虑程序架构问题。反省自己,首先urllib2、request库是网络io阻塞的,其次网络是短连接的,再次这么多进程切换系统开销也很大。在广袤的互联网海洋中遨游了一番,得出的结论就是grequest库可能是个解决办法。gevent是个协程库,它使用greenlet库提供的基于libev实现的高性能异步网络框架。Perfect!看起来是那么的完美。于是又尝试重写了程序。可是性能还是没有上去。那到底是不是python语言自身的限制问题,导致cpu高居不下,并发量又上不去呢?这里留个疑问,到文章的最后再来回答这个问题。

第三章:豁朗开朗

​ 不甘心并且不再纠结于python,用当下网红golang重写下。golang的协程库号称是性能优秀,语言层面支持并行的,易于书写的利器。写完跑一跑,并发量还是上不去。一直保持打死都不放弃的精神,笔者再次用go的第二性能利器自带的golang pprof分析下代码的瓶颈。pprof生成的报告还可以用uber第三方组件go-torch生成更直观的火焰图。如图1所示。从火焰图查看出runtime.gcBgMarkWorker(gc:垃圾回收器),并且runtime.mallocgc也占用大量cpu时间。接着进行内存占用分析,使用go tool pprof -alloc_space replay1 /tmp/mem.prof查看如图2 所示,敲入top10命令,发现pull_worker累加分配了600多G内存,占比93%,list pull_worker命令找到该函数的瓶颈点。这个r4变量的初始化放在一个for循环内,r4是用于临时读取响应body,这个r4每次请求都重复分配,导致内存居高不下,解决办法是把他放在for循环外。

终章:总结

​ 好了,至此单机并发量最高可以到3w了,也差不多达到计划的目标了。用两台这种机器组成的肉鸡就可以满足5w qps的请求了。再来回答之前留下来的问题,python语言并发上不去只是因为,库不支持从外面提供读buffer读取响应body,导致内存暴增,这不是语言本身的问题。相信python并没有那么差。同时,也熟悉了一门新利器go语言。go的原生协程支持和性能分析利器还是非常直观非常好用的,力荐!!

ieyI7nV.png!web

img

图1:性能瓶颈前的cpu火焰图

VbM7faR.png!web

img

图2:找到内存使用最多的函数

263IBjJ.png!web

img

找到增长最多的代码

此文已由作者授权腾讯云+社区发布,原文链接: https://cloud.tencent.com/developer/article/1160803?fromSource=waitui

欢迎大家前往腾讯云+社区或关注云加社区微信公众号(QcloudCommunity),第一时间获取更多海量技术实践干货哦~

海量技术实践经验,尽在 云加社区


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK