如何实现rsyslog客户端日志与服务器本地消息日志分离并支持20万客户端大规模部署
如何实现rsyslog客户端日志与服务器本地消息日志分离并支持20万客户端大规模部署
我来给你拆解下这个问题,分两步解决:先搞定日志和本地消息的彻底分离,再优化配置让它能扛住20万客户端的大规模压力。
一、核心:把客户端日志和服务器本地日志彻底分开
你现在遇到的问题是客户端日志既进了专属文件,又蹭进了/var/log/messages,本质是rsyslog的日志处理规则是自上而下执行的,默认规则会把所有没被提前拦截的日志都写入messages。所以关键是:把客户端日志先过滤出来,写完专属文件后就终止它的处理流程,不让它走到后续的本地规则里。
具体改法结合你的现有配置来:
- 先给客户端日志整个专属的模板(可选,但统一格式方便后续排查):
template(name="ClientLogTemplate" type="string" string="%timestamp:::date-rfc3339% %HOSTNAME% %syslogtag% %msg:::drop-last-lf%\n")
- 加一个过滤规则,匹配所有远程客户端的日志,写入专属存储后直接终止处理:
# 匹配所有非本地来源的日志(也就是客户端发过来的) if $fromhost-ip != '127.0.0.1' then { # 按客户端主机名分文件存储,也可以按IP改路径 action(type="omfile" file="/var/log/clients/%HOSTNAME%.log" template="ClientLogTemplate" asyncWriting="on") & stop # 重点!这条指令让日志不再往下走,不会进本地的messages }
- 然后给本地日志单独加规则,确保只有服务器自己的日志进
messages:
# 只处理本地来源的日志 if $fromhost-ip == '127.0.0.1' then { action(type="omfile" file="/var/log/messages" template="RSYSLOG_TraditionalFileFormat") }
这样改完,客户端日志就只会进你指定的专属文件,再也不会出现在/var/log/messages里了,单客户端的场景绝对没问题。
二、升级:适配20万客户端的大规模部署
20万客户端的核心挑战是高并发连接、日志吞吐量、磁盘IO阻塞,得从网络模块、线程队列、存储优化这几个地方下手:
1. 换掉UDP,用TCP做传输
UDP在高并发下丢包太严重,完全扛不住20万客户端的规模,换成IMTCP模块,还得调整参数撑住最大连接数:
# 卸载旧的UDP模块(如果不用的话) # $ModLoad imudp # $UDPServerRun 514 # 加载TCP模块,调整最大连接数、监听队列 module(load="imtcp" MaxSessions="200000" ListenBacklog="32768") # 把远程客户端的日志处理放到单独的规则集,用多线程缓冲 input(type="imtcp" port="514" ruleset="RemoteClientRules")
2. 用规则集+队列做异步缓冲
把客户端日志的处理逻辑放到单独的规则集,用队列缓冲高并发的日志,避免rsyslog进程被IO阻塞:
ruleset(name="RemoteClientRules" queue.type="linkedlist" queue.size="200000" queue.workerThreads="8") { if $fromhost-ip != '127.0.0.1' then { action( type="omfile" file="/var/log/clients/%HOSTNAME%.log" template="ClientLogTemplate" asyncWriting="on" # 异步写入磁盘,不卡主进程 queue.type="linkedlist" queue.size="50000" ) & stop } }
这里的queue.workerThreads是开多个线程处理日志,queue.size是缓冲队列的大小,根据你的服务器内存调整就行。
3. 全局参数和系统内核优化
- 调整rsyslog全局参数,增加线程数、消息大小:
global( workDirectory="/var/lib/rsyslog" maxMessageSize="64k" numWorkerThreads="16" # 按服务器CPU核心数调整,比如8核开16线程 )
- 调整系统内核参数(编辑
/etc/sysctl.conf,然后执行sysctl -p生效),撑住高并发TCP连接:
net.ipv4.tcp_max_syn_backlog = 65536 net.core.somaxconn = 65536 net.ipv4.tcp_tw_reuse = 1 net.ipv4.ip_local_port_range = 1024 65535
4. 日志存储的小技巧
如果20万客户端每个都生成一个日志文件,文件数量太多会拖垮文件系统,建议:
- 按网段+日期分片存储,比如
/var/log/clients/192.168.1.%Y%m%d.log - 用XFS文件系统,它比EXT4更适合存储大量小文件
- 定期归档旧日志,避免磁盘被占满
最后提醒
改完配置后先拿几十台客户端测试下,看看日志分离是否生效,有没有丢包;然后再逐步扩容到20万,同时监控rsyslog的队列长度、CPU和磁盘IO,根据实际情况调整参数。
备注:内容来源于stack exchange,提问作者Gongze




