Linux 下 tcp 通讯程序的阻塞问题

2016-02-19 20:31:31 +08:00
 eas

这个问题有些怪异。
我们之前有一些 win 下的 c++服务端程序,最近把他转到了 linux 下面。

服务端程序提供 tcp 接口来让客户端程序连接。服务端程序提供了一个简单的 echo 服务来确认双方正常连接(一般所说的心跳检测)。每个客户端 3 秒左右一个 echo 请求,服务端收到之后立刻回复一个 echo 回复包。

问题:
在差不过 200 个客户端程序连接上之后。 客户端发出的包,会有一定几率超过 1 秒才收到回复。

目前 c++ 底层是 epoll 直接操作的。为了防止 epoll 操作有问题。我们尝试了这个 echo 程序和客户端的程序的基础 echo 逻辑 都用 golang 重新实现了一遍。

目前,我们在公司内网\腾讯云、 centos6\centos7 、 裸 linux\docker 容器 NAT 。都测试过。
都或多或少,有这个现象。

我想问,这个是正常的吗? 还是 linux 下 tcp 有什么需要特殊设置的部分?

请大神略微指点一二。 或者略微指点一二关键字也可~~~。

6482 次点击
所在节点    Linux
39 条回复
est
2016-02-20 09:10:50 +08:00
SOMAXCONN
snnn
2016-02-20 09:17:59 +08:00
@skydiver TCP 不发心跳会断。你没做过网管。
snnn
2016-02-20 09:18:16 +08:00
@redsonic 对,是这样
snnn
2016-02-20 09:19:14 +08:00
BTW ,我是做网游的
gamexg
2016-02-20 09:22:44 +08:00
golang 默认就关闭了 Nagle 。
eas
2016-02-20 10:00:55 +08:00
我的 cpp 程序和 golang 程序都是关闭了 nagle 的。

cpp 我不了解非常。但是 go 肯定多核跑的。

但是延迟 1 秒以上好诡异啊
eas
2016-02-20 10:21:50 +08:00
@est 这个我回头测试一下
eas
2016-02-20 10:37:11 +08:00
@snnn 我这 libuv 的也有在做,现在还没完整实现。主要是在不同的语言( c++ with epoll, golang ),并且都关闭 nagle 的情况下,陆续都出现了延迟 1 秒以上返回心跳回复的包。

200 左右的客户端。之前还有一些业务逻辑在这个 tcp 上跑。现在业务逻辑全部去除,写了纯粹的 echo 的服务端和客户端的实现。还是能看到这些现象
zhicheng
2016-02-20 15:55:34 +08:00
TCP 协议本身没有心跳,不会自已断开。 client 和 server 建立连接之后如果没有通信,你即使拔掉网线再插上连接都不会断。
心跳一定要在业务层做,并且一定不能单独开线程或进程。不然仅仅是一个检测网络是否连通,进程或系统是否挂掉的工具,这些用第三方就可以了。
skydiver
2016-02-20 16:20:03 +08:00
@snnn 你再好好复习一下基础知识吧。。
skydiver
2016-02-20 16:20:43 +08:00
@zhicheng +1 把我想说的都说了
leeyiw
2016-02-20 19:27:11 +08:00
给 LZ 一个排查的思路:
在 client 和 server 端把 echo 的日志打印出来,然后配合 tcpdump 把包也抓下来,遇到延时高的请求,这两者可以具体定位到是应用层处理有问题 or 网络的问题 or 协议栈的问题。
tftk
2016-02-20 19:43:12 +08:00
TCP 中的连接, keepalive 都是在两端抽象出来的概念,不是现实中的线,网络不通就会断,心跳包的存在也仅仅只是为了探测一下两端是否还在线。
firefox12
2016-02-20 20:40:06 +08:00
tcpdump 先在 2 边抓包 确定, 是服务器发包慢, 客户端收包慢 还是网络传输问题。

200 客户端都出现这个问题 C1000k 怎么办
snnn
2016-02-20 21:50:32 +08:00
@firefox12 嗯,我觉得你说的有道理。建议楼主认真考虑下这个。看看服务器端是否是每 3 秒收到了一个包, request 和 response 直接的间隔是多少。
eas
2016-02-21 10:26:15 +08:00
@zhicheng 我的心跳检测的确是在业务层内做的。只是发现有问题之后,我把其他代码都擦掉了,纯粹测试心跳时间而已。

@firefox12 之前有简单 tcpdump 过,好像是收发包都速度快的,好像是网络传输的问题。我回头再详细的从新做一次这方面的测试。
yangxin0
2016-02-21 10:53:48 +08:00
检查服务器 liaten 的 backlog 是否过小
firefox12
2016-02-21 19:48:08 +08:00
之前有简单 tcpdump 过,好像是收发包都速度快的,好像是网络传输的问题。

..... 这是什么情况,看服务器的 tcpdump 数据 看 recv 和 send 的时间差是多少 如果是 1 秒多 那么就是服务器的问题,如果是 0.001 秒 那么服务器就没问题,要么就是客户端和网络。

然后看客户端的 send 和 recv 时间查,情况同上。

如果 2 个都是 0.001 秒 那么就是网络问题。 还有可能就是 客户端的 send 时间戳 你算得不对。
eas
2016-02-22 10:55:51 +08:00
@firefox12 好的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/257745

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX