Dubbo 是阿里巴巴开源的一款 Java 高性能分布式微服务框架它以远程方法调用功能为基础, 将系统中的服务以远程方法调用 (RPC) 的形式暴露并管理, 提供配套的面向服务 (SOA) 的治理手段, 从而形成完整的分布式微服务框架体系
Dubbo 项目大概始于 2009 年, 但不知出于什么原因, 官方于 2012 年停止了维护颇有戏剧性的是, 墙内开花墙外香, Dubbo 受到国内很多第三方厂商的欢迎, 并在其项目中广泛使用因此, 官方于 2017 年重启 Dubbo 项目的维护, 目前最新版本是 2.6.1
mac-rpc 是一款新的基于 Java AIO 的开源 RPC 框架, 小巧精悍强大的异步能力是它最大的亮点 Dubbo 在异步支持上比较弱, 而 mac-rpc 天生就是异步的, 使得 mac-rpc 在异步方法调用的性能方面颇具优势(了解其实现原理请访问官方网站 www.boarsoft.com)
作为 RPC 框架, 大多数的应用场景都是同步方法调用而 mac-rpc 在同步方法调用方面的性能也非常不俗, 可以与 dubbo 一较高下因此, 笔者仅对两者的同步方法调用的性能进行对比测试
异步调用的评测见: dubbo vs mac-rpc 性能评测之异步调用
一测试环境
硬件: 笔记本电脑一台 CPU Intel i5-6300HQ @2.30GHz,8G 内存
软件: JDK1.7dubbo 2.6.1mac-rpc 1.0.1
注: 笔记本电脑在 CPU 温度过高时会自动降频, 导致测试结果的波动笔者不得不采用轮流执行, 多次测试取平均值的方式进行所得数据可能并不很准确, 但能从大体上看出两者的性能水平
二测试场景
Dubbo 可调参数众多, 其调优过程本身就已非常复杂, 费时费力因此, 本次测试将尽可能采用其默认参数经过多轮测试, Dubbo 在采用固定大小线程池时性能表现最佳, 同时为了避免 dubbo 抛出线程池耗尽的异常, 我们将服务方的线程池大小固定为 600, 在消费方使用 300 个线程并行发起调用
另外, dubbo 在传输大对象时表现不佳, 过大的数据量将导致 dubbo 的性能严重下降因此我们只让测试程序拼装并返回 10~1 万个字符因为实际应用过程中, 绝大多数 RPC 方法调用, 一次调用通过网络往返的数据量大致都位于这个区间内
注: 作为 RPC 框架, 在方法调用时只传输小对象是可以的但作为微服务框架, 系统内服务的形式多种多样, 如果限制所有服务都不能返回大对象, 似乎有一些差强人意在这一点上 mac-rpc 则更具优势
三测试要点
在生产实践中, 我们可以看到这样一种现象, 单笔测试时, 只需要几个毫秒, 甚至零毫秒的服务, 在压力测试或生产环境下, 延迟到几十数百毫秒, 有的甚至数秒, 直到超过规定的响应时长导致这一现象的原因有很多, 包括: 磁盘 IO 网络 IO 线程切换锁等待 CPU 负载过高, 内存不足, 频繁 GC 第三方系统时延等等经常会发现系统吞吐量低, 响应缓慢时, 各项物理资源消耗却很少
为了更真实的模拟生产的运行环境, 我们在方法中通过 Thread.sleep 来模拟以上各种原因造成的时延观察 RPC 方法调用在受这些因素影响下的实际性能表现此外, 在大压力的情况下, 输入输出数据量的大小对性能也有显著影响, 我们还需要测试不同数据量下的性能表现
还有一个重要一因素就是微服务的粒度, 服务粒度越小, 灵活度越高, 但在系统中相互调用的开销就越大, 管理起来也更加复杂适当的粒度对提高系统的吞吐量非常重要
三测试方法
服务消费者使用 300 线程并行的发起同步 RPC 方法调用, 服务提供者采用固定 600 个线程的线程池模拟在 0ms10ms20ms50ms100ms 时延下, 数据量在 101000500010000 个字符时的表现
同时为了避免磁盘 IO 和网络 IO 对性能的影响, 测试程序不打日志, 不写磁盘服务消费者和服务提供者都在同一台电脑上
注: 由于长时延和大数据量时, 测试耗时急剧增加, 为了节省时间, 随着时延加长数据量的加大, 每线程的调用次数相应的被减少到 5000 次或 2000 次
四测试结果
注: 每线程 = 每线程发起的调用次数
五资源消耗
资源上看, Dubbo 的线程池使用 SynchronousQueue 队列, 这意味着服务消费者通过 300 个线程发起调用时, 服务提供者对应的也会调起 300 个线程来执行而 mac-rpc 的线程池默认使用 LinkedBlockingQueue, 使得服务消费者的线程数对服务提供者无影响同时, mac-rpc 默认采用 CallerRunsPolicy 作为线程不足的处理策略, 而 dubbo 则采用 AbortPolicy, 除非采用 cached 线程池, 否则当线程不足时, dubbo 将抛出 RejectedExecutionException 无论从配置方便程度, 还是灵活度, mac-rpc 都更优
在使用固定 600 个线程的线程池的情况下, mac-rpc 在 CPU 使用 (25%) 上略高于 dubbo(20%), 在内存使用上则显著优于 dubbo(50~200M), 稳定在 50M 左右
dubbo 服务提供方资源消耗:
mac-rpc 服务提供方资源消耗:
六测试结论
当时 RPC 方法的时延较小, 且数据量也较小, 在此例中约为小于 15ms, 字节数小于大约 2000~3000 个时, Dubbo 较 mac-rpc 有明显优势之后随着时延和数据量的增加, mac-rpc 的优势逐渐显现, 响应时间和 TPS 都相对平稳, 而 dubbo 的性能则显著下降, 差距较大继续增大压力, dubbo 的表现会更糟糕, mac-rpc 则相对更好一些
综合来看, mac-rpc 在同步方法调用方面, 相较 dubbo, 有着更优秀的性能表现, 稳定性也更好, 能够更好的承受压力目前 mac-rpc 已具备了简单的微服务治理能力, 但由于作者精力有限, 发展时间较短, 在功能性和治理手段方面还有待完善和加强
来源: https://juejin.im/entry/5ab31bf7518825557f00d2d6