乐趣区

记录一次errnoENOSPEC导致的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 解决

在找到问题的原因后,我能做的解决方法有两种:

  1. 增加 /dev/vdb1 的索引节点
  2. 定时删除 /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 小结

这次又解决了一个问题,满足了我小小的成就感,然而我觉得更重要是我总结出了排查问题的要点:

  1. 根据现象分析问题,不要凭直觉下手
  2. 不要直接一把梭,干事之前先阅读说明文档,大部分的问题说明文档里都有
  3. 遇到问题是常态,不要焦躁,冷静分析
  4. 平时多技术积累,也许现在用不到,但总会有用到的时候

0x04 延伸资料

  • 理解 Inode
  • How To Increase Amount of Disk inodes in Linux(Linux 上如何增加 Inode)
退出移动版