【问题标题】:Raise TimeoutError: [Errno 110] Connection time out while sockt.send_all(request)引发 TimeoutError:[Errno 110] 连接超时,而 sockt.send_all(request)
【发布时间】:2019-02-22 02:33:12
【问题描述】:

客户端套接字设置:

 s = socket.create_connection(self._addr, timeout=15)
 s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
 s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
 s.settimeout(300)

服务器套接字设置:

 sock = socket.socket(family=socket.AF_INET)
 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 sock.setblocking(False)
 sock.bind(addr)
 sock.listen(512)

每台客户端机器大约 300 个客户端(8 核 CPU)。 每个服务器工作者服务大约 300 个客户端。 请求主体很小,可能只有 2KB。 有时客户端会在 s.send_all(request) 远小于 300s 时引发超时错误,尤其是在客户端密集请求时。

我不知道问题出在哪里?在客户端还是服务器端?

【问题讨论】:

    标签: sockets concurrency timeout


    【解决方案1】:

    最后我发现原因与并发性无关。它是由 LB 和 keep-alive 选项引起的。

    服务端发送 FIN 时,无论客户端是否发送 FIN,LB 都会在 2 分钟后删除连接信息。

    客户端没有向服务器发送 FIN,并且在 tcpkeepalivetime 之后,客户端将开始发送检测消息,但由于连接信息已删除,LB 无法识别。因此客户端将重试 tcpkeepaliveprobes 次,然后发送 RST。

    在此之后,如果客户端发送一些东西,则会引发 TimeoutError。

    在我的应用程序中,服务器不会主动发送消息。

    我对这种情况的解决方法是:客户端发送前,检查socket是否可读,如果socket可读,则连接不正常,需要关闭socket重新与服务器连接。

    (请原谅我的英语不好,我希望这可能对某人有所帮助)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-12
      相关资源
      最近更新 更多