我有一个小的UDP perl服务,它接收syslog数据,用它来解决它,然后通过它(通过UDP)将它发送回同样在localhost上运行的syslog服务器。它工作得很好,但我担心它可能会丢失syslog事件,所以测试它
基本上我推了100"这是一个测试$ NUM ++"消息输入,有时100会出现 - 但一旦99出现(通过运行perl脚本的主机上运行的tcpdump来衡量)。这是在我们的生产系统上,它处理500-1500 syslog msg / sec。像往常一样,当它只有测试流量时,它可以很好地工作,但在负载下我不确定。
tcpdump显示了超过eth0的100个事件,但是tcpdump显示99超过了lo。所以也许有人从来没有把它变成了'rcvSock'或者也许有人迷失了通过' $ sndSock'
基本上perl代码如下所示。然而,"#fiddling" bit确实涉及DNS查找的一些暂停,所以有一些" read-> block-> write"继续我不认为"听"在UDP下受支持,所以我无法确定perl脚本是否阻止下一次接收,而它正在进行" fiddling"?
任何人都可以了解损失可能发生的位置以及如何通过它吗?
$rcvSock = IO::Socket::INET->new(
LocalAddr => $hn,
LocalPort => $rcvPort,
Timeout => $timeout,
Proto => 'udp'
);
$sndSock = IO::Socket::INET->new(
PeerAddr => $syslogSrv,
PeerPort =>$syslogPort,
Timeout => $timeout,
Proto => 'udp',
Blocking => 0
);
while (1) {
$now=time;
$rcvSock->recv($input,2560);
$remote_addr=$rcvSock->peerhost();
#fiddling occurs
$sndSock->send("$input");
}
答案 0 :(得分:0)
谢谢你SO_RCVBUF的伎俩。
正在发生的事情是我每秒推送(比方说)1000个系统日志记录/数据包,但DNS查询我暂停处理1秒/记录。所以这意味着在处理完一条记录之后,现在有999条记录需要处理。在1998年之后的两秒钟。这看起来并不好......
操作系统可以根据SO_RCVBUF对这些数据包进行排队,默认情况下(在Redhat上)为212992字节。因此,假设每个syslog记录平均有400个字节,那么在内核开始丢弃新数据包之前,最多可排队约530个记录。所以我可以将SO_RCVBUF 10提高100倍,但它不会解决那个大停顿的根本问题。然而,实际上我在谈论峰值速率:有时候记录/秒下降,并且许多系统日志记录不需要DNS查找(即我跳过它们)。同样通过缓存那些DNS查找,我可以最大限度地减少完成它们的时间,因此1000 /秒可能是101 /秒涉及DNS,而这反过来可能是99%可缓存,导致只有2-5 /需要DNS查找的秒 - 在该级别,健康的缓存将帮助您解决峰值负载问题
我不是程序员,因此使用输入队列,异步DNS查找等正确执行此操作是我无法做到的。但我确实知道iptables ...所以我打算在不同的端口上运行其中的几个,并使用iptables循环传递传入的数据包到它们上面,给它们提供异步功能而不需要编写一行代码。这应解决我需要担心的负载水平: - )
谢谢!
答案 1 :(得分:-1)