返回信息流多个客户端每秒钟共有8w多条数据发送到服务器,服务器端负责接收数据。每个客户端会和服务器维持一个tcp长连接,一共会有几十个长连接。客户端发送给服务器的每条数据都有一个ID号,服务器接收数据后会将该ID返回给客户端,客户端再发下一条数据(实际中有一个ID号的滑动窗口)
我使用gevent编写了一个单进程单线程的数据接收(gevent socket)程序,每个接收数据的长连接都分别占一个协程,该进程性能测试结果约为:12000 msg/s
由于性能不够,我想着发挥多核的威力,于是又使用tornado,开了多个进程,经测试每个进程的吞吐率竟然只有4000+ msg/s,在每一个可能阻塞的地方都使用了异步调用,确保不会发生阻塞
我想问问论坛大神,tornado性能下降这么多是因为它的框架太重了?针对长连接数量不多,但是吞吐量比较大的情况,有什么好的解决办法?
这是一条镜像帖。来源:北邮人论坛 / python / #15401同步于 2016/8/7
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Python机器人发帖
Python长连接吞吐率问题
tastier
2016/8/7镜像同步9 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
确实是这个思路,gevent + multiprocess的方法,这个帖子太老了,程序跑不同,我参考的这里:https://gist.github.com/denik/1169975
效率提高不少
【 在 huawudi 的大作中提到: 】
: 试试这个可行否?http://my.oschina.net/visualgui823/blog/36987
【 在 tastier 的大作中提到: 】
: 确实是这个思路,gevent + multiprocess的方法,这个帖子太老了,程序跑不同,我参考的这里:https://gist.github.com/denik/1169975
: 效率提高不少
tornado能不能不用multiprocess,而是用单线程呢?
可以,tornado有一套自己的process,但我理解tornado的亮点不就是发挥多核吗
ps:暖神竟然换头像了[ema29]
【 在 nuanyangyang (暖羊羊) 的大作中提到: 】
: tornado能不能不用multiprocess,而是用单线程呢?
【 在 tastier 的大作中提到: 】
: 可以,tornado有一套自己的process,但我理解tornado的亮点不就是发挥多核吗
: ps:暖神竟然换头像了
关键是网络程序大多数瓶颈是网络而不是CPU。多线程反而会增加调度的开销。
io密集型的任务,不就是用多线程吗,或者事件驱动
【 在 nuanyangyang (暖羊羊) 的大作中提到: 】
: 关键是网络程序大多数瓶颈是网络而不是CPU。多线程反而会增加调度的开销。
【 在 tastier 的大作中提到: 】
: io密集型的任务,不就是用多线程吗,或者事件驱动
刚好相反。io密集型的任务,多线程帮不上什么忙。“线程”是CPU调度的单位。多个线程可以有助于提高CPU利用率,但对于IO密集型,多加一个CPU并不能增加IO的速度。反而会因为要不断从一个线程切换到另一个线程,还有线程间同步的代价,速度反而会比单线程还慢。google一下“c10k problem”。
首先建议排除下带宽瓶颈,8w条数据,每条数据多大?
然后建议优化下协程的逻辑,找找瓶颈在什么地方,是否有cpu bound运算,看看cpu占用
最后再不行就考虑换框架或者调整业务架构吧。。
另外有个疑问,你这个8w条/s的需求有理论验证过吗?看你的逻辑是客户端发送给服务器数据,服务器返回后客户端再发下一条数据,这种通信模式必然会影响吞吐率啊,特别是延迟高的情况下。要不要试试单客户端的情况下能不能达到要求?
【 在 tastier 的大作中提到: 】
: 多个客户端每秒钟共有8w多条数据发送到服务器,服务器端负责接收数据。每个客户端会和服务器维持一个tcp长连接,一共会有几十个长连接。客户端发送给服务器的每条数据都有一个ID号,服务器接收数据后会将该ID返回给客户端,客户端再发下一条数据(实际中有一个ID号的滑动窗口)
: 我使用gevent编写了一个单进程单线程的数据接收(gevent socket)程序,每个接收数据的长连接都分别占一个协程,该进程性能测试结果约为:12000 msg/s
: 由于性能不够,我想着发挥多核的威力,于是又使用tornado,开了多个进程,经测试每个进程的吞吐率竟然只有4000+ msg/s,在每一个可能阻塞的地方都使用了异步调用,确保不会发生阻塞
: ...................