记录一次errno.ENOSPEC导致的supervisor启动失败
supervisor 报错
0x00 起因
最近公司的蓝鲸发布上线系统又一次 down 掉了,而之前搭建这个平台的老哥已经离职,所以我也是临危受命来负责处理这个问题,只隐约记得当时那位老哥好像是说过频繁 down 掉的原因是性能瓶颈,并升级过一次 ECS 的配置,所以我第一反应也认为是机器性能瓶颈,然而事情并没有那么简单。
0x01 分析
1. 现象分析
排查问题的过程我觉得和看病很相似,所以第一时间是看现象,当时的现象是 nginx 返回 502 code,而根据502 code 的含义和以往的经验,我第一时间就想到的是后端服务 down 掉了,接下来一检查,果然是如此。所以下一步是要把后端程序服务启动起来。
2. 资料查阅
由于我之间并没有接触过蓝鲸这个发布平台,所以我第一次时间是去找官方文档,而不是直接操作一把梭,这也是我在这几年工作中摸索出来的重要的一点。在查阅了官方的的资料后,我大概清楚了蓝鲸的软件架构,并了解到了蓝鲸的主要几个服务是由 supervisor 托管的,那么接下来就是需要把这几个服务启动起来了。
3. 问题处理
supervisor和 systemd 作为 Linux 上用的最多的两款进程管理系统,我还是比较熟悉的,所以当我尝试将supervisord 启动的时候,却报错了:
Error: Cannot open an HTTP server: socket.error reported errno.ENOSPC (28)
当我看到这个错误的时候,和所有的程序员一样,首先就是复制错误码到 google 里面搜索看有没有结果。。。然而并没有和我一样的错误,我只好查阅 supervisor 的官方文档,里面也并没有详细的说明,接下来我又查了一些英文资料也无任何线索,我开始有些焦急了。
万幸,我明白越是在排查问题的时候就越是要镇静,像无头苍蝇一样乱飞是没有任何效果的。所以我再仔细认真的读了报错信息的每一个单词,最后我觉得弄清楚error code,也就是 errno.ENOSPC (28)是关键,所以我改为搜索这个错误信息。
原来这个错误的意思在Node.js里是 no space left on device.(设备上无剩余空间),那么在 supervisor 里可能也是类似的,顿时我感觉豁然开朗,那么我接下来就是检查磁盘空间了
可是磁盘空间仍然相当充足,我又一次迷惑了。。。就在这时,我突然想起了不久前看过的一篇介绍 Linux文件系统的文章(说明平时技术的积累也很重要),文章里说磁盘在执行文件系统格式化的时候,会分为三个存储区,分别是:
- 超级块,存储整个文件系统的状态
- 索引节点区,用来存储索引节点
- 数据块区,用来存储文件数据
既然/dev/vdb1
的数据块区是有空余的,那么索引节点是不是还有空余的呢?我执行df -hi
看了下
/dev/vdb1
的IFree 为 0,接下来我又在/data
目录里面搜索了下,发现很多历史遗留的日志文件,至此真相大白了。
4. 原因
之所以蓝鲸进程启动失败的原因就是/dev/vdb1
块设备上的索引节点被大量的日志占用光了,而之前的日志清理脚本并没有彻底清理干净日志,所以导致有时服务不可用。
0x02 解决
在找到问题的原因后,我能做的解决方法有两种:
- 增加
/dev/vdb1
的索引节点 - 定时删除
/dev/vdb1
的日志
在查阅了资料后,我发现方法一需要重新格式化块设备
Do you want to increase the amount of inodes? Either increase the capacity of the disk entirely (Guide: Increase A VMware Disk Size (VMDK) LVM), or re-format the disk using mkfs.ext4 -i to manually overwrite the bytes-per-inode ratio.
所以这个方法是不可接受的。那么我就只能采用定时删除日志的方法了,写了个 crontab 的脚本执行定时任务
至此该问题彻底解决
0x03 小结
这次又解决了一个问题,满足了我小小的成就感,然而我觉得更重要是我总结出了排查问题的要点:
- 根据现象分析问题,不要凭直觉下手
- 不要直接一把梭,干事之前先阅读说明文档,大部分的问题说明文档里都有
- 遇到问题是常态,不要焦躁,冷静分析
- 平时多技术积累,也许现在用不到,但总会有用到的时候