压测后台组件TCP长连接不能就收完所有请求包,netstat命令查看Recv-Q不为0

unixplus 2015-08-24 08:16:30
首先单个客户端连接测试没有问题。
1、压测端50个线程与服务器建立50个TCP长连接
2、 然后向后台服务组件发送请求,服务器读出请求处理完成后将结构返回给压测端
3、压测端解析应答输出然后继续向服务器发送请求,这样重复100次。
问题是压测端总是只有部分线程线程能够执行完成退出,如只有20个线程完成请求退出,使用netstat -antp查看端口,发现服务端有多个连接的Recv-Q是76,应该是没有退出的线程都在等待服务器应答。但是服务器读端使用read和write系统调用,都做了中断(EINTR)继续读的处理。
服务器使用了两种架构进行测试,一种是一个连接请求一个线程处理,即一个线程只处理一个连接;另一种使用epoll IO复用处理。

1、一个连接一个线程的处理压测端也是有部分线程没有执行完成,等待服务器应答,netstat查看服务端连接Recv-Q是76。
2、使用epoll LT或ET模式处理后也是结果Recv-Q是76,奇怪的是将压测端程序退出后服务器只把压测程序处理完成的那些线程的连接关闭了,而没有处理完成的线程的连接没有关闭。当启动一个客户端向服务器端发送请求时服务器端读出的刚刚关闭的压测程序的连接发送的内容,可我已经关闭了压测程序。

不知道这是什么问题,希望大家帮解析下这个问题。

下图是 执行 netstat -antp | grep 4900命令输出的部分截图,4900是服务器绑定的端口
...全文
1264 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
unixplus 2015-08-26
  • 打赏
  • 举报
回复
引用 11 楼 xihu1364 的回复:
你不是压测么? 你可以压测的demo,先n个线程建立连接,连接完成以后,然后让所有的线程开启发消息。 在这个过程中,连接的时候,你就有时间保证连接成功
现在就每个线程建立连接后睡眠1秒,再发送请求,这样是不出问题的。 但是又有了新的问题,原来说好的有上百个TCP长连接,现在又说只有几个了。。。一个中间件,要每秒处理500个请求以上,该如何处理这几个长连接效率比比较高效呢。
版主大哥 2015-08-26
  • 打赏
  • 举报
回复
你不是压测么? 你可以压测的demo,先n个线程建立连接,连接完成以后,然后让所有的线程开启发消息。 在这个过程中,连接的时候,你就有时间保证连接成功
赵4老师 2015-08-26
  • 打赏
  • 举报
回复
楼主改为短连接再试试。
unixplus 2015-08-26
  • 打赏
  • 举报
回复
引用 4 楼 mujiok2003 的回复:
[quote=引用 3 楼 Gfeng168 的回复:] 发现主要是epoll_wait 默认LT模式下,明明有数据却不反回,即使客户端退出,在连接,返回并读出的是上个已经关闭的连接的请求内容。但是服务器关闭连接时已经从epoll中删除关闭的描述符了。对epoll使用经验不深,希望有经验的大哥指点下!!
使用现成的库吧,先解决问题。等有时间的时候, 再研究那些库是如何实现的。 [/quote] 我知道有libevent库,但是好像多线程处理比较麻烦,时间紧没有时间学。
unixplus 2015-08-26
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
你意思是我发送的请求有问题吗
unixplus 2015-08-26
  • 打赏
  • 举报
回复
引用 5 楼 xihu1364 的回复:
看是压测端的某些连接没得到应答,是服务端处理有问题吧
找到原因是有的连接没有成功建立,不知道是服务端太忙还是。如果压测端所有线程连接后睡眠1秒再发送请求可以。不然有的连接会accept出错
unixplus 2015-08-26
  • 打赏
  • 举报
回复
引用 15 楼 xihu1364 的回复:
中间件就是转发?
包含两个RPC操作返回值,第一个RPC返回的值用于第二个RPC,第二个值返回的内容取出需要的返回给请求端。现在所有组件在测试服务器上(就是一台普通PC)测试完成500个请求需要2-3秒,运行比较稳定,放到线上服务器可能会好点。epoll + 一个内存工作队列 + 多线程(池),能在哪里提高效率呢
版主大哥 2015-08-26
  • 打赏
  • 举报
回复
中间件就是转发?
unixplus 2015-08-26
  • 打赏
  • 举报
回复
引用 13 楼 lianshaohua 的回复:
[quote=引用 12 楼 Gfeng168 的回复:] [quote=引用 11 楼 xihu1364 的回复:] 你不是压测么? 你可以压测的demo,先n个线程建立连接,连接完成以后,然后让所有的线程开启发消息。 在这个过程中,连接的时候,你就有时间保证连接成功
现在就每个线程建立连接后睡眠1秒,再发送请求,这样是不出问题的。 但是又有了新的问题,原来说好的有上百个TCP长连接,现在又说只有几个了。。。一个中间件,要每秒处理500个请求以上,该如何处理这几个长连接效率比比较高效呢。[/quote] 这样做中间件?以后感觉会遇到蛮多问题的,即使是压测过关了也会遇到不少问题;因为底层的知识、网络IO的知识你好像理解的不太深入[/quote] 刚开始工作,很多以前做过的都没有经历过实战,现在要做公司用压力山大,生怕出问题。
ztenv 版主 2015-08-26
  • 打赏
  • 举报
回复
引用 12 楼 Gfeng168 的回复:
[quote=引用 11 楼 xihu1364 的回复:] 你不是压测么? 你可以压测的demo,先n个线程建立连接,连接完成以后,然后让所有的线程开启发消息。 在这个过程中,连接的时候,你就有时间保证连接成功
现在就每个线程建立连接后睡眠1秒,再发送请求,这样是不出问题的。 但是又有了新的问题,原来说好的有上百个TCP长连接,现在又说只有几个了。。。一个中间件,要每秒处理500个请求以上,该如何处理这几个长连接效率比比较高效呢。[/quote] 这样做中间件?以后感觉会遇到蛮多问题的,即使是压测过关了也会遇到不少问题;因为底层的知识、网络IO的知识你好像理解的不太深入
赵4老师 2015-08-25
  • 打赏
  • 举报
回复
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
版主大哥 2015-08-25
  • 打赏
  • 举报
回复
看是压测端的某些连接没得到应答,是服务端处理有问题吧
mujiok2003 2015-08-25
  • 打赏
  • 举报
回复
引用 3 楼 Gfeng168 的回复:
发现主要是epoll_wait 默认LT模式下,明明有数据却不反回,即使客户端退出,在连接,返回并读出的是上个已经关闭的连接的请求内容。但是服务器关闭连接时已经从epoll中删除关闭的描述符了。对epoll使用经验不深,希望有经验的大哥指点下!!
使用现成的库吧,先解决问题。等有时间的时候, 再研究那些库是如何实现的。
unixplus 2015-08-25
  • 打赏
  • 举报
回复
发现主要是epoll_wait 默认LT模式下,明明有数据却不反回,即使客户端退出,在连接,返回并读出的是上个已经关闭的连接的请求内容。但是服务器关闭连接时已经从epoll中删除关闭的描述符了。对epoll使用经验不深,希望有经验的大哥指点下!!
unixplus 2015-08-25
  • 打赏
  • 举报
回复
引用 1 楼 lianshaohua 的回复:
怀疑是服务器多线程的问题
什么问题?急啊
ztenv 版主 2015-08-25
  • 打赏
  • 举报
回复
怀疑是服务器多线程的问题

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧