我在运行 PG、MariaDB、sidekiq 和 apache httpd 的 CentOS 7 VM 上。有时我的日志中充满了错误,例如:
unable to resolve address: System error
WARN: Mysql2::Error::ConnectionError: Unknown MySQL server host 'mariadb' (16)
WARN: PG::ConnectionBad: could not translate host name "postgres" to address: System error
WARN -- : Unable to record event with remote Sentry server (Errno::EBUSY - Failed to open TCP connection to o383708.ingest.sentry.io:443 (Device or resource busy - getaddrinfo)):
所有这些主机(哨兵服务除外)在我的 /etc/hosts 文件中都设置为 127.0.0.1。
Ping 主机名似乎可以从控制台进行,这些错误在运行时会在各种应用程序日志中弹出。
lsof | wc -l => 700k(最大 1.6M)
VM 没有明显负载(平均负载为 10%)。没有攻击或 rootkit 或类似的东西。
我的主机文件:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1 mariadb
127.0.0.1 postgres
127.0.0.1 mongodb
127.0.0.1 redis
127.0.0.1 memcached
127.0.0.1 socketcluster
/etc/nsswitch.com 的内容
passwd: files sss
shadow: files sss
group: files sss
hosts: files mdns4_minimal [NOTFOUND=return] dns myhostname
bootparams: nisplus [NOTFOUND=return] files
ethers: files
netmasks: files
networks: files
protocols: files
rpc: files
services: files sss
netgroup: nisplus sss
publickey: nisplus
automount: files nisplus sss
aliases: files nisplus
有人知道发生了什么事吗?为什么getaddrinfo打不开hosts文件???
为这个问题添加悬赏。请不要贪图便宜。
答案1
我认为您通过讨论找到了正确的根本原因/etc/hosts
。事实上,其中一些失败主机中的域配置正确和主机首先出现nsswitch.conf
表明故障发生在打开之前/期间/etc/hosts
。
您的第一个障碍是在命令行重现问题。
我会调查这些服务是否正在运行挂载命名空间。我在某处读到 Centos 为其服务使用了更多的挂载命名空间。我依稀记得原因是它改变了一些东西,/etc/
但我可能完全错了。因此,对于 mariadb 检查这三个的输出是否匹配:
# systemd
ls -lh /proc/1/ns/mnt
# console
ls -lh /proc/self/ns/mnt
# mariadb / mysql
ls -lh /proc/$(pidof mysqld)/ns/mnt
如果 mariadb 与您的控制台不匹配,那么它位于不同的命名空间中。您应该能够通过以下方式输入该名称空间:
nsenter -mt $(pidof mysqld) /bin/bash
这将使您进一步调查发生了什么。希望它能为您提供一个与 mysql 遇到相同问题的命令行。
笔记如果问题是暂时的,那么您将需要在“中断”期间执行此操作。
下一步是寻找到底是什么失败了。目前我们猜测是这样,/etc/hosts
但在此之前还读取了其他文件。真正有用的命令是斯特雷斯
如果您可以在命令行上重现错误,则使用 strace 和一个简单的命令。例如,如果 ping 命令失败,请查看以下命令生成的输出文件:
strace -o output_file ping mariadb
如果您无法重现该错误,那么您可以 strace mariadb 本身。其输出文件将非常大,但可能会给您一些可以使用的东西
strace -o output_file -p $(pidof mysqld)
获得 strace 输出后,您可以在其中搜索失败的确切系统调用和上下文。根据您要查找的错误消息忙碌:
grep -nC5 EBUSY output_file
这将为您提供失败的系统调用以及两侧 5 行以祝您好运。这可能需要一些取证工作,但它应该告诉您到底是什么被卡住了。
答案2
这是由于只有 4096 个 inotify 处理程序造成的。我增加了限制,问题就消失了。
fs.file-max = 131070
fs.inotify.max_user_watches = 65536