【问题标题】:concerned about perl IO::Socket losing UDP packets担心 perl IO::Socket 丢失 UDP 数据包
【发布时间】:2017-05-05 15:46:31
【问题描述】:

我有一个小型 UDP perl 服务,它接收 syslog 数据,对其进行处理,然后将其按原路(通过 UDP)发送回也在 localhost 上运行的 syslog 服务器。它工作得非常好,但我担心它可能会丢失 syslog 事件,所以对其进行了测试

基本上我推送了 100 条“这是一个测试 $NUM++”消息,有时会出现 100 条 - 但一旦出现 99 条(由运行 perl 脚本的主机上运行的 tcpdump 测量)。这是在我们的生产系统上,它处理 500-1500 syslog msg/sec。像往常一样,当它只有测试流量时它工作得很好,但在负载下我不确定。

tcpdump 显示通过 eth0 传入的 100 个事件,但 tcpdump 显示通过 lo 传出的 99 个事件。因此,也许有人从未进入“$rcvSock”,或者有人通过“$sndSock”迷路了

perl 代码基本上如下所示。但是,“#fiddling”位确实涉及 DNS 查找的一些暂停,因此有一些“读取->块->写入”正在进行。我认为 UDP 不支持“侦听”,所以我无法确定 perl 脚本在“摆弄”时是否阻止并丢弃下一个接收?

谁能阐明损失可能发生在哪里以及如何克服损失?

$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");
}

【问题讨论】:

  • 这与 Perl 无关,但 UDP 是一个简单的不可靠协议。 What are the chances of losing a UDP packet? 的可能重复项
  • 确实 UDP 是一个不可靠的协议。但如果速度变慢,可能是 Perl 应用程序的问题

标签: perl sockets udp


【解决方案1】:

感谢 SO_RCVBUF 成功了。

正在发生的事情是我每秒推入(比如说)1000 个系统日志记录/数据包,但是我的 DNS 查询确实将处理暂停了 1 秒/记录。所以这意味着在处理 ONE 记录后,现在有 999 条记录需要处理。两秒钟后是 1998 年。这看起来不太好......

操作系统可以根据 SO_RCVBUF 对这些数据包进行排队,默认情况下(在 Redhat 上)为 212992 字节。因此,假设每个 syslog 记录平均有 400 字节,在内核开始丢弃新数据包之前,最多有约 530 条记录排队。所以我可以将 SO_RCVBUF 增加 10 甚至 100 倍,但它无法解决那个大停顿的根本问题。然而,实际上我说的是峰值速率:有时记录/秒会下降,并且许多系统日志记录不需要 DNS 查找(即我跳过它们)。此外,通过缓存这些 DNS 查找,我可以最大限度地减少它们完成的时间,因此 1000/秒可能是涉及 DNS 的 101/秒,这反过来可能是 99% 可缓存的,导致只有 2-5/秒需要 DNS 查找 - 在该级别上,健康的缓存将帮助您解决峰值负载问题

我不是程序员,所以用输入队列、异步 DNS 查找等正确执行此操作超出了我的能力范围。但我确实知道 iptables ......所以我打算在不同的端口上运行其中的几个,并使用 iptables 将传入的数据包循环传递到它们上,为它们提供异步功能,而无需我编写一行代码.这应该可以解决我需要担心的负载水平:-)

谢谢!

【讨论】:

    【解决方案2】:

    尝试增加SO_RCVBUF

    IO::Socket::INET->setsockopt(SOL_SOCKET, SO_RCVBUF, ...)

    sar 对网络统计调查很有帮助。

    idgmerr/s 每秒接收的 UDP 数据报数 没有提交申请以外的其他原因无法交付 目标端口 [udpInErrors]。

    $ sar -n UDP 5
    
    08:18:12 AM    idgm/s    odgm/s  noport/s idgmerr/s
    08:18:15 AM    121.33    121.33      7.67      0.00
    

    【讨论】:

      猜你喜欢
      • 2015-06-30
      • 2012-07-15
      • 2018-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多