接口QPS达到100K的压测过程

线上某服务接口QPS最高只能达到40K,架构中各层服务(Nginx、Tomcat、Dobbu、Redis/Mysql)的服务器负载都很低,横向扩展Nginx、Tomcat服务器,QPS不提升,增加压力,QPS和服务器负载还会下降。

1、现状

无法知道架构的瓶颈在哪一层,各层服务的瓶颈值是多少,导致无法根据用户量来预估服务器的数量。

2、测试目标

  • 测试出各层服务的瓶颈值
  • 测试出当前架构能达到的QPS
  • QPS达到100K时,是否需要扩展或调整架构,怎么调整

3、测试计划

阶段 测试项目 目标
单压Nginx 增加压力,QPS成线性增长,单台Nginx QPS能达到200K以上
单压Tomcat(空) 掌握Tomcat的QPS和服务器负载情况
Nginx + Tomcat(空) 增加压力和Tomcat,QPS成线性增长,QPS能达到100K以上
Nginx + 带业务Tomcat 掌握业务的QPS和服务器负载情况,增加压力和Tomcat,QPS成线性增长,QPS能达到100K
Nginx + 带业务Tomcat + Dubbo 掌握Dubbo的负载情况
Nginx + 带业务Tomcat + Dubbo + Redis 掌握Redis的负载情况,以及整体QPS达到100K的情况

4、术语说明

测试中,经常会遇到一些术语,这些术语可能在不同的场景会出现概念偏差,为了保持统一,在本次测试中,对这些术语和公式进行说明。

带宽: 单位一般用 MbpsMbit/s,用来描述数据传输速度。常用在描述光纤和网线上。

吞吐量: 单位一般用 MBMByte,用来描述数据量。常用在描述网卡上。MbpsMB 是可以计算转换的,1000Mbps = 125 MB(8倍的关系)。

QPS: 每秒的响应请求数,该值代表了系统的吞吐能力。

TPS: 每秒处理的事务数。该值代表了系统的性能。

并发数: 系统同时处理的 Request 数,在真实场景中,该值一般等同于并发用户数,因为在同一时刻点,一般一个用户只发送一个Request。

响应时间:平均响应时间。

公式:

1
2
3
QPS或TPS = 并发数 / 响应时间

并发数 = QPS * 响应时间

根据上面的公式,假设一个用户一次请求的响应时间是0.010秒,那么,在1秒内,该用户只能发送100次请求。要想提高1秒内的请求数,只能从两个因素来考虑,要么降低响应时间,要么增加用户数。

同理,对我们的架构来讲,要想提高压测的QPS,要么优化接口的响应时间,要么提供压力的并发用户数。

接口响应时间的优化是下一步工作,并不在这次压测计划范畴,所以,我们只能通过提高压力的并发用户数来提高QPS。

5、服务器配置说明

由于测试都是基于阿里云的ECS进行的,所以配置说明以阿里云提供的信息为标准。

服务器名称 规格 CPU 内存 处理器主频 内网带宽 内网收发包
Nginx 通用网络增强型 sn2ne 4 16 2.5GHz 1.5Gbps 50万PPS
Tomcat 通用型 g5 4 16 2.5GHz 1.5Gbps 50万PPS
压力机 通用型 g5 4 16 2.5GHz 1.5Gbps 50万PPS
Redis

6、测试过程

由于服务器配置和操作成本原因,整个测试过程都是基于 abTsung 两个压测软件进行的。等全部过程结束后,可以用 Loadrunner 进行一次验证。

整个压测过程中,服务器的内存、磁盘IO都很低,所以就没有记录。

6.1、第一阶段

目标:增加压力,QPS成线性增长,单台Nginx QPS能达到200K以上。

压测结果:

压测命令:

1
ab -c200 -n100000 -k http://nginx01/
压测说明 压力机数量 QPS 响应时间(毫秒) CPU 内网进峰值 内网出峰值 说明
1台空Nginx 1 140K 1.4 3% 很低 很低 正常压力
1台空Nginx 2 140K
140K
1.4
1.4
3% 很低 很低 正常压力

结论:

通过压测,说明QPS等于100K的压力,对 Nginx 服务来说,没有任何压力。

6.2、第二阶段

目标:掌握单台Tomcat的QPS和服务器负载情况。

压测结果:

压测命令:

1
ab -c200 -n60000 -k http://tomcat01:8810/
压测说明 压力机数量 QPS 响应时间(毫秒) CPU 内网进峰值 内网出峰值 说明
1台空Tomcat 1 50K 3.6 80% 很低 很低 正常压力
1台空Tomcat 2 25K
26K
3.6
3.6
85% 很低 很低 正常压力

结论:
通过压测,说明当前配置的服务器,单台TomcatQPS为50K,CPU已经达到了80%,增加压力,并不能明显提高QPS。

备注:
该步骤的Tomcat没有部署任何服务,是一个空的Tomcat。

6.3、第三阶段

目标:增加压力和Tomcat,QPS成线性增长,QPS能达到100K以上。

压测结果:

压测命令:

1
ab -c240 -n100000 -k http://nginx01/
压测说明 压力机数量 QPS 响应时间(毫秒) CPU 内网进峰值 内网出峰值 说明
1台Nginx + 1台Tomcat 1 50K 4.2 Nginx:5%
Tomcat:80%
很低 很低 正常压力
1台Nginx + 2台Tomcat 1 60K 4 Nginx:10%
Tomcat:12%
很低 很低 压力不够
1台Nginx + 2台Tomcat 2 48K
48K
4.9
4.9
Nginx:16%
Tomcat:75%
很低 很低 QPS = 96k
1台Nginx + 2台Tomcat 3 36K
36K
36K
6.5
6.5
6.5
Nginx:16%
Tomcat:85%
很低 很低 QPS = 10.8
1台Nginx + 3台Tomcat 3 40K
40K
41K
6
5.8
5.8
Nginx:16%
Tomcat:76%
很低 很低 QPS = 12.1
1台Nginx + 4台Tomcat 4 33K
35K
33K
33K
7
7
6.8
7.3
Nginx:20%
Tomcat:80%
很低 很低 QPS = 13.4
1台Nginx + 4台Tomcat 5 24K
24K
23K
21K
22K
6
21
5.8
Nginx:24%
Tomcat:86%
很低 很低 QPS = 11.4

说明:

通过压测,说明当前配置的服务器,Nginx代理Tomcat后的QPS,与单压Tomcat的QPS差不多。而且,持续增加压力,不增加Tomcat,响应时间会增加,QPS并没有明显提升。

通过增加压力和Tomcat,QPS能接近线性增长,也能达到100K。

备注:
ab 多台压力机进行压测时,是通过人工手动触发的,存在一定误差。后面将会采用Tsung的集群方式压测。

6.4、第四阶段

目标:掌握业务的QPS和服务器负载情况,增加压力和Tomcat,QPS成线性增长,QPS能达到100K。

压测接口:

1
2
# 接口
/api/xxx?id=xxx&...

由于登录接口必须要用Dubbo服务,为了减少Dubbo服务的影响,在每台Tomcat的本地服务器上,都部署了一套Dubbo服务。

压测结果:

查看压测报告中的QPS时,请以 Throughput graps 中的 Requests 为准。

压测说明 压力机数量 QPS 响应时间(毫秒) CPU 内网进峰值 内网出峰值 说明
1台Tomcat 1 9K 21.6 Tomcat:50% 78Mbps 76Mbps 正常压力
1台Nginx + 1台Tomcat 1 9K 21 Nginx:7%
Tomcat:37%
30Mbps 35Mbps 正常压力
1台Nginx + 2台Tomcat 3 18.5K 21 Nginx:20%
Tomcat:64%
133Mbps 134Mbps 压测报告
1台Nginx + 3台Tomcat 3 27K 24 Nginx:21%
Tomcat:85%
330Mbps 369Mbps 压测报告
1台Nginx + 4台Tomcat 3 36K 24 Nginx:28%
Tomcat:85%
459Mbps 472Mbps 压测报告
1台Nginx + 6台Tomcat 3 50K 14 Nginx:40%
Tomcat:85%
684Mbps 702Mbps 压测报告
1台Nginx + 8台Tomcat 3 52K 14.5 Nginx:40%
Tomcat:72%
698Mbps 710Mbps 压测报告
1台Nginx + 8台Tomcat 5 70K 7.5 Nginx:46%
Tomcat:65%
941Mbps 963Mbps 压测报告
1台Nginx + 8台Tomcat 5 71K 10.11 Nginx:46%
Tomcat:65%
941Mbps 963Mbps 此处增加了压力数,查看压测报告
2台Nginx + 8台Tomcat 7 100K 12.47 Nginx:40%
Tomcat:78%
698Mbps 710Mbps 压测报告

说明:

1、在QPS小于50K时,增加Tomcat数量,QPS能成线性增长。

2、在QPS大于50K时,压力不够,增加压力机后,QPS能提升。但是,当QPS达到70K,Nginx内网进出带宽之和已经超出1500Mbps,继续增加压力,QPS几乎不能提升,说明Nginx层的带宽已经达到极限。

3、扩展Nginx,增加压力,QPS能达到100K,每台Nginx的内网带宽也下降了。

6.5、第五阶段

目标:掌握Dubbo的负载情况。

压测接口:

1
2
# 接口
/api/xxx?id=xxx&...

压测结果:

压测说明 压力机数量 QPS 响应时间(毫秒) CPU 内网进峰值 内网出峰值 说明
1台Nginx + 5台Tomcat + 1台Dubbo 1 29K 10.8 Tomcat:40%
Dubbo:85%
nginx:383Mbps nginx:393Mbps 压测报告
1台Nginx + 8台Tomcat + 4台Dubbo 5 70K 7.5 Nginx:46%
Tomcat:65%
941Mbps 963Mbps 压测报告
1台Nginx + 8台Tomcat + 4台Dubbo 5 71K 10.11 Nginx:46%
Tomcat:65%
941Mbps 963Mbps 此处增加了压力数,查看压测报告
2台Nginx + 8台Tomcat + 4台Dubbo 7 100K 12.47 Nginx:40%
Tomcat:78%
698Mbps 710Mbps 压测报告

说明:

  • 1、单台Dubbo服务的QPS能达到29K,扩展Dubbo服务,QPS能增长。<
  • 2、4台Dubbo服务能撑起QPS等于100K的目标,这时Dubbo服务器的CPU负载已经超过80%,QPS在增加的话,需要扩展Dubbo服务。

6.5、第六阶段

目标:掌握Redis读操作的负载情况,以及整体QPS达到100K的情况。

压测接口:

1
2
# 登录接口
/api/xxx?id=xxx&...

注意:

  • 该接口会对Redis执行3次读操作。

压测结果:

压测说明 压力机数量 QPS 响应时间(毫秒) CPU 内网进峰值 内网出峰值 说明
2台Nginx + 8台Tomcat + 4台Dubbo + 1个Redis实例 1 20K 10 Redis: 100%
其它服务无压力
压测报告
2台Nginx + 8台Tomcat + 4台Dubbo + 1个Redis实例 2 19K 20 Redis: 100%
其它服务无压力
此处增加了压力数,查看压测报告
2台Nginx + 8台Tomcat + 4台Dubbo + 1个Redis实例 2 24K 16 Redis: 100%
其它服务无压力
此处将Redis进程绑定了指定的CPU,查看压测报告
2台Nginx + 8台Tomcat + 4台Dubbo + 2个Redis实例 2 47K 7 Redis: 100%
其它服务无压力
此处将Redis进程绑定了指定的CPU,查看压测报告
2台Nginx + 8台Tomcat + 4台Dubbo + 3个Redis实例 2 66K 5.7 Redis: 96%
Dubbo: 70%
Tomcat: 56%
此处将Redis进程绑定了指定的CPU,查看压测报告
2台Nginx + 8台Tomcat + 6台Dubbo + 5个Redis实例 2 92K 10 Redis: 80%
Dubbo: 80%
Tomcat: 70%
450Mbps 468Mbps 此处将Redis进程绑定了指定的CPU,5台Redis实例分布在2台服务器上,查看压测报告
2台Nginx + 8台Tomcat + 6台Dubbo + 5个Redis实例 2 92K 14 Redis: 80%
Dubbo: 80%
Tomcat: 70%
450Mbps 468Mbps 此处增加了压力数,5台Redis实例分布在2台服务器上,查看压测报告

说明:

  • 1、Redis实例进程不绑定CPU时,单实例Redis的登录接口QPS等于20K,当绑定CPU后,QPS等于24K。
  • 2、2台Redis实例QPS等于47K,近似线型增长。
  • 3、3台Redis实例QPS等于66K,理论值应该等于72K,折损9%,相当于近似线型增长。
  • 4、5台Redis实例QPS等于92K,理论值应该等于120K,增加压力,并不能提升QPS,此时,Dubbo服务出现排队情况,已经达到瓶颈,Nginx网络流量接近千兆,而Tomcat和Redis服务没有达到瓶颈。
  • 5、再增加一台Dubbo服务,整体QPS应该能达到100K,此项压测省略。

注意:

  • 在压测时,并发用户数直接从400调整到1000时, Dubbo服务出现过中途连接Redis超时的问题,多几十秒后,又恢复,说明并发量瞬间值较大时,Dubbo服务可能会出现瓶颈。
  • 在压测时,出现一种现象,同样的服务配置和压力,只是因为重新选择了服务器,导致压测结果有一定误差,例如:2个Redis实例(部署在同一台服务器)曾经在不同的服务器上测登录接口,QPS有一定的差异,分别为26K,27K,29K(理论值应该为28K),这个可能跟云服务器的宿主机资源抢占有关。
  • Redis实例绑定CPU时,一定要绑定到没有被用到的CPU上。
  • 在压测时,曾出现最后启动的Redis实例,CPUS始终无法压到98%,换台服务器重新压测,就可以。这个也可能跟云服务器的宿主机资源抢占有关。

6.6、第七阶段

目标:掌握Redis写操作的负载情况。

压测接口:

1
2
3
4
# 写接口(String类型)
/api/xxx/writeStr?key=MYSTR&value=SUCCESS

/api/xxx/writeHash?key=MYHASH&field=fffff&value=vvvvvv

压测结果:

压测说明 压力机数量 QPS 响应时间(毫秒) CPU 内网进峰值 内网出峰值 说明
2台Nginx + 8台Tomcat + 6台Dubbo + 1个Redis实例 2 63K 5.8 Redis: 100%
其它服务无压力
第一个接口,压测报告
2台Nginx + 8台Tomcat + 6台Dubbo + 1个Redis实例 2 74K 4.5 Redis: 100%
其它服务无压力
第一个接口,增加压力数压测报告
2台Nginx + 8台Tomcat + 6台Dubbo + 1个Redis实例 2 63K 5.2 Redis: 100%
其它服务无压力
第二个接口,压测报告

说明:
1、单Redis实例写操作,String类型的QPS等于74K,Hash类型的QPS等于63K。

6.7、第八阶段

目标:掌握阿里云Redis性能。

压测接口:

主要有注册、登录、简单的数据写入接口

压测结果:

压测说明 Redis版本 说明
标准版 2.8 与自搭建单节点的性能相似
读写分离版 2.8 与自搭建单节点的性能相似
集群版 2.8 8个节点,登录QPS能达到98000,注册能达到30000

说明:

  • 1、阿里云Redis的标准版和读写分离版,与我们自己搭建的Redis性能没有太大区别。
  • 2、阿里云Redis的集群版能满足我们的要求。
  • 3、自搭建codis与阿里云Redis集群版性能差不多,但是维护成本较高。

7、总结

根据目前的压测情况,可以得出以下初步结论。

负载均衡

  • 1、这个需要服务商的负载均衡带宽限制来决定,建议采用N + 1的方式。

Nginx

  • 1、Nginx服务在保持长连接的情况下,基本上没有什么压力;
  • 2、当并发用户数大于60K(这个跟系统的TCP的端口号范围配置有关),需要扩展Nginx;
  • 3、当Nginx的网络带宽峰值达到极限时,需要扩展Nginx,这个值需要根据所有业务接口的返回数据量大小来评估,根据登录接口压测的情况来看,QPS超过50K时,就需要扩展Nginx;

Tomcat

  • 1、从登录接口来看,单台Tomcat的QPS为9K+,不同的业务接口,该值会不同,但不会超过50K;
  • 2、横向扩展Tomcat,QPS能达到线性增长;
  • 3、从登录接口来看,当Tomcat等于8台时,QPS能达到100K;

Dubbo

  • 1、从登录接口来看,单台Dubbo的QPS为29K,不同的业务接口,该值会不同;
  • 2、横向扩展Dubbo,QPS能近似线性增长;
  • 3、从登录接口来看,当Dubbo等于4台时,QPS能达到100K;

Redis

  • 1、从登录接口来看,单实例Redis的QPS为24K,不同的业务接口,该值会不同;
  • 2、横向扩展Redis,QPS能近似线性增长;
  • 3、从登录接口来看,当Dubbo等于7台,Tomcat等于8台,Nginx等于2台,Redis实例等于5时,整体QPS能达到100K;

整个服务QPS达到100K的各服务部署数量规划表:

服务 建议数量 说明
Nginx 3 主要瓶颈在网络带宽,当QPS达100K时,2台Nginx的平均带宽接近千兆
Tomcat 10 虽然用8台Tomcat,压测结果能达到100K,这个可能与服务器性能多少有点影响
Dubbo 8 受业务逻辑影响很大
Redis 2+ 每台上部署多个实例
单实例写操作QPS无法达到目标,读可以,需要重新设计Redis的集群部署方式
文章作者: OneRain
文章链接: https://kiswo.com/2018/03/04/system-optimize/qps/qps-100k-report/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 OneRain's Blog