小明之线上websocket服务异常排查思路

开篇

话说上周小明在跟产品的激烈争辩中, 虽然说最终他用一套观察者模式比较好的解决了特定行为发生后频繁变动后续操做的事情, 但处理过程当中对同事的感觉来讲, 并非那么好。linux

因而小明暂时脱离业务的开发, 去作一些技术方面的支持, 还没开始可怜的小明又遇到了新的问题。nginx

技术背景

在他们公司的内部有一个 websocket 服务, 用于给在线的用户推送一些消息, 顶峰时期也就两千多左右的实时用户量(至关于两千多个长链接)golang

这个 websocket 服务是用 golang 开发,由 nginx 作了反向代理web

大概的技术架构图:bash

突发事故

叮叮叮...websocket

对于这种声音小明早已经再熟悉不过了, 下意识大喊了一声: 有状况! , 把周边人吓了一大跳.架构

问题排查

websocket 服务报警频发, 马上去线上链接websocket发现 nginx 504 报错 Gateway Time-out运维

小明虽然说开始作 websocket服务 技术支持, 但还没来得及拥有线上的权限, 当即让运维给他开了个帐号, 运维警告他, 不要在这个机器上瞎搞,这个还有其余业务也使用着呢.socket

小明拿到帐号, 登录后噼里啪啦反复clear命令热身后, 一顿操做猛如虎, 找到了nginx错误日志.ui

nginx error日志

链接 ws 服务超时. 既然 nginx 说是 ws服务 的问题, 那就看看 ws服务 的错误日志吧.

ws服务 错误日志

看看当前打开的文件数

lsof |wc -l
output:
4435
复制代码

小明定睛一看, 朝着屏幕同事会心一笑, 这个问题立刻修复!

查看系统配置的 open files个数

ulimit -a
复制代码

额。。。这个已经调整为 65535 了, 咱们远没有达到这个限制...

小明从兴奋又陷入到了沉思当中...

再次排查

叮叮叮...

查看 ws服务 pid 19246 进程打开了多少文件

lsof -p 19246 | wc -l
复制代码

查看这个进程的系统限制

cat  /proc/19246/limits
复制代码

小明看到 Max open fields为1024, 可是经过 ulimit 命令发现已经调到 65535 了啊. 难道没有生效?

重启大法好!

反正已经不能用了, 直接重启下看看.

....小明两眼一黑,顿时短路......

从 soft limit 提及

ulimit -Sn 查看的是软限制

ulimit -Hn 查看的是硬限制
复制代码

在 Linux 的系统中对于进程(Process)会有一些限制,这就所谓的 limit,在实际应用中最多见的就是对打开文件 (Open Files) 的限制,在配置 web 服务如 nginx 时就会用到。在 linux 中这些限制是分为软限制(soft limit)和硬限制(hard limit)的。他们的区别就是软限制能够在程序的进程中自行改变(突破限制),而硬限制则不行(除非程序进程有root权限)

小明想还有这么多限制呢. 那我提升一点不就能够了嘛

配置具体的限制

cat /etc/security/limits.conf
复制代码

* 表示适用的全部用户, 配置的soft nofile 已经很高了...

小明想: 为何 push-ws 的进程会限制再 1024 这个数字呢?

再次思考

莫非是应用程序限制了最大或默认文件打开数? 可是并无发现文档或代码中去作这个限制.

操做系统没有作任何 1024或4096 的限制, 那这个程序被谁限制了...

小明不只百度、bing还顺着网线爬到香港去谷歌.

有多是 supervisor 影响着咱们的服务.

咱们看下 supervisor 影响 max-open-files 的配置:

minfds=1024; #这个是最少系统空闲的文件描述符,低于这个值supervisor将不会启动。
minprocs=200; #最小可用的进程描述符,低于这个值supervisor也将不会正常启动。
复制代码

具体这两个参数的官方解释:

The minimum number of file descriptors that must be available before supervisord will start successfully. A call to setrlimit will be made to attempt to raise the soft and hard limits of the supervisord process to satisfy minfds. The hard limit may only be raised if supervisord is run as root. supervisord uses file descriptors liberally, and will enter a failure mode when one cannot be obtained from the OS, so it’s useful to be able to specify a minimum value to ensure it doesn’t run out of them during execution. These limits will be inherited by the managed subprocesses. This option is particularly useful on Solaris, which has a low per-process fd limit by default.

The minimum number of process descriptors that must be available before supervisord will start successfully. A call to setrlimit will be made to attempt to raise the soft and hard limits of the supervisord process to satisfy minprocs. The hard limit may only be raised if supervisord is run as root. supervisord will enter a failure mode when the OS runs out of process descriptors, so it’s useful to ensure that enough process descriptors are available upon supervisord startup.

由于 supervisor 管理的子进程都是经过它进程 fork 的, 因此针对 supervisor 的配置会影响到子进程的系统参数. 固然 root 用户不受此限制, 但在生产环境, 这并非一个好注意。

这两个参数正好影响着咱们当前服务进程的指标

supervisord中参数minfds和minprocs决定了supervisord进程及其守护的子进程的Max Processes及Max open files,而且这个limit限制不受系统ulimit所影响。

固然对于咱们的服务场景, 将系统参数调高便可。

[supervisord]
minfds=65535
minprocs=65535
复制代码

重启supervisor服务便可...

结局

等等...

你说啥?

我要重启

你不能

那我怎么验证, 怎么突出个人贡献

下来再弄吧。。。

好吧。。。

更多精彩内容, 关注公众号 呆呆熊的技术路:

相关文章
相关标签/搜索