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

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

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

序言:

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

第一章:HTTP初体验

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

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

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

​ 再回过头来考虑程序架构问题。检讨本身,首先urllib二、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/dev...

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

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

相关文章
相关标签/搜索