背景:第五场展会开始后,并发量比较大,多次出现502错误。
日志中出现了大量的如下错误:
发现 master服务器已经并发tcp数量达到 7000
Slave服务器并发tcp数量达到 700+
下面做了一些应急的处理方式,
1、 keepalive_timeout = 32 改成了 keepalive_timeout = 120
2、 此时发现定向到主服务器的upstream出现502的几率相当大。因此设置权重改变为3:7
3、 结果还是不行,最后取消了负载到主服务器,仅仅使用slave服务器。
4、 效果有所改善,但是秒杀开始的时候,依然会出现502错误。
5、 后来停掉了聊天服务器。
6、 基于产品的需要,又开启了聊天服务器,只不过更改了聊天服务器的发送频率由2s到5s,但还是没从根本上解决问题。
问题:
通过日志分析,访问的人数和之前的几次访问人数相差不多,可是这次出现了比较严重的502错误。原因暂时还未查明。
不过我通过我试着ab 测试来复现该错误。
通过上面的分析,只有两个请求错误,还可以接受。
当我随着加大并发量的时候,到了250个的时候,
ab -n 10000 -c 300 http://192.168.10.106:8080/tje/exhibition/chatroom
几乎90%以上的都是502了。
下面我的处理方式,修改了一个参数
在/etc/sysctl.conf下面添加了
net.core.somaxconn = 1024
然后执行 sysctl –p 使修改生效
重启web服务器。
测试:
依然没问题,只是响应时间都变成5s以上了。
我看内存依然有剩余,我试着增大了passenger_max_pool_size 由32到40 。
在执行并发 100 ,300 ,1000 。
发现并发处理能力却没有提高,依然每秒 170次左右,如果下降到20,处理并发能力下降。
这个值的设定依据情况而定,如果railsapp本身占内存特别大,开大了反而不好。我保守按照80M-100M计算。
现在解决了并发出现502错误的问题。
那原理是什么呢
看到网络上很多说 修改backlog的,其实passenger在2.2.6的时候已经修改了他的backlog。提升至 1024了
而且man 2 listen查询 了解到这里的backlog实际上是完成三次握手后的tcp队列,换句话说这里是TCP已经建立,等待服务器accept的队列数目。
而我们应对并发的时候,很多客户端发送SYN j请求,服务器给与ACK j+1 应答并SYN k,客户端需要应答ACK k+1 ,这样,如果客户端不应答,或者来不及应答ACK k+1 就造成了半连接,这在并发高的系统中是常见的,linux有个队列来维持半连接,如果队列溢出,则拒绝服务,这就是DOS工具的基本原理。
因此我们需要修改半连接队列的长度,这里有两个地方,可以通过命令查看
修改这两个值为1024即可。不过系统对对tcp_max_syn_backlog默认为1024了,所以只需要在 /ect/sysctl.conf后添加 net.core.somaxconn = 1024即可。