在一个运行在虚拟容器(VMware)中且缺乏本地存储的高流量网站上,我们通过从直接记录到日志文件(驻留在远程网络存储上)切换到rsyslogd。
本质上,我们已经从同步日志记录切换到异步日志记录。Web 服务器工作器使用系统日志(3)到一些内存缓冲区和rsyslogd(8)将数据并行地按照自己的速度发送到实际文件,因此记录时进程不会在 IO 上阻塞。
到目前为止一切顺利。问题是偶尔rsyslogd无法写入(例如,瞬时/长时间的网络中断)并且传入缓冲区很快就会被填满。
我的问题是:
- 客户端在写入时是否会阻塞rsyslogd使用系统日志(3)?
- 有没有办法看看rsyslogd统计数据,例如缓冲区有多大/多满?
- 有没有办法增加rsyslogd传入缓冲区?
答案1
据我所知,rsyslog 中主消息队列的默认模式是固定大小数组。它限制为 10k 个元素左右。尝试将其更改为链接列表队列,它应该可以更好地处理偶尔的消息突发。
是的,有FixedArray
排队LinkedList
。
答案2
第一个问题的答案是:
是的,对 syslog() 的任何调用都是阻塞的。可能只持续很短的时间,但它仍然是涉及文件描述符的同步调用。请参阅
man 3 syslog
了解更多详细信息。
除非您的服务器使用异步架构和原语,否则总会存在一些锁定。这可以减轻,但不能消除,例如通过使用单独的线程进行日志记录。对于其他两个问题,我不太清楚,但检查 rsyslogd 源代码(以及 syslog() 系列函数的源代码)是唯一的了解方法。
更一般地说,如果你通过 UDP:514“网络系统日志协议”将日志记录移动到外部服务器,那么创建锁定的可能性几乎为零。使用可能丢失部分日志记录的缺点在高负载期间。
第一的,在“原始”服务器中,您需要确保所有日志记录都通过 syslog 进行。例如,在 Apache2 中,您需要指定:
ErrorLog "syslog:daemon"
对于其他服务器,请参阅适当的手册页。如果您无法确保这一点,请记住,登录文件系统可能会创建
第二,在原始 rsyslogd 配置中,您要求将您选择的设施(本例中为“守护进程”)的所有 syslog 流量定向到一个或多个外部 syslog 服务器。在 rsyslog 配置文件中,您可以指定:
daemon.* @192.168.128.1
daemon.* @192.168.254.1
将两份日志副本同时发送到两个不同的服务器。
第三,在目标服务器中,您启用通过 UDP:514 接收 syslog 消息。它位于(目标)rsyslogd 配置文件中,通常默认禁用(删除前导 # 就足够了:
$ModLoad imudp
$UDPServerRun 514
第四,可选但强烈推荐,我还将启用高分辨率时间戳:
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
而且此选项通常默认是禁用的(为什么?)。