使用rust开发了一款rpc通信组件,当前支持socket, websocket(udp还在协议设计中)通信,默认编码支持binnary和json两种。为最大化提高通信效率,最大化的不使用锁机制,通信的业务都在单个虚拟线程中运行,提高组件整体QPS。

为进行性能测试,选择了redis和axum对rpc进行比较。

测试场景:  分别开启N个客户端,向服务端发送消息,每个客户端发送M个消息后就停止,服务端接受到消息马上返回消息,  rpc还测试binnary和json编码,最终记录总耗时,并按照耗时进行倒排序

测试1: N=6, M=10000

栏目 编码方式 耗时(ms) ops/s 排名
rpc-websocket-server binnary 2531 23706 3
rpc-websocket-server json 2374 25273 2
rpc-socket-server binnary 2552 23510 4
rpc-socket-server json 2577 23282 5
auxm-server json 2135 28103 1

测试结果竟然是websocket的性能比socket性能强点。

测试2: N=50, M=10000

栏目 编码方式 耗时(ms) ops/s 排名
rpc-websocket-server binnary 14139 35363 1
rpc-websocket-server json 15070 33178 4
rpc-socket-server binnary 16825 29717 5
rpc-socket-server json 14452 34597 3
auxm-server json 14306 34950 2

测试结果竟然rpc websocket server(binnary)最强,rpc socket server (binnary)最弱,太反常了。

测试3: N=200, M=10000

栏目 编码方式 耗时(ms) ops/s 排名
rpc-websocket-server binnary 62419 32041 2
rpc-websocket-server json 69215 28895 4
rpc-socket-server binnary 67448 29652 3
rpc-socket-server json 53226 37575 1
auxm-server json 72300 27662 5

测试结果rpc-socket-server(json)性能最好。

初步判断是binnary的codec编码导致的性能低下,就分别对binnary-codec和json-codec进行性能测试。测试结果还真是json-codec比binnary-codec编码性能强。binnary编码主要使用的是bincode, json编码主要使用的是serde-json,对bincode和serde-json的性能测试,明显是bincode性能更强。分析其它编码代码,发现是使用ByteMut编码的缘故,改用Vec后,binnary-codec的性能就比json-codec强了。

但是rpc整体性能还是json比binnary强,未改变上面测试结果。

对比rpc-socket和rpc-websocket,那么共用组件router, channel, service都不是影响性能的原因,那么只能是connection组件导致的性能差异。那对比rpc-socket的binnay和json差异,发现是发送数据存在差异。

差异点:

stream.write_u32(bytes.len() as u32).await?;
stream.write_all(&bytes[..]).await?;

 上需代码还是认为聪明写法,是节省内存的写法。改成

let result = bytes_wrap(bytes);
stream.write_all(&result[..]).await?;

binnay的性能就比json性能强了。重新测试结果如下:

测试4: N=6, M=10000

栏目 编码方式 耗时(ms) ops/s 排名
rpc-websocket-server binnary 1920 31250 2
rpc-websocket-server json 2544 23584 5
rpc-socket-server binnary 1793 33463 1
rpc-socket-server json 2297 26121 4
auxm-server json 2081 28832 3

这次测试结果rpc-socket>rpc-websocket, binnary>json。是理想结果。

测试5: N=50, M=10000

栏目 编码方式 耗时(ms) ops/s 排名
rpc-websocket-server binnary 14005 35701 3
rpc-websocket-server json 15078 33160 5
rpc-socket-server binnary 11960 41806 1
rpc-socket-server json 12767 39163 2
auxm-server json 14425 34662 4

测试结果还是很理想的。

测试6: N=200, M=10000

栏目 编码方式 耗时(ms) ops/s 排名
rpc-websocket-server binnary 63559 31466 3
rpc-websocket-server json 66922 29885 4
rpc-socket-server binnary 51572 38780 1
rpc-socket-server json 55555 36000 2
auxm-server json 67685 29548 5

最后补上对redis的性能测试场景: N个客户端,每个客户端对独自的Key进行set操作M次。

1,N=6, M=10000.  总耗时: 2123ms。 吞吐量:28261 ops/s

2,  N=50,  M=10000。总耗时: 17087ms。吞吐量: 29262 ops/s

3,  N=200, M=10000。总耗时: 63688ms。 吞吐量: 31403 ops/s

结果总结:

  1, 虚拟线程是个好东西,但是用不好,也能导致性能降低,毕竟线程切换还是有成本的,在高并发的情况下,需要评估线程的切换成本。

  2,bytes是tokio的重要组件,用不好也能影响性能。

 测试代码: https://gitee.com/ldh123/rpc-rs/blob/master/rpc-test/src/main.rs (在 rpc-test 目录下,运行 cargo run --release 即可)

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐