tcp - 为什么 Windows7 上的 TCP/IP 需要 500 次发送才能预热? (w10,w8 证明没有受到影响)

标签 tcp zeromq winsock distributed-computing low-latency

我们在 Windows 7 上看到 ZeroMQ 出现奇怪且无法解释的现象,通过 TCP 发送消息。(或通过 inproc,因为 ZeroMQ 在 Windows 上在内部使用 TCP 进行信号传输。

现象是前500条消息到达的速度越来越慢,延迟稳步上升。然后延迟下降,消息始终快速到达,但 CPU/网络争用导致的峰值除外。

此处描述了问题:https://github.com/zeromq/libzmq/issues/1608

一直是500条消息。如果我们没有延迟地发送,那么消息会被分批处理,所以我们会看到这种现象会持续数千次发送。如果我们在发送之间延迟,我们会更清楚地看到图表。即使在发送之间延迟多达 50-100 毫秒也不会改变事情。

消息大小也无关紧要。我用 10 字节的消息和 10K 的消息进行了测试,结果相同。

最大延迟始终为 2 毫秒(2,000 微秒)。

在 Linux 机器上我们没有看到这种现象。

我们想要做的是消除这条初始曲线,以便消息以其正常的低延迟(大约 20-100 微秒)离开新连接。


Update: the issue does not show on Windows 10 nor 8. It seems to happen only on Windows 7.

最佳答案

我们已找到原因和解决方法。这是 Windows 7(至少)上所有 TCP 事件的一个普遍问题,由接收端的缓冲引起。您可以在“TCP 慢启动”下在线找到一些提示。

在一个新的连接上,或者如果连接空闲了(我认为)150 毫秒或更长时间,接收方缓冲传入的数据包并且将这些提供给应用程序,直到接收缓冲区是已满和/或某些超时到期(不清楚)。

我们在 ZeroMQ 中使用 TCP 套接字进行线程间信号传输的解决方法是在新信号对上发送一个虚拟数据 block 。这会强制 TCP 堆栈“正常”工作,然后我们会看到大约 100-150 微秒的一致延迟。

我不确定这是否普遍有用;对于大多数应用程序来说,在接收时稍等片刻是有利可图的,这样 TCP 堆栈就可以向调用应用程序传递更多信息。

但是对于发送许多小消息的应用程序,此解决方法可能会有所帮助。

请注意,如果连接空闲,慢速启动会再次发生,因此连接应该每 100 毫秒左右检测一次,如果这很关键的话。

关于tcp - 为什么 Windows7 上的 TCP/IP 需要 500 次发送才能预热? (w10,w8 证明没有受到影响),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33409749/

相关文章:

Python连续TCP连接

c++ - 将 os x 10.9 上的 zeromq 3.2 与 libstdc++ 链接起来

c - 安全软件讨厌我的套接字

windows - winsock 周围的 BSD 套接字兼容包装器?

java - 通过 TCP 接收用户定义的对象并出现 ClassNotFoundException

java - 跨平台和跨语言的客户端/服务器应用程序连接

multithreading - 使用 ZeroMQ 套接字时,我可以从一个线程发送()并从另一个线程接收()到同一个套接字吗?

protocols - ZeroMQ + Protocol Buffer

c - 在 Windows 中的套接字上使用 fprintf

c - 如何在接受多个客户端连接时设置 TCP 服务器超时