紧急情况下应直接停用rsyslogd并禁用开机自启,同时启用syslog-ng等轻量替代方案;需通过进程状态、strace和dmesg确认是否为内核bug导致的死锁。

直接停掉 rsyslogd 并临时禁用,不是“治本”,但在内核 bug 导致其死锁的线上崩溃场景下,这是最快速有效的恢复手段。
确认是否为内核级死锁引发的rsyslogd异常
内核 bug 引发的 rsyslogd 死锁,往往表现为:
– 进程状态长期卡在 D(uninterruptible sleep) 或 R+(running, but in kernel space);
– strace -p $(pgrep rsyslogd) 显示系统调用卡在 write()、fsync() 或 epoll_wait() 等底层 I/O 调用上;
– 同一内核版本(如 CentOS 7.9 的 3.10.0-1160.118.1.el7.x86_64)在多台机器复现,且均伴随磁盘 I/O 延迟突增或 dmesg 中出现 INFO: task rsyslogd blocked for more than 120 seconds 类似警告。
紧急止血:绕过内核路径强制终止并隔离
普通 kill -9 可能无效(因进程处于 D 状态)。应采用以下组合操作:
- 先尝试发送 SIGSTOP 冻结进程,避免进一步抢占 CPU:
kill -STOP $(pgrep rsyslogd) - 若仍不可控,立即卸载 rsyslog 模块依赖的内核日志接口(仅限已知触发点):
modprobe -r af_packet(若 rsyslog 使用 imptcp/imudp)或echo 0 > /proc/sys/kernel/printk(临时关闭内核 printk 输出流) - 执行
systemctl stop rsyslog && systemctl disable rsyslog,并移除开机自启配置项(如/etc/systemd/system/multi-user.target.wants/rsyslog.service) - 清空其工作队列缓存(防止重启时重放导致二次卡死):
rm -f /var/lib/rsyslog/queue/*
替代方案:用轻量级日志代理临时接管
停掉 rsyslogd 后,业务日志不能中断。推荐立刻启用无内核态阻塞风险的替代方案:
- 启动
syslog-ng(其 event loop 更健壮,对某些内核 bug 不敏感):yum install syslog-ng && systemctl enable --now syslog-ng - 或使用纯用户态转发工具,如
logger+nc组合将关键日志发往远程日志中心:echo "$(date): EMERGENCY RECOVERY ACTIVE" | logger -t 'rsyslog-failover' - 若已有 ELK 或 Loki,可改用
promtail或filebeat直接 tail 日志文件,完全绕过 syslog socket 接口
后续加固与规避建议
内核 bug 往往需等待厂商补丁,但可提前规避典型触发路径:
- 禁用 rsyslog 的高风险模块:编辑
/etc/rsyslog.conf,注释掉module(load="imtcp")、module(load="imudp")、module(load="imklog") - 将日志写入方式从
sync改为async,并在action(type="omfile")中显式设置io.buffering="on"和io.buffersize="262144" - 升级前验证:在测试环境复现相同内核版本 + 磁盘压力 + rsyslog 配置,用
perf record -e 'syscalls:sys_enter_write' -p $(pgrep rsyslogd)定位卡点系统调用
这类问题不常发生,但一旦触发就是雪崩起点。核心思路是:快速隔离故障源、启用更可控的日志路径、再回溯内核层根因。等补丁发布后,再分批灰度升级验证。

















