根本解法是启用rsyslog的磁盘辅助队列(LinkedList类型),需在远程动作中显式配置queue.type="LinkedList"、queue.filename、action.resumeRetryCount="-1"和queue.saveonshutdown="on"四项参数,缺一不可。

根本解法是把默认的纯内存队列,替换成“内存为主、磁盘兜底”的磁盘辅助队列(disk-assisted queue),而不是等溢出再抢救。rsyslog 本身不提供“自动降级”机制,必须在配置中显式启用 LinkedList 类型并绑定磁盘文件,否则一旦远程服务断开,日志持续写入就会卡死在内存队列里。
确认当前队列类型和问题根源
先检查你正在使用的转发动作是否还在用默认内存队列:
- 运行 rsyslogd -N1 验证配置语法,同时留意输出中是否有 "action queue type: LinkedList" —— 没有就说明没启用磁盘辅助
- 查配置文件(如 /etc/rsyslog.d/50-remote.conf),看远程动作是否缺少 queue.type="LinkedList" 和 queue.filename
- 观察 /var/lib/rsyslog/ 下有没有以你设置的 queue.filename 开头的 .qf 或 .qi 文件 —— 没有就代表磁盘队列压根没激活
配置磁盘辅助队列的关键参数
在远程转发动作中,必须包含以下四项,缺一不可:
- queue.type="LinkedList":唯一支持磁盘落盘的队列类型,不是 FixedArray 或 Direct
- queue.filename="xxx":指定磁盘队列文件前缀(如 remoteq),rsyslog 会自动生成 .qf/.qi 文件
- action.resumeRetryCount="-1":无限重试,避免网络恢复后丢弃积压日志
- queue.saveonshutdown="on":关机或重启前强制刷盘,防止断电丢失
建议补充:queue.maxdiskspace="1g"(防磁盘写满)、queue.size="100000"(内存部分容量上限)、queue.dequeuebatchsize="1000"(提升重传效率)。
验证与主动测试容错能力
配完不能只等出事,要主动验证是否真能扛住中断:
- 临时阻断远程端口:sudo iptables -A OUTPUT -d 192.168.10.100 -p tcp --dport 514 -j DROP
- 用 logger "test message $(date)" 连续发几十条日志
- 立刻检查:ls -lh /var/lib/rsyslog/remoteq* —— 应出现非零大小的 .qf/.qi 文件
- 恢复网络后,观察 rsyslog 日志中是否出现 "resuming operation" 及重传记录
避免常见配置陷阱
这些错误会让磁盘辅助形同虚设:
- 只写了 queue.filename 却漏了 queue.type="LinkedList" —— rsyslog 会静默忽略磁盘参数
- 把队列参数写在 module() 加载块里,而不是写在 action() 动作定义内部 —— 参数不生效
- 权限问题:/var/lib/rsyslog/ 目录属主不是 syslog 或 rsyslog 用户,导致无法创建队列文件
- 用 UDP 转发却没设 action.resumeInterval —— TCP 才支持可靠重连,UDP 丢包即丢日志
配完记得 sudo systemctl restart rsyslog,别只 reload。

















