1)并发
并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。
2)我们说的高并发是什么?
上面的定义明显不是我们通常所言的并发,在互联网时代,所讲的并发、高并发,通常是指并发访问。也就是在某个时间点,有多少个访问同时到来。通常如果一个系统的日PV在千万以上,
有可能是一个高并发的系统。有的公司完全不走技术路线,全靠机器堆,这不是我们的讨论范围。
3)高并发的问题,我们具体该关心什么?
- QPS:每秒钟请求或者查询的数量,在互联网领域,指每秒响应请求数(指HTTP请求);
- 吞吐量:单位时间内处理的请求数量(通常由QPS与并发数决定);
- 响应时间:从请求发出到收到响应花费的时间(例如:系统处理一个HTTP请求需要 100ms,这个 100ms 就是系统的响应时间);
- PV:综合浏览量(Page View),即页面浏览量或者点击量,一个访客在 24 小时内访问的页面数量。同一个人浏览你的网站同一页面,只记作一次PV;
- UV:独立访客(UniQue Visitor),即一定时间范围内相同访客多次访问网站,只计算为1个独立访客;
- 带宽:计算带宽大小需关注两个指标, 峰值流量 和 页面的平均大小。
- 日网站带宽 = PV / 统计时间(换算到秒)x 平均页面大小(单位KB)x 8
- 峰值一般是平均值得倍数,根据实际情况来定;
- QPS 不等于 并发连接数;
- QPS是每秒HTTP请求数量,并发连接数是系统同时处理的请求数量(1个HTTP请求叫做1个QPS,一个并发连接数有可能里面有多个HTTP请求)
- 峰值每秒请求数(QPS) = (总PV数 * 80%) / (6小时秒数 * 20%)【代表80% 的访问量集中在 20% 的时间】;
- QPS压力测试:用来了解单台服务器所能承受的QPS值是多少:
- 测试能承受的最大并发数(测试服务器最大能承受多少QPS,网站一天PV是多少,可以计算出来整个QPS的峰值是多少);
- 测试最大承受的QPS值
注:首先要知道 整个网站的日PV 是多少,服务器单台QPS的承受能力 是多少(如:我们日QPS经过计算得到200(单机峰值QPS为200),单机QPS承受力为50,至少需要4台机器,才能完成访问)。
4)常用性能测试工具
① ab
全称是 apache benchmark,是 apache 官方推出的工具。 原理:创建多个并发访问线程,模拟多个访问者同时对某一个URL地址进行访问。它的测试目标是基于URL的,因此,它既可以用来测试 apache 的负载压力,
也可以测试 nginx、lighthttp、tomcat、IIS等其它 Web 服务器的压力。 使用方法:如模拟并发请求 100次,总共请求 5000次(ab -c 100 -n 5000 待测试网站:-c 表示 并发数,这儿是100; -n表示 总共请求次数,这儿是5000)。
注意事项:
测试机器与被测试机器分开; 不要对线上服务做压力测试; 观察测试工具ab所在机器,以及被测试的前端机的CPU,内存,网络等都不超过最高限度的 75%.
② wrk
③ http_load
④ Web Bench
⑤ Siege
⑥ Apache JMeter
5)QPS达到极限,该怎么办?
随着QPS的增长,每个阶段需要根据实际情况来进行优化,优化的方案也与硬件条件、网络带宽息息相关。
① QPS 达到 50
可以称之为小型网站,一般的服务器就可以应付。(不需要进行优化)
② QPS 达到 100
假设关系型数据库的每次请求在 0.01秒 完成; 假设单页面只有一个SQL查询,那么 100QPS 意外着 1秒钟 完成 100次请求,但是此时我们并不能保证数据库查询能完成 100次; 方案:数据库缓存层、数据库的负载均衡。
③ QPS 达到 800
假设我们使用百兆带宽,意味着网站出口的实际带宽是 8M 左右; 假设每个页面只有 10K,在这个并发条件下,百兆带宽已经吃完; 方案:CDN加速、负载均衡。
④ QPS 达到 1000
假设使用 Memcache 缓存数据库查询数据,每个页面对 Memcache 的请求远大于直接对 DB 的请求; Memcache 的悲观并发数在 2w 左右(Memcache 在 QPS 达到 800 的时候已经不太稳定了),但有可能在之前内网带宽已经吃光,表现出不稳定。 方案:静态HTML缓存。
⑤ QPS 达到 2000
这个级别下,文件系统访问锁都成了灾难; 方案:做业务分离,分布式存储。
如:现在有 库存系统 和 订单系统,可以把这两个系统分到不同的集群。
2、高并发解决方案案例
1)流量优化
防盗链处理
把一些恶意的请求拒之问外。如:现在有A,B两个站,A站 想用 B站 的资源,直接在页面嵌入了一些图片,JS,CSS,本身来说,A站并不关心B站会消耗多少流量,
但是对于B站来说,如果我们调用了B站的一些图片,JS或者CSS,都会对它做一个HTTP请求,就会消耗流量和带宽,
所以本身对B站来说,会有不好的影响。从另一个角度来说,也侵犯了B站的版权问题,因此在这儿,要做 防盗链处理,这是流量的优化。
2)前端优化
① 减少HTTP请求
假设打开一个界面,可以把一些CSS,JS文件,图片进行合并,这样做虽然会使文件变大,但是减少了请求的次数。
② 添加异步请求
如:不是一些很重要的数据,用户首次请求界面的时候,先不进行展示,需要的时候再进行展示,我们可以在旁边放一些事件,通过一些JS、jQuery等第三方库做一些AJAX的相关的异步请求,
这样对于HTTP请求在性能上回有一个大幅度的提升,不要一次性把数据都加载过来,这样会对服务器造成很大的压力。
③ 启用浏览器缓存和文件压缩
如:启用浏览器 去缓存HTML文件给其设定过期时间,设定缓存文件相关的指纹等等。还可以将静态资源文件(如:JS、image等一些前端资源)设置过期时间缓存,为其指定过期时间,
把它缓存到浏览器中,这样下一次再去访问的时候,不需要去请求服务端,可以直接通过浏览器把缓存读取出来。对于 文件压缩,可以通过一些压缩方式,如:把图片压缩的小一些,
展示的时候图片就会下载的更快些,响应速度会加深,并且减少了流量的消耗,减少了带宽的消耗。同时也可以启用 Nginx 的 GCPR服务,将文件整体来说压的小一些。
④ CDN 加速
可以把一些前端的文件,前端的资源全部都放到CDN当中,用户过来访问的时候,可以就近来进行访问,从而提高访问速度,并且从一定意义上来说,也解决了带宽不够用的问题,
可以把数据缓存到CDN的节点中,在用户去访问的时候,都会就近的选择CDN的节点进行访问,从一定意义上来说,就不会访问我们真实的服务器。
⑤ 建立独立图片服务器
因为本身来说,图片服务器是比较吃I/O的,为了解决对 I/O的损耗,可以把它与我们的 Web 服务器完全分离开,这样 Web 服务器本身的I/O 不会被我们的图片损耗,
然后还可以针对性的对我们的图片服务器做一些优化,如:提高硬盘的转速;把CPU的计算能力降低下来;把图片服务器做一个集群。
3)服务端优化
① 页面静态化
把现有的服务端的逻辑(如:PHP),把PHP的一些逻辑,PHP的一些数据,PHP最终生成的要显示给用户的一些HTML内容缓存起来,直接缓存成HTML代码速度会更快,
并且对我们的CPU负载,对我们的服务器的压力都会减小很多。
② 并发处理
如:页面做了一些静态化,但是静态化会有一个过期时间,不可能永远显示页面,如果是这样创建一些动态的内容就没有意义了,但是对于实质性要求比较高的来说,
我们可能在做一些静态化的时候,不是特别的合理。这时需要穿透静态化,即绕过静态化,来直接访问真实的数据。访问真实数据的时候,可能就需要做一些程序上的并发处理,
如 多线程多进程的异步处理、队列处理 等等,都可以异步完成数据的处理,从而提升请求的响应的速度,同时也提升了并发数。
③ 队列处理
4)数据库优化
① 数据库缓存
- memcache 缓存
- redis 缓存等
② 分库分表、分区操作
- 垂直拆分、水平拆分;
- 分区
③ 读写分离
- 把一些服务器,一些数据完全分开;
- 一些服务器做数据库的读操作(查询),一些服务器做写操作(增、删、该)
④ 负载均衡
5)Web 服务器优化
负载均衡
- 可以使用 Nginx 的反向代理来实现负载均衡;
- 使用七层,使用四层(LVS)软件来实现负载均衡。