微博轻量级RPC框架Motan正式开源:支撑千亿调用

时间:2017-07-09 13:34

  新浪科技讯 5月10日消息,微博方面宣布,支撑微博千亿调用的轻量级 RPC 框架 Motan 正式开源了,项目地址为https://github.com/weibocom/motan。微博技术团队希望未来能有更多优秀的开源人入驻,并进一步完善优化。

微博轻量级RPC框架Motan正式开源

微博轻量级RPC框架Motan正式开源

  Motan 是微博技术团队研发的基于 Java 的轻量级 RPC 框架,已在微博内部大规模应用多年,每天稳定支撑微博上亿次的内部调用。Motan 基于微博的高并发和高负载场景优化,成为一套简单、易用、高可用的 RPC 服务框架。

  Motan 功能特点:简单、易用、高可用

  无侵入集成、简单易用,通过 Spring 配置方式,无需额外代码即可集成分布式调用能力。

  集成服务发现和服务治理能力,灵活支持多种配置管理组件,如 Consul、ZooKeeper 等。

  支持自定义动态负载均衡、跨机房流量调整等高级服务调度能力。

  基于高并发、高负载场景优化,具备 Failover、Failfast 能力,保障 RPC 服务高可用。

  业界典型 RPC 框架对比

  目前,业界 RPC 框架大致分为两类,一种是偏重服务治理,另一种侧重跨语言调用。

  服务治理型的 RPC 框架典型的是 Dubbo 和 DubboX。Dubbo 是阿里开源的分布式服务框架,实现高性能的 RPC 调用同时提供了丰富的管理功能,是一款应用广泛的优秀的 RPC 框架,但现在较少维护更新。DubboX 是由当当在基于 Dubbo 框架扩展的一个 RPC 框架,支持 REST 风格的远程调用、Kryo/FST 序列化,增加了一些新的 feature。

  这类 RPC 框架的特点是功能丰富,提供高性能的远程调用、服务发现及服务治理能力,适用于大型服务的服务解耦及服务治理,对于特定语言(Java)的项目可以实现透明化接入。缺点是语言耦合度较高,跨语言支持难度较大。

  跨语言调用型的 RPC 框架有 Thrift、gRPC、Hessian、Hprose 等。这类 RPC 框架侧重于服务的跨语言调用,能够支持大部分的语言进行语言无关的调用,非常适合多语言调用场景。但这类框架没有服务发现相关机制,实际使用时需要代理层进行请求转发和负载均衡策略控制。

  微博的 Motan RPC 倾向于服务治理型,跨语言方面正在尝试与 PHP 的调用集成。与 Dubbo 系列相比在功能上或许不是那么全,扩展实现也没有那么多,但 Motan 更注重简单、易用以及在高并发高可用场景的使用。

  Motan 是基于 Java 的高性能轻量级 RPC 框架,其具备实用的服务治理功能和 RPC 协议扩展能力。服务发现灵活支持多种配置管理组件,基于高并发高负载场景的高可用策略优化,良好的 SPI(Service Provider Interface)扩展,详细的调用统计,灵活支持多种 RPC 传输协议,在使用上,无缝支持Spring 配置方式,通过简单灵活的配置即可快速接入使用。

  Motan 的架构及模块设计

  架构设计,分为服务提供方(RPC Server)、服务调用方(RPC Client)、注册中心(Registry)三个角色,Server 向 Registry 注册声明所提供的服务;Client 向 Registry 订阅指定服务,与 Registry 返回的服务列表的 Server 建立连接,进行 RPC 服务调用。Client 通过 Registry 感知 Server 的状态变更。三者的交互关系如下图:

微博轻量级RPC框架Motan正式开源:支撑千亿调用

  服务模块化设计方便灵活扩展,Motan 主要包括 register、transport、serialize、protocol、cluster 等,各个模块都是支持通过SPI 进行扩展,各个模块的交互图如下:

微博轻量级RPC框架Motan正式开源:支撑千亿调用

  register 模块

  用来和注册中心进行交互,包括注册服务、订阅服务、服务变更通知、服务心跳发送等功能;Server 端会在系统初始化时通过 register 模块注册服务,Client 端在系统初始化时会通过 register 模块订阅到具体提供服务的 Server 列表,当 Server 列表发生变更时也由 register 模块通知 Client。

  protocol 模块

  用来进行 RPC 服务的描述和 RPC 服务的配置管理,这一层还可以添加不同功能的 filter 用来完成统计、并发限制等功能。

  serialize 模块将 RPC 请求中的参数、结果等对象进行序列化与反序列化,即进行对象与字节流的互相转换;默认使用对 Java 更友好的 hessian2 进行序列化。

  transport 模块用来进行远程通信,默认使用 Netty NIO 的 TCP 长链接方式。

  cluster 模块