压测目标
- 读请求接口1.6W并发,总请求16W
- 写请求接口8K并发,总请求8W
压测前的准备工作
- 分析所有接口是否存在可能的性能问题
- 静态代码分析
- 采用Yii2提供的debug工具进行分析
- 采用xhprof进行性能分析
- 压测代码准备
- 生成压测相关数据
- 编写压测代码(有用户态的接口需要做模拟用户登录)
- 人员准备
- 人员分工
- 运维人员进行服务器部署,配置修改,查询各种服务器性能监控
- 开发人员进行代码分析,检测新部署服务器各种配置项,对单台服务器性能进行测试,推测大概需要的服务器配置及台数,对出现的问题进行分析,得出解决方案,进行压测
- 测试人员全流程测试新部署服务器是否正常,对开发人员给出的接口压测报告进行加工,生成可视化的压测报告。包含不局限于接口地址、强并发数、总请求数量或者持续时间、接口响应报告(eg:90%的请求2s以内返回)、web服务器负载情况、数据库负载和redis等存储的负载)。每台web服务器能支持的最大请求数量、暴露在极限情况下的资源瓶颈(数据库、web服务器或者其他)。
服务器及客户端配置要求
- SLB:最大并发数:50000,按量收费,带宽无上限(上限5Gbps,可调)
- WEB服务器:4C8G,600PHP-FPM,不需要外网,单台压测极限能达到800并发,为了给服务器预留资源,按500并发计算,需要32台服务器。
- RDS集群:单台9C6G,IOPS:3000,最大连接数:1500
- Redis集群:内存16G,最大并发数:50000
- 16台客户端:4C8G,无需外网,直接内网访问
压测环境准备
客户端准备
- 客户端下载安装siege并修改参数配置
wget http://download.joedog.org/siege/siege-4.0.4.tar.gz \
&& tar zxvf siege-4.0.4.tar.gz \
&& cd siege-4.0.4 \
&& ./configure \
&& make \
&& make install \
&& siege -h
sed -i "s/limit = 255/limit = 1000/g" ~/.siege/siege.conf
查看配置文件方式:siege -C | grep resource
4.0.4版本的siege配置文件在~/.siege/siege.conf
siege客户端线程数上限默认为255,需要将其调大,以支持1000并发
siege -C | grep "thread limit" ==> 应该为1000
- 修改linux系统打开文件数限制
ulimit -n 65535
PS:linux限制最大打开文件数为$((2*20)),即为1048576,多一个都不行
- 修改hosts到SLB
服务器准备
- 先复制一台WEB服务器,测试人员采用hosts方式进行测试,开发人员对单机进行压测,符合标准后做镜像
- 将镜像部署到32台服务器
- 将所有服务器挂载到SLB
- 将所有服务器的日志接入到日志平台
正式开始压测
压测遇到的坑
- 第一次压测的时候,php的session采用ocs,新部署的服务器网络环境在vpc网络中,造成ocs连接不上,现象是所有请求的响应时间都会大于1秒,由于php的memcache连接不上,压测接口正常返回数据,运维人员没有将错误日志接入日志平台。所以只能上单台服务器上进行测试,刚开始是在入口和结束的地方加入运行时长日志,发现php运行时间只有0.004秒,但是nginx日志却是1.004秒,大半夜头晕,找不到思路,后来直接上了xhprof进行性能分析,发现在性能瓶颈在Yii的Session::Open方法上,才发现是php没有连接上ocs,看源码,才知道Yii在打开会话失败的时候只是记录了一个错误日志,由于运维没接入错误日志,所以也没想到。后来修改了ocs代理,压测响应时间正常。
- 第二次压测,由于不想让服务器通过代理访问ocs,于是将session从ocs切换到redis。php的session使用Redis时,方式是在php.ini中配置的redis.so,发现这个组件有性能问题,一压就挂了。后面改成使用yii2配置,使用yii2的组件(yii2使用unix stream socket,性能杠杠滴),又发现Redis压力上不去。后面把session的Redis和缓存的Redis分开才解决问题,怀疑是阿里云集群版redis和yii2的session中的操作有冲突,后面需要再确定。
转载请注明:MitNick » 对生产环境网站API接口进行全链路压力测试-通过优化支持16000并发