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

作者: a3aac2d1b674 | 来源:发表于2018-07-27 14:30 被阅读5次

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

本文由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的原生协程支持和性能分析利器还是非常直观非常好用的,力荐!!

img

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

img

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

img

找到增长最多的代码

问答

Angular2如何处理http响应?

相关阅读

HTTP/2之服务器推送(Server Push)最佳实践

如何备份你的MySQL数据库

MySQL 8.0 版本功能变更介绍

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

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

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

相关文章

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

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由mariolu 发表于云+社区专栏 序言: ​...

  • 压测指标

    我们经常需要对程序进行压测,怎么压才合适?压到什么样才说明应用达到了性能瓶颈?用什么指标来衡量才合适?一些指标异常...

  • 压测关注指标

    我们经常需要对程序进行压测,怎么压才合适?压到什么样才说明应用达到了性能瓶颈?用什么指标来衡量才合适?一些指标异常...

  • 2018-08-30第十九天

    2018-08-30压测 课堂笔记 性能瓶颈做压测需要准备什么1.压测脚本压测思路是什么由小到大,逐渐添加压力 j...

  • 2018-08-30压测

    课堂笔记 性能瓶颈做压测需要准备什么1.压测脚本压测思路是什么由小到大,逐渐添加压力 jmeter可视化执行优点:...

  • 2018-08-30压测

    课堂笔记 性能瓶颈做压测需要准备什么1.压测脚本压测思路是什么由小到大,逐渐添加压力 jmeter可视化执行优点:...

  • 谈谈压测

    目的 验证单个业务及整个的处理能力及响应时间等 验证系统的性能瓶颈 做容量规划 分类 单接口压测 全链路压测 性能...

  • rabbitmq消息标记拦截处理

    链路压测是一种常见的压测手段,可以测试出系统,链路的性能瓶颈在哪。大公司基本都有根据自己的业务开发的整套链路压测的...

  • 5.基于jmeter压测的一些思考

    1.jmeter允许多个线程并发取样,那么,多线程有上限、瓶颈吗? 按我的理解,实际压测过程中,是用4台压测机,一...

  • Sanic、Fastapi 和 Fiber 简单压测对比

    测试代码 Sanic: Fiber: 压测 压测使用的程序是go-stress-testing[https://g...

网友评论

    本文标题:我是怎么一步步用go找出压测性能瓶颈

    本文链接:https://www.haomeiwen.com/subject/zetgmftx.html