我们的(Linux)服务器在套接字上使用了{active, once}选项,并且弹出了{tcp_error, Socket, etimedout}消息。我知道这可能是由不良的网络状况引起的,但是有一些奇怪的地方。

在我们的计算机上,系统范围内启用了TCP keepalive,而实际的选项值为:

net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75

我相信这意味着套接字将在至少20分钟内超时。但是奇怪的是,我们的进程在不到10秒的时间内收到了{tcp_error, Socket, etimedout}

我想知道,它是由gen_tcp:send(...)操作触发的吗?然后我发现这是不可能的,因为发送操作都是同步的,它们会立即失败。

所以,我的问题是,etimedout消息从何而来?或究竟是什么触发了它?我无所适从Erlang VM的C源代码,尤其是inet_drv.c,但是还没有结论。

谢谢。

最佳答案

tcpdump捕获显示这是TCP重传的超时事件。

我们的服务器计算机的/proc/sys/net/ipv4/tcp_retries2设置为5,这将导致5次重传时断开连接,而在开发人员计算机上,此值默认为15,因此我们无法在本地重现该问题。

gen_tcp:send(...)(或其他语言的等效API)返回仅表示该数据包已被TCP堆栈接受,但不能保证该数据包可以到达对等方,并且当您被阻止执行其他操作时,错误可能会解决。

找到有关TCP重传here的简要描述。

关于linux - 事件套接字的 '{tcp_error, Socket, etimedout}'消息从何而来?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20093028/

10-15 12:15