web架构优化的几个点

:-}

举一个例子,抽奖。
抽奖是一个典型的高并发场景应用,平时流量不多,但遇到大促活动,流量就会暴增,今年我司的717周年庆期间的日均UV就超过百万。零点时刻一时间风起云涌,网站加载缓慢,到零点30分nginx开始报http 502错误。

此处做下笔记:

wikipedia上这么解释:
502 Bad Gateway
The server was acting as a gateway or proxy and received an invalid response from the upstream server.
503 Service Unavailable
The server is currently unavailable (because it is overloaded or down for maintenance). Generally, this is a temporary state.
504 Gateway Time-out
The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.

502 Bad Gateway

fpm进程挂掉或者后端程序过长时间未返回。
编写一个简单的php脚本gateway.php进行测试,内容很简单 <?php sleep(10);echo ‘ok;’?> ,开始下面的测试:

1.启动nginx,不启动fpm,直接 curl http://localhost/gateway.php ,响应502 bad gateway错误且nginx的error log出现错误

2017/02/10 19:08:21 [error] 216#216: *84 connect() failed (111: Connection refused) while connecting to upstream, client: 172.17.0.1, server: website80.com, request: "GET /gateway.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "localhost"

2.启动fpm,修改php-fpm.conf中request_terminate_timeout的值为5s。继续 curl http://localhost/gateway.php ,响应502 bad gateway。nginx和php-fpm分别报错

// nginx error log
2017/02/10 19:10:57 [error] 246#246: *88 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 172.17.0.1, server: website80.com, request: "GET /gateway.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "localhost"

// php-fpm error log
[10-Feb-2017 19:10:57] WARNING: [pool www] child 242, script '/home/website/default/gateway.php' (request: "GET /gateway.php") execution timed out (6.205572 sec), terminating
[10-Feb-2017 19:10:57] WARNING: [pool www] child 242 exited on signal 15 (SIGTERM) after 36.692467 seconds from start

503 Service Unavailable

当遇到这个状态码的时候表示服务临时不可用,比如nginx配置了频率限制而client端又超过了配置的限制后就会收到503的响应。

504 Gateway Time-out

nginx的fastcgi模块有一个fastcgi_read_timeout配置,它表示从FastCGI server获取数据的超时时间。如果超过这个配置客户端就是收到504的响应。还以 gateway.php 举例(修改fastcgi_read_timeout的值为5s):

// nginx error log
2017/02/12 14:57:26 [error] 138#138: *1113 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 172.17.0.1, server: website80.com, request: "GET /gateway.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "localhost"

整体设计

在我看来,能提高服务器应对并发的能力的方式无非两种:

限流削峰:通过降低实际抵达服务器的并发量,降低服务器处理压力;
性能优化:从前台到硬件,优化系统各方面性能,提高服务器处理能力。

服务部署层面

web服务器和应用服务器集群分离
应用服务器集群,做负载均衡,对话共享
静态资源cdn
防cc
访问频率限制
增加服务实时监控
预计高并发前适时提升带宽

项目层面

减少http请求
使用浏览器缓存
启用gzip压缩
css文件放在页面最上面
javascript文件最下面
增加队列,异步
代码分层,增加复用性
禁止for循环sql操作
增加缓存,热点缓存,列表缓存

硬件层面

提高磁盘io速率,使用ssd硬盘
cpu升配,增加内存

数据库方面

逻辑允许的情况下不访问数据库

使用缓存
使用页面静态化

必须访问就优化

参数配置
索引优化
sql优化
分离数据库中活跃的数据
读写分离
批量读取和延迟修改
使用搜索引擎搜索数据库中的数据
使用NoSQL和Hadoop等技术

高并发和高可用

高并发

即在单位时间内的并发请求数非常高,因此对网站的吞吐能力和处理能力比较高。例如12306,淘宝等。

高可用

即对网站的稳定性要求比较高,比如不允许停止服务,某台机器出问题后不影响网站的正常访问等。

互联网应用中,通常面临的问题是前者——高并发。

高并发又分为cpu密集型和io密集型。前者要求网站的计算能力要高,后者要求网站的吞吐能力要高。

http和tcp

HTTP 2.0

HTTP 2.0标准于2015年5月以RFC 7540正式发布,Google Chrome、Mozilla Firefox、Microsoft Edge和Opera已支持HTTP 2.0,并默认启用。Internet Explorer自IE 11开始支持HTTP 2.0,目前谷歌、Facebook、Twitter 等服务器已经采用2.0协议。

2016年4月26日 nginx-1.10.0 stable 也已经提供了对 HTTP 2.0的支持,理论上不需要对程序进行优化,仅仅更换 HTTP 2.0,就可以有效的提升50%以上的性能。

客户端优化

重用TCP连接至关重要,频繁的三次握手是对性能极大的浪费

不能让数据传输的更快,可以让数据传输的更短

压缩数据,减少不必要的比特传输

再快也快不不过什么也不用发,能少发就少发

消除不必要的连接和数据传输本身就是很大的优化,优化好TCP是所有应用高性能的前提和基础。

浏览器优化

减少DNS查找:每一次主机名解析都需要一次网络往返,从而增加请求的延迟时间,同时还会阻塞后续请求。

重用TCP连接:尽可能使用持久连接,以消除 TCP 握手和慢启动延迟(Keep-Alive

减少HTTP重定向:HTTP 重定向极费时间,特别是不同域名之间的重定向,更加费时;这里面既有额外的 DNS 查询、 * TCP握手,还有其他延迟。最佳的重定向次数为零。

HTTPS优化:启用TLS的会话缓存和无状态恢复及共享(可以减少HTTPS后续验证时间)

去掉不必要的资源:任何请求都不如没有请求快。

在客户端缓存资源:应该缓存应用资源,从而避免每次请求都发送相同的内容。浏览器提供了 Cache-Control,Last-Modified 和 ETag 首部提供验证机制,可以让不经常变更的内容直接从本地获取避免重复访问服务器拉取同样的资源,要说最快的网络请求,那就是不用发送请求就能获取资源。

传输压缩过的内容:传输前应该压缩应用资源,把要传输的字节减至最少:确保对每种要传输的资源采用最好的压缩手段。 图片一般会占到一个网页需要传输的总字节数的一半,HTML、 CSS 和 JavaScript 等文本资源的大小经过 gzip 压缩平均可以减少 60%~80。

打包资源减少HTTP请求:拼接资源如图片精灵技术,合并CSS,JS等文件以减少HTTP请求。

合理设置资源域名:HTTP 规定为了防止客户端同时发起的请求过多给服务器造成自我DDOS,客户端对于单个域名一次最多不可发起超过6个并行请求,因此页面中同域名下资源太多,会造成等待6个资源的返而以防造成请求阻塞,可以用多个域名来突破并行请求数量。

借鉴

https://my.oschina.net/u/3833719/blog/1801552