1

我使用带有 {active, true} 的 TUNCTL 从 TUN 接口获取 UDP 数据包。该进程获取数据包并将它们发送到另一个可以工作的进程,然后将它们发送到另一个进程,该进程使用 gen_udp 将它们推出不同的接口。相同的过程以相反的方向重复,我使用 gen_udp 获取数据包并将它们发送到 TUN 接口。

当 CPU 负载接近 50%(大约 2500 个数据包/秒)时,我开始在传入的 TUN 接口上看到溢出。我永远不会在 gen_udp 端丢失任何数据包,只有 tunctl。为什么我的应用程序在 CPU 没有过载的情况下没有从 TUN 接口获取所有数据包?我的进程的消息队列中没有消息。

我玩过进程优先级和缓冲区大小,但这并没有多大作用。总 CPU 负载会有所不同。我设法降低了 CPU 负载,但即使我看到 TUN 接口吞吐量略有增加,现在它似乎在较低的 CPU 负载下达到最大值,比如 50% 而不是 60%。

TUNCTL/Procket 是否无法足够快地读取数据包,或者 TUNCTL/Procket 是否由于某种原因没有获得足够的 CPU 时间?我的理论是,Erlang Scheduler 不知道它在调用 NIF 时需要多少时间,也不知道 TUN 接口上未处理消息的数量。我需要弄脏 C++ 和/或编写自己的 NIF 吗?帮助!

4

1 回答 1

0

正如预期的那样,当活动为真时,TUNCTL 没有获得足够的 CPU 时间是一个问题。我使用 procket:read 从 TUN 缓冲区获取数据包。使用这种方法,您可以指定检查缓冲区的频率,这告诉 Erlang 调度程序您的进程需要多少时间。如果需要,这让我可以将 CPU 加载到 100%,并允许我从 TUN 接口获取我需要的所有数据包。瓶颈解决了。

于 2018-10-29T23:55:38.843 回答