feat: deliver UDP packets from same connection in receiving order #1540
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
当前 UDP 转发的实现是,将 UDP 报文收到一个 channel 内,然后启动多个 worker 一并 poll 该 channel. 这样一来,同一条 UDP 连接的包可能被不同的 worker 收走,worker 内又没有保序机制,由于 worker 的异步特性,最终导致发出的 UDP 包乱序。
虽然说 UDP 不提供任何顺序保证,但乱序还是会不可避免地导致上层感受到的延迟经常跳动,还是会影响使用体验。因此,能够避免的乱序还是最好要避免。特别是,即便专门采用了能够保证底层有序的传输通道,这里的问题会导致发出的包仍然乱序,这样也是比较难接受的。
本提交参考网卡的 RSS 机制,将 queue 分为每个 worker 一个,将传入的包的 IP 地址、端口、协议进行哈希(实际因为都是 UDP,所以不再计算协议),然后根据哈希结果将包分配到一个 queue、一个 worker 去处理,这样对于同一条连接的包就可以保证都在一个 worker 中处理,借此解决乱序问题。
性能方面我预计是没有明显影响的,因为以前 natTable 里面每条连接也有锁,导致以前的单连接转发性能也有单 worker 瓶颈。多连接性能至少是不受影响,且因为锁的争抢减少乃至消失,甚至还可能有提升。新引入的哈希代码会有一些开销,但是相比后面的加解密部分,这里的开销应当可以忽略不计。
这基本上算是我第一次接触 Go 语言,如有问题,请不吝赐教。谢谢!