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

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

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

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

找到增长最多的代码

问答

Angular2如何处理http响应?

相关阅读

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

如何备份你的MySQL数据库

MySQL 8.0 版本功能变更介绍

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

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

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

我是怎么一步步用go找出压测性能瓶颈的更多相关文章

  1. 记录一下通过分析Tomcat内部jar包找出request.getReader()所用的字符编码在哪里设置和起效的完整分析流程

    前言: 之前写Java服务端处理POST请求时遇到了请求体转换成字符流所用编码来源的疑惑,在doPost方法里通过request.getReader()获取的BufferedReader对象内部的 R ...

  2. 我是如何一步步裹挟老板从.net 转到 java 阵营的

    我是如何一步步裹挟老板从.net 转到 java 阵营的 仅记录从 .net(C#) 转到 java 的一些心路历程 时间点跨度 2016 — 2017 一.前 xx 公司同事群的一次聊天 前公司同事 ...

  3. SQL注入—我是如何一步步攻破一家互联网公司的

    最近在研究Web安全相关的知识,特别是SQL注入类的相关知识.接触了一些与SQL注入相关的工具.周末在家闲着无聊,想把平时学的东东结合起来攻击一下身边某个小伙伴去的公司,看看能不能得逞.不试不知道,一 ...

  4. Windbg找出死锁

    使用Windbg找出死锁,解决生产环境中运行的软件不响应请求的问题 前言 本文介绍本人的一次使用Windbg分析dump文件找出死锁的过程,并重点介绍如何确定线程所等待的锁及判断是否出现了死锁. 对于 ...

  5. 使用Windbg找出死锁,解决生产环境中运行的软件不响应请求的问题

    前言 本文介绍本人的一次使用Windbg分析dump文件找出死锁的过程,并重点介绍如何确定线程所等待的锁及判断是否出现了死锁. 对于如何安装及设置Windbg请参考:<使用Windbg和SoS扩 ...

  6. 我是如何一步步编码完成万仓网ERP系统的(四)登录的具体实现

    https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...

  7. 我是如何一步步编码完成万仓网ERP系统的(十二)库存 1.概述

    https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...

  8. 我是如何一步步编码完成万仓网ERP系统的(十三)库存 2.加权平均价

    https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...

  9. 我是如何一步步编码完成万仓网ERP系统的(十四)库存 3.库存日志

    https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...

随机推荐

  1. delphi Form显示先后问题

  2. XE7 & FMX 那些年我们一起上过的控件:StringGrid 之(1) 自定义标题样式

    FMX下的Grid类控件似乎不太尽如人意,可能是和官方的资料没有跟得上它的发行版本有关系. 以下讨论StringGrid的列表头及对齐方式. 先上个效果图: FMX的列表头估计很多人都是用盒子上流传甚 ...

  3. Linq实战 之 DataSet操作详解

    Linq实战 之 DataSet操作详解  一:linq to Ado.Net 1. linq为什么要扩展ado.net,原因在于给既有代码增加福利.FCL中在ado.net上扩展了一些方法. 简单一 ...

  4. java-04流程控制语句

    这里先简单介绍几种流程控制语句 包括if/if-else.switch语句 1.三大流程控制结构 所谓流程控制,就是说要控制程序的执行方式,根据不同的情况执行不同的代码,从而得到不同情况下的不同结果. ...

  5. 【python】@property装饰器

    Python内置的@property装饰器可以把类的方法伪装成属性调用的方式.也就是本来是Foo.func()的调用方法,变成Foo.func的方式.在很多场合下,这是一种非常有用的机制. class ...

  6. C#开源定时回调库PETimer的使用

    PETimer PETimer开源项目GitHub地址:点击跳转 PETimer 1.双端通用:基于C#语言实现的高效便捷计时器,可运行在服务器(.net core/.net framework)以及 ...

  7. CentOS7系统更改网卡名为eth0

    centOS7系统更改网卡名为eth0 1.编辑grub参数 [root@localhost ~]# vim /etc/sysconfig/grub 2.在GRUB_CMDLINE_LINUX行中添加 ...

  8. 对xaml的深入探究(补交作业)

    首先,下结论,看完那个外国老师的视频后,5%左右听懂了,分享给大家: 1.理解一下,xaml是特殊的xml,我们可以从代码语法看出,xaml中的打码很类似与html和xml的代码. 2.xaml.cs ...

  9. AlvinZH掉坑系列讲解(背包DP大作战H~M)

    本文由AlvinZH所写,欢迎学习引用,如有错误或更优化方法,欢迎讨论,联系方式QQ:1329284394. 前言 动态规划(Dynamic Programming),是一个神奇的东西.DP只能意会, ...

  10. struts2后台向前台传值为空

    今天遇到了一个bug,在后台定义了一个list,然后在前台展示,结果前台接手到的一直是个空,然后找了半天最后才知道是名字名字的问题,这个变量是第一个字母小写,然后第二个字母大写了,然后自动生成的get ...