多个tcp套接字,其中一个已停止
Multiple tcp sockets, one stalled
我正试图找到一个起点,从哪里开始理解可能导致套接字停滞的原因,并感谢您可能提供的任何见解。
所以,服务器是一个现代的双插槽xeon (2 x 6核@ 3.5 ghz)运行windows 2012。在单个进程中,有6个带有默认选项的阻塞tcp套接字,每个套接字都在自己的线程上运行(不是指定的numa/core)。其中5个连接到同一个远程服务器,并且接收非常重的负载(每秒数十万个~75字节的小msg)。最后一个套接字连接到另一个服务器,用于管理消息传递的发送/接收负载非常轻。我遇到的问题是管理消息套接字中出现了5秒的停顿。对套接字的多次发送调用成功返回,但是没有从远程服务器接收到任何内容(应该在几毫秒内接收到协议ack),也没有被远程管理服务器接收到5秒。就好像那个插座关闭了一会儿。5秒的停顿过后,所有的声音突然响起,之后一切又恢复正常。在此期间,其他套接字接收的消息数量比正常情况下高得多,但是没有任何中断或停滞的迹象,因为数据日志没有显示任何异常(少量日志记录,可能为500 msgs/sec)。
据我所知,套接字发送调用并不能确保数据已经在线路上发出,只是确保向tcp堆栈的传输成功。所以,我试图理解可能发生的不同情况,这可能会导致管理套接字上出现5秒的停顿。是否有可能由于接收到大量数据,tcp堆栈基本上不堪重负,并优先考虑那些利用率最高的套接字?还有什么其他情况可能导致这种情况?
谢谢!
如果套接字每秒接收数十万个75字节的消息,则服务器可能已达到某些资源的最大容量。也许不是带宽,因为对于100K的消息,您可能会消耗大约10Mbps。但也可能是CPU利用率。
你应该使用两个工具来理解你的问题:
- perfmon查看CPU(用户和特权https://technet.microsoft.com/en-us/library/aa173932(v=sql.80).aspx)、内存、带宽和磁盘队列长度的利用率。你也可以用perfmon检查中断和上下文切换的数量。
- 一个嗅探器,如Wireshark,以查看是否在TCP级别的数据正在传输和响应接收。
- 我要做的另一件事是写一个时间戳后发送调用和之前和之后的读调用在负责管理套接字的线程。可能是编码问题。
send调用成功返回的事实并不意味着数据被立即发送。在TCP中,数据将被存储在发送缓冲区中,从那里,TCP堆栈将数据发送到另一端。
如果您的系统是CPU限制的(您可以通过perfmon看到这是否为真),那么您应该注意@EJP写的注释,这是在机器处于高负载时可能发生的事情。使用我提到的工具,您可以查看管理套接字中的接收窗口是否关闭,或者只是套接字读取占用了管理套接字中的时间。
- 一个非常简单的win32套接字代码,但工作错误
- 在线程C++中创建一个套接字
- UDP 套接字读取最后一个传入字节
- 通过 c++ 中的 udp 套接字将派生类对象从一个进程发送到另一个进程
- 我正在编写一个简单的客户端套接字应用程序,但在连接后服务器收到一个空缓冲区
- 当我使用套接字代码发送第二条消息时,我有一个"sendto() Invalid argument"
- 是否可以寻址另一个网络中的服务器/客户端套接字?(C++)
- 我可以将一个套接字添加到多个 epoll 实例吗?
- 每个线程或每个调用一个 ZeroMQ 套接字
- QSocketNotifier:不能从另一个线程启用或禁用套接字通知程序
- 我正在尝试用 DevC++ 编译一个套接字程序,但每次我这样做时,我都会收到很多链接器错误,如下所示:
- 处理一个套接字和多个线程时异步 IO 的用例
- 服务器多线程无法保存最后一个套接字描述符
- 异步等待,直到在Asio中有一个套接字可用于读/写
- 同时等待一个条件(pthread_cond_wait)和一个套接字更改(select)
- 如何在一个套接字上实现并行请求和响应的非阻塞客户端-服务器通信模型,而不存在数据竞争
- 如何从一个套接字读取' 1 '字节,而从另一个套接字读取' read_some '字节
- 在android代码中创建一个套接字(而不是在android应用程序中)获得Permission Denied
- 通过ZeroMQ以字符串形式接收对象,然后通过另一个套接字以零拷贝发送对象的正确方法是什么
- 线程中一个套接字发送/接收