一个轻量化的分布式服务框架。典型的应用场景是,将同一个服务部署在多个Server上提供分布式的 request、response 消息通知。RSF 的设计吸收了 HSF 的设计精华,而 HSF 是阿里内部使用最广泛的一款 RPC框架。久经考验。当然这并不意味着 RSF 也同样具备 HSF 的超高稳定性,但是不可否认的是 RSF 在分布式 RPC 框架的设计中确实走了很多捷径。
RSF的源码地址:http://git.oschina.net/zycgit/rsf
RSF 功能盘点:http://my.oschina.net/u/1166271/blog/38637
本文的目的是测试 RSF 在高并发下其性能表现如何。测试 RSF 的机器是“阿里云,按量计费”中最高配置,因为财力有限阿里云 16核机器只能意淫的想一想。下面是配置详情:
Server节点为:青岛
数量:2(一台客户机、一台Server)
网络:100M带宽(网络流量走外网地址)
CPU:4核
内存:16G
价格:机器配置费 2.736元/时,公网流量0.72 元/GB
整个测试耗时 2 个小时,测试成本 26元。先看一下Server这两个小时的整体情况:
从上面统计信息可以看出,4核CPU其实并未全力以赴(这个稍后我会提到)。而网卡的入网和出网流量都基本上已经达到最大流量限制,换句话说:100M的网卡打满了。后面的实际测试数据中也可以看到网卡是最大的性能瓶颈。
address 绑定到:121..42.193.51 这个外网IP上,意为所有流量走公网IP。
port 端口号绑定到 8000 上。
server 所属虚拟机房为 local(该配置在测试中并未产生任何作用,虚拟机房策略是当有多server,多client下负责控制跨网络调用的策略配置)
下面这个参数是Server的关键配置:
<queue maxSize="1000000" minPoolSize="1" maxPoolSize="4" keepAliveTime="300">
在解释这个配置的时候先解释一下 RSF Server端内部的一个保护机制。
RSF在设计的时候留了很多可配置的参数,这些参数用来设定一个阀值用以保护应用程序稳定性。如果一个框架自己没有任何保护措施就开始“裸奔”很可能框架在某一个业务压力下把自己跑死而,开发者还在苦苦追寻原因。queue其中就是一个保护机制。
queue是用来管理 request 积压的一个队列。这个队列可以用来保证Server在高并发下不会自身产生OOM,同时合理的调整队列容量也可以调整服务策略服务模式。它的实现是由ThreadPoolExecutor、LinkedBlockingQueue 两个类提供。
在上面配置中,处理队列的线程数最小为 1个,最大为4个。 取这个值的原因是业务方法本身很简单不会消耗过多的CPU周期,设定最大4已经戳戳有于,前面Server整体情况上CPU的使用率也反映了这个事实。keepAliveTime是新线程产生时的等待时间。我们不去过多关注它。
<network workerThread="8" listenThread="1" />
表示的是 Nett 方面将会采用 8条线程来处理网络IO,1条线程处理连接请求。
接受测试的远程Server地址列表为:rsf://121.42.193.51:8000/unit <-- unit 应该改为 local,但这里无关紧要。因为虚拟机房策略并未配置,所以只是保证有值就可以了。
<testConfig clientCount="2" threadCount="100"/>
表示的意思是,客户端将会启动 2 个全新的RSF实例程序来模拟压测,每个客户端下同时开启 100 个无阻塞异步调用。无阻塞异步调用指的是:client 异步的发起调用请求,当调用完成时立刻发起下一个异步调用,中间不间断。
在这个配置下,client最大可以产生 2 * 100 =2000 个并发 RSF 请求。
connectTimeout="500" 这个参数是指,RSF 允许client 到 server 之间建立连接的最大期限。当超过这个期限。连接的远端server地址将会被置为失效。
maximumRequest="100000" ,client 允许最大 10W 条并发 request。超过这个值 client 会进行自我保护,自动进行回绝 client 的调用请求,在目前这个配置里是根本达不到这个量的。
以下测试数据是 Server 端配置保持不变,适当调整 client 端的 clientCount、threadCount 两个配置值。
|
请求量 (成功数/总数) |
客户端报告:RT 单位:毫秒 |
服务端报告:QPS 单位:秒 |
服务端:CPU max:400% |
服务端内存:RAM 使用率% |
clientCount=2,threadCount=100 | 6450000/6450189 6455000/6455200 6460000/6460197 6465000/6465119 6470000/6470119 |
5 4 2 4 3 |
3.4W+ | 188.1% | 1.7% |
clientCount=2,threadCount=1000 | 9745000/9746843 9750000/9751699 9755000/9756664 9760000/9761740 9765000/9766673 |
38 39 41 37 47 |
4.6W+ | 198.5% | 1.9% |
clientCount=2,threadCount=4000 | 15955000/15968371 15960000/15973724 15965000/15978511 15970000/15981194 15975000/15987266 |
249 409 298 263 181 |
4.6W+ |
239.3% | 6.7% |
clientCount=2,threadCount=10000 |
18655000/18674284 18660000/18679269 18665000/18684844 18670000/18689318 18675000/18694204 |
315 360 293 364 430 |
4.7W+ | 203.5% | 9.3% |
clientCount=10,threadCount=100 |
11840000/11840417 11845000/11845387 11850000/11850584 11855000/11855311 11860000/11860398 |
32 6 14 5 21 |
3.3W+ | 203.2% | 1.7% |
clientCount=10,threadCount=1000 |
14875000/14880505 14880000/14887261 14885000/14893780 14890000/14898746 14895000/14903842 |
24 126 242 151 139 |
4.3W+ | 245.1% | 4.5% |
clientCount=10,threadCount=4000 |
8585000/8623539 8590000/8628938 8595000/8634636 8600000/8638767 8605000/8643556 |
753 767 721 776 785 |
4.1W+ | 239.0% | 9.4% |
clientCount=10,threadCount=10000 |
9915000/10055117 9920000/10063842 9925000/10070482 9935000/10084538 9940000/10089888 |
1816 2025 2053 2227 2269 |
4.1W+ | 233.7% | 9.5% |
clientCount=20,threadCount=100 |
10730000/10730905 10735000/10735550 10740000/10740714 10745000/10746152 10750000/10751195 |
7 11 21 24 46 |
3.3W+ | 211.5% | 1.1% |
clientCount=20,threadCount=1000 |
5800000/5818674 5805000/5822908 5810000/5828438 5815000/5830541 5820000/5838423 |
409 379 342 337 374 |
4W+ | 259.3% | 8.8% |
clientCount=20,threadCount=4000 |
1095000/1308640 1100000/1309727 1105000/1315539 1110000/1322031 1120000/1311961 |
1645 1590 1619 1900 1970 |
3.3W+ | 206% | 9.5% |
clientCount=20,threadCount=10000 |
55000/141942 60000/159892 65000/173944 70000/187413 75000/202027 |
3975 4196 4450 4601 4859 |
ERROR:timeout | 70% |
17.3% |
在测试例子中,100M网卡已经跑满,出网流量约 100Mbps,折算成字节约为12.5MB,根据上面表显示测试中网卡稳定在70%的工作状态,吞吐数据约为8MB。平均Server的 QPS在4W左右,我们粗略估计一下RSF数据包大小为:8MB / 4W = 209Byte。
209Byte这个很接近Demo测试例子的网络单向数据包的大小。因为测试环境有限,我无法在千兆网卡上进行测试。按照千兆网卡传入传出 50MB速率来算。 RSF 单个节点可以到 25W 的 QPS。
RSF博客:http://my.oschina.net/u/1166271/blog?catalog=574765
RSF源码:http://git.oschina.net/zycgit/rsf
测试程序Server端:http://www.hasor.net/attachments/launcher-rsf-server-8000.zip
测试程序Client端:http://www.hasor.net/attachments/launcher-rsf-client.zip
如果你对 RSF 感兴趣可以加入:193943114 QQ群,欢迎讨论。更欢迎各种拍砖提意见。