dubbo vs mac-rpc 性能评测之异步调用

前言

笔者在此前发表的《dubbo vs mac-rpc 之性能评测 之 同步调用》一文中将dubbo和mac-rpc在同步调用方面的性能作了简单的对比和分析。原本不打算对异步调用这一块进行评测,由于双方在异步方法调用上差距有点大,并不太对称。但前面有不少同窗和我讨论关于mac-rpc的线程模型,以及底层通信的实现问题,笔者思来想去仍是写一写比较好。欢迎你们继续和我讨论。session

mac-rpc是我新近发布的做品,了解详情请访问:http://www.boarsoft.com多线程

Dubbo的异步调用的实现

关于异步调用,Dubbo官方文档上这样写到“基于 NIO 的非阻塞实现并行调用,客户端不须要启动多线程便可完成并行调用多个远程服务,相对多线程开销较小。”事实真的是这样吗?异步

笔者给被测试方法的dubbo:method标签的如下属性:async

async="true" sent="false" return="true" timeout="6000"性能

为了观察服务提供者和服务消费者双方的资源消耗状况,咱们须要将dubbo的线程池设置为cached,而后用300个线程并行的发起调用,每线程执行5000次异步调用,服务方法模拟延时10ms,结果以下:测试

服务消费者一方大数据

服务提供者一方优化

对,没有看错,实际上服务消费者一方是额外启动了一个线程来发起异步处理。最终的处理时间会比同步方法调用要慢一些,CPU使用率也明显增长。服务提供者一方则不受影响。spa

因为Dubbo不支持在一个线程内发起同时发起多个异步调用,这意味着是在前一个异步调用未返回前,不容许再发起下一个。所以,很难象测试同步方法调用同样经过循环来发起压力测试。.net

mac-rpc的异步调用的实现

一样,为了能看出mac-rpc在异步调用时线程的使用状况,笔者将mac-rpc所用线程池大小设置为0~600,队列设置为SynchronousQueue,也用300个线程并行的发起调用,每线程执行5000次异步调用,服务方法模拟延时10ms,结果以下:

服务消费者一方

服务提供者一方

与dubbo不一样,mac-rpc在异步调用时,服务消费者一方并不额外去启线程来执行。那么为何服务消费者一方的线程数是400而不是300也不是600呢?这是由于mac-rpc在收RPC调用的返回时,启动了额外的线程去处理。这个设计使得mac-rpc在大量并行的执行低延时、低数据量的同步调用时更慢,但在处理高延时、大数据量的场景则更快。mac-rpc的下一版将考虑优化此处。

性能对比测试

测试方法

为了进行对比测试,并排除没必要要的因素,咱们让服务双方均使用600大小的固定线程池,配合600大小的LinkedBlockingQueue队列,并让服务方法模拟100ms的延时,且只返回10字符,再使用300线程并行地发起调用,每线程调用2000次,并将得到的Future对象保留起来,在程序的最后一并get,而后观察总的耗时和资源消耗状况。

测试结果

当使用固定600大小的线程池时,Dubbo的服务提供者一方出现Thread pool is EXHAUSTED警告,服务消费者一方出现 Client session timed out, have not heard from server in 37125ms 警告。意味着如何服务消费者一方迟迟不get结果,会形成服务提供者一方线程一直被占用直到超时。这应该算是dubbo的一个严重的设计缺陷。

当使用cached线程池时,Dubbo彻底没法工做,服务提供者状态以下:

服务消费者状态以下:

在超时时间同为6秒的状况下,不管使用何种线程池,mac-rpc都能成功完成,使用固定600大小的线程池时,成绩最好,平均耗时为104206ms,比同步执行时快了一倍。

服务提供者状态以下:

注意:能够看出当服务消费方的RPC请求发送完成,服务提供方在一段时间后完成了全部请求,CPU降到0%,而服务消费方还在获取并处理服务方返回的响应。

服务消费者状态以下:

测试结论

mac-rpc在异步方法调用上完胜。不管从性能、抗压能力,仍是稳定性上都更胜一筹。此外,除了基本的异步方法调用外,mac-rpc还支持异步通知,异步回调等多种异步形式,值得一试。

相关文章
相关标签/搜索