以前使用websocket服务为H5页面进行实时数据推送,忽然有一天产品给我反馈,说该页面的实时刷新功能失效了,因而开始进行排查和处理,并将过程记录下来。html
这个服务是有监控程序的,每分钟检查一次websocket是否正常,不正常的话会将进程所有杀掉进行重启。nginx
当天接到反馈后,我看了下服务,监控程序是正常的,会对websocket进行重启,但每次重启事后不超过30s,websocket的master节点就又挂了。web
状况就是这样的,下面进入排查流程。redis
在官网上有列举如下三种状况会致使没法提供服务:vim
(1)系统负载过大swoole没法申请到内存而挂掉
(2)swoole底层发生段错误
(3)Server占用内存过大被内核Kill,或者被某些程序误杀
复制代码
可是根据当前环境,并不符合上述状况,因此这个问题暂时尚未找到具体的缘由。bash
(1)首先看了下nginx的error.log,发现大量报错:websocket
13247#0: *176909901 connect() failed (111: Connection refused) while connecting to upstream,
复制代码
看了下nginx配置,能够看出一开始的配置是很小的,因此对几个配置进行增大swoole
worker_processes 1; //worker角色的进程个数
worker_rlimit_nofile 1024;// 更改worker进程的最大打开文件数限制。
worker_connections 1024;//每个worker进程能并发处理(发起)的最大链接数(包含全部链接数)
复制代码
(2)swoole自带的log日志中也有不少报错:并发
ERROR swServer_master_onAccept (ERROR 502): accept() failed. Error: Too many open files[24]
复制代码
(3)还有在程序启动会输出:socket
WARN swServer_start_check: serv->max_conn is exceed the maximum value[1024].
复制代码
官方解释为啥会出现这个报错,因此说明当前的问题就是由于ulimit -n设置的太低致使的问题:
max_connection最大不得超过操做系统ulimit -n的值,不然会报一条警告信息,并重置为ulimit -n的值
复制代码
综合(2)(3)能够得出结论就出在这个ulimit -n上面了,以前也修改过这个值但实际上并无生效。
ulimit -n 指定同一时间最多可打开的文件数
vim /etc/security/limits.conf -------永久修改
ulimit -n 1024 -----------------------即时修改,但重启后就无效了
复制代码
(1)访问量上来后,发现会出现redis偶尔连接失败的报错,查找缘由是由于大量创建连接致使机器上的端口都在使用中,经过调整内核参数解决。
vim /etc/sysctl.conf
编辑文件,加入如下内容:
net.ipv4.tcp_tw_reuse = 1 //表示开启重用。容许将TIME-WAIT sockets从新用于新的TCP链接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 //表示开启TCP链接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
而后执行/sbin/sysctl -p让参数生效。
复制代码
(2)订阅redis后,一段时间后会没法收到信息。缘由暂时不明,经过增长连接超时捕获异常后从新创建订阅请求解决。
ini_set('default_socket_timeout', 10);
复制代码
整理文档的同时就是将解决问题的过程从新复盘一遍,之后解决这种问题的思路就会比较清晰了。