我们的(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/