应用如何支撑10000并发?

背景: 高并发是现在在互联网项目中常见的字眼,很多人第一次接触的时候都是处于一脸懵逼的状态,就比如我,我一开始接到leader的要求——我们需要我们的应用支撑10000的并发时,我的脑子是混乱的,从哪里入手呢?慢慢从科普,测试,****,github翻阅相关资料,我慢慢明白了如何面对一个这样的需求。

本文将会按照系列更新,从本人的实战角度且避免敏感业务的方向讲解本人对10000并发的设计方案和测试方案。

一、什么是并发?

并发通俗易懂,但是很少有人深究并发是什么一个概念,大部分的Java开发工作者应该也都不太能清楚的讲述并发的概念,收集了很多资料,也结合了业务场景,我做了个总结。

并发是一个伪概念,以10000并发为例,落地其实分为三大块:

1、静态页面并发
10000请求同时访问你的页面,这叫做静态页面并发。
2、查询并发
10000请求同时调用你的服务,要求从数据库查询数据。
2、事务操作并发
10000请求同时调用你的服务,要求数据事务操作你的数据库。

这三大类的并发所需要优化的方向都不一样,但是按照一般的业务场景其实都会遇到这个问题,比如某东或者某宝的秒杀活动都是先进入页面,下单,付款的,这所遇到的并发问题就涵盖了以上三种情况。
应用如何支撑10000并发?

二、并发的测试学习准备工作

要做并发,就需要知道自己的应用现有的环境下能支撑多少,问题出在哪里,调优后有没有达到想要的性能作为一个合格的技术人员,不可能总是天天拉着测试和自己一起弄,那就要提到我在工作中用到的测试利器Jmeter了。
Jmeter只是测试工具的一种,作为技术开发测试并发已经够用了,需要配置的主要有以下几点:

1、线程组
应用如何支撑10000并发?
应用如何支撑10000并发?
线程数:虚拟用户数。一个虚拟用户占用一个进程或线程。设置多少虚拟用户数在这里也就是设置多少个线程数。
Ramp-Up Period(in seconds)准备时长:设置的虚拟用户数需要多长时间全部启动。如果线程数为10,准备时长为2,那么需要2秒钟启动10个线程,也就是每秒钟启动5个线程。
循环次数:每个线程发送请求的次数。如果线程数为10,循环次数为100,那么每个线程发送100次请求。总请求数为10*100=1000 。如果勾选了“永远”,那么所有线程会一直发送请求,一到选择停止运行脚本。
Delay Thread creation until needed:直到需要时延迟线程的创建。
调度器:设置线程组启动的开始时间和结束时间(配置调度器时,需要勾选循环次数为永远)
持续时间(秒):测试持续时间,会覆盖结束时间
启动延迟(秒):测试延迟启动时间,会覆盖启动时间
启动时间:测试启动时间,启动延迟会覆盖它。当启动时间已过,手动只需测试时当前时间也会覆盖它。
结束时间:测试结束时间,持续时间会覆盖它。

2、Http请求
应用如何支撑10000并发?
1、Web服务器
协议:向目标服务器发送HTTP请求协议,可以是HTTP或HTTPS,默认为HTTP
服务器名称或IP :HTTP请求发送的目标服务器名称或IP
端口号:目标服务器的端口号,默认值为80
2.Http请求
方法:发送HTTP请求的方法,可用方法包括GET、POST、HEAD、PUT、OPTIONS、TRACE、DELETE等。
路径:目标URL路径(URL中去掉服务器地址、端口及参数后剩余部分)
Content encoding :编码方式,默认为ISO-8859-1编码,这里配置为utf-8
同请求一起发送参数
在请求中发送的URL参数,用户可以将URL中所有参数设置在本表中,表中每行为一个参数(对应URL中的 name=value),注意参数传入中文时需要勾选“编码

3、响应断言
应用如何支撑10000并发?
应用如何支撑10000并发?
这里根据实际返回格式做断言匹配。
Apply to:关于应用范围,我们大多数勾选“main sample only” 就足够了,因为我们一个请求,实质上只有一个请求。但是当我们发一个请求时,可以触发多个服务器请求,就有main sample 和 sub-sample之分了。
测试字段:指需要匹配的响应类型。
模式匹配规则:如名所说,用来规范匹配的规则。
测试模式:需要校验的数据值。

4、查看结果树
应用如何支撑10000并发?
应用如何支撑10000并发?
这主要是用来查看实时测试返回的明细的,默认配置即可,也可以自定义配置,比如只显示错误日志或者其他的,选择左下方的数据取样器会显示结果明细。

4、聚合报告
应用如何支撑10000并发?
应用如何支撑10000并发?
添加聚合报告可以在测试结束后得到的统计数据比较有参考意义,其中最需要关注的数据是:
样本Samples:总共发给服务器的请求数量,如果模拟10个用户,每个用户迭代10次,那么总的请求数为:10*10 =100次;
平均值Average:默认情况下是单个 Request 的平均响应时间,当使用了 Transaction Controller 时,以Transaction 为单位显示平均响应时间 ,单位是毫秒;
异常Error%:错误率=错误的请求的数量/请求的总数;
吞吐量Throughput: 默认情况下表示每秒完成的请求数(Request per Second),俗称TPS。
发送接收KB/sec: 每秒从服务器端发送和接收到的数据量

根据以上的值一般可分析出当前测试的结果。
特别的,当测试静态页面时需关注发送接收KB/sec指标是否达到网络的上下行瓶颈。
一般的,结合错误率平均值还有吞吐量来分析。

三、让静态页面支撑起10000并发

当测试的时候发现静态页面无法处理并发的时候需要分析几点:
1、我的代理服务器性能是否能支撑10000的并发。
2、当10000并发请求过来的时候页面返回数据量是不是超过了服务器的网络带宽。
3、当10000并发请求过来的时候页面返回数据量是不是超过了测试机的网络带宽。
以上三点都是在做并发测试的时候需要注意的。
我个人使用的是nginx做静态页面的代理转发,实测情况下nginx的默认配置加缓存已经能达到并发10000以上的性能要求,关键的关注点在服务器的带宽和磁盘IO上。
优化建议有以下几点:
1、nginx做负载均衡减轻磁盘IO压力,提高页面服务器的带宽。
2、加CDN。
关于CDN的介绍在我的另一篇文章里有写,配置比较简单,查看官网手册就行,主要需要关注的点就是缓存的配置和回源的规则,一般情况缓存和回源的配置默认设置就行,更新的时候可以通过后台手动刷新的方式。