sofa-pbrpc
sofa-pbrpc copied to clipboard
性能优化
40万qps在两年前处于领先地位,而今天已经被很多竞品超越。 希望拿出几天时间优化下性能,将极限吞吐提升到100万qps以上。
优化了两点
- 多线程共享一个io_service导致server没有线程扩展性,现在改成了io_service per cpu
- ptime_now函数使用了boost库中的取时间函数,gmtime_r这个应该是有锁的
以上两点优化后,在 Intel(R) Xeon(R) CPU E5-2450 v2 @ 2.50GHz 128g RAM
机器上,qps大概110w左右
左言,有没有什么别的建议
非常赞。其实还是有不少地方可以优化的,你可以通过搜索代码中的TODO找出一些,譬如:
- client中controller_map的存取需要加锁
- RpcMessageStream::_pending_calls存取需要加锁,可以考虑改为无锁队列
另外,还想到一些:
- 链接tcmalloc
- 改进日志打印库,提高日志打印性能
- 将一些不必要的代码通过宏开关disable掉,得到一个更简洁的代码,譬如RpcControllerImpl中很多时间(start_process_time等)的计算是没有必要的,目前并没有用上
RpcMessageStream::_pending_calls存取需要加锁,可以考虑改为无锁队列
这点我尝试过替换成boost::lockfree::queue
,感觉效果不明显,应该是得益于swapped_calls 的缓存作用
其他几点我争取一并修改,多谢
目标单io_service能支撑百万以上QPS
TODO
-
[ ] RpcServer 批量响应
-
[ ] 记录请求处理时间的时间戳,加上宏开关
-
[ ] buffer中使用的deque,是否用list更合理,要注意size()是O(n)复杂度
-
[ ] 默认的block size是否合理
以上每一个点都需要结合延迟分布,再决定合入哪个到主干
目前看现在是客户端发一个rpc后是立即断开了网络连接吧?如何保证客户端不断开呢?游戏场景是否适合使用?谢谢。
@cyshi ,感谢你的工作,这块我也想想优化点。 @LazyPlanet 客户端发一个RPC后不会立即断开连接,client端和server端都有一个keep_alive_time的参数,控制连接的保持时间。你可以调成-1,保持长连接。
好的,感谢老板。 @qinzuoyan