活动套接字的“{tcp_error,Socket,etimedout}”消息来自哪里?

我们的(Linux)服务器在它的套接字上使用了{active, once}选项,并且{tcp_error, Socket, etimedout}消息。 我知道这可能是由于networking条件不好造成的,但是有一些奇怪的事情。

TCP keepalive在我们的机器上被全系统启用,实际的选项值是:

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

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

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

所以,我的问题是,这个消息来自哪里? 或者究竟是什么触发了它? 我围绕Erlang VM的C源代码进行了inet_drv.c ,尤其是inet_drv.c ,但还没有结论。

谢谢。

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

我们的服务器机器将/proc/sys/net/ipv4/tcp_retries2设置为5,这将导致5次重新传输中的连接断开,而在开发者机器上这个值默认为15,所以我们不能在本地重现问题。

gen_tcp:send(...)返回gen_tcp:send(...) (或其他语言的等效API)仅意味着数据包被TCP堆栈接受,但不能保证它可以到达对等点,并且当你阻止其他操作。

在这里找到关于TCP重传的一些简要描述。