一、Protocol 在 RPC 中的层次关系
二、Dubbo 中的协议
(1)dubbo://、(2)rmi://、(3)hessian://、(4)http://、(5)webserivice://、(6)thrift://、(7)memcached://、(8)redis://、(9)rest://、(10)jsonrpc://、(11)Why HTTP、(12)Why Not RESTful
三、Motan 中的协议
(1)motan://、(2)injvm://、(3)grpc://和yar://、(4)restful://、(5)motan2://
四、面向未来的协议
RPC :远程过程调用协议,熟悉的协议:HTTP 和 TCP,RPC 和 RESTFUL (也可被理解为一种协议)经常做对比,“协议”理解为:不同厂家不同用户之间的“约定”, RPC协议的含义也有多层。
dubbo,motan 仅作为RPC 框架,默认协议(dubbo 协议,motan 协议),如需对接异构系统,需替换其他。自研 RPC 改协议,为适配业务,协议层选择非常重要。
一、Protocol 在 RPC 中的层次关系
dubbo 和 motan RPC 框架(或叫服务治理框架)支持多种协议。RPC 框架结构分层,传输层,序列化层,动态代理层,协议层(所有层之上)
protocol 层:配置 refer(发现服务)、 exporter(暴露服务) 实现方式,
transport 层:定义传输方式
codec 层:传输过程中报文解析方式
serialize 层:对象转换字节,用于传输,proxy 层屏蔽这些细节。
protocol > transport > codec > serialize
motan 的 Protocol 接口可以佐证这一点:
RPC 框架支持多种协议,协议层次高,替换可能导致服务发现和注册、传输、序列化的方式,不同协议给不同场景带来更多选择,常用协议。
二、Dubbo 中的协议
(1)dubbo:// Dubbo 缺省协议:单一长连接、 NIO 异步通讯
场景:小数据量高并发服务调用,服务消费者机器数远大于服务提供者机器数。常规远程服务方法调用
不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。
(2)rmi:// 阻塞式短连接、JDK 标准序列化方式,RMI 协议采用 JDK 标准的java.rmi.*实现,
场景:与原生RMI服务互操作,常规远程服务方法调用
(3)hessian://
用于集成 Hessian 的服务,Hessian 底层Http 通讯, Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现。
Dubbo 的 Hessian 协议可以和原生 Hessian 服务互操作,即:
提供者用 Dubbo 的 Hessian 协议暴露服务,消费者直接用标准 Hessian 接口调用
或者提供方用标准 Hessian 暴露服务,消费方用 Dubbo 的 Hessian 协议调用。
也可做序列化工具。
场景:页面,文件传输,与原生hessian服务互操作
(4)http://
基于 HTTP 表单的远程调用协议,采用 Spring 的 HttpInvoker 实现
场景:同时给应用程序和浏览器 JS 使用的服务。
(5)webserivice://
基于 WebService 的远程调用协议,基于 Apache CXF 的frontend-simple和transports-http实现。
和原生 WebService 服务互操作,即:
提供者用 Dubbo 的 WebService 协议暴露服务,消费者直接用标准 WebService 接口调用,
或者提供方用标准 WebService 暴露服务,消费方用 Dubbo 的 WebService 协议调用
适用场景:系统集成,跨语言调用
(6)thrift://
dubbo 支持的 thrift 协议是对 thrift 原生协议的扩展,添加额外头信息,service name,magic number 等。
(7)memcached://
基于 memcached 实现的 RPC 协议
(8)redis://
基于 Redis 实现的 RPC 协议。
dubbo 支持的众多协议详见http://dubbo.io/books/dubbo-user-book/references/protocol/dubbo.html
dubbo的一个分支dangdangdotcom/dubbox扩展了 REST 协议
(9)rest://
JAX-RS 是标准的 Java REST API, Oracle 的 Jersey,RedHat 的 RestEasy,Apache 的 CXF 和 Wink,以及 restlet 等等。
适用场景:跨语言调用,非常成熟解决方案,没有vendor lock-in 问题。
JAX-RS 入门教程,要掌握各种 annotation 用法即可:
Oracle 官方的 tutorial:http://docs.oracle.com/javaee/7/tutorial/doc/jaxrs.htm
IBM developerWorks 中国站文章:http://www.ibm.com/developerworks/cn/java/j-lo-jaxrs/
ps:dubbo 基于 JAX-RS 2.0 ,注意一下资料或REST实现所涉及的版本。
千米网给 dubbo 贡献的扩展协议:https://github.com/dubbo/dubbo-rpc-jsonrpc
(10)jsonrpc://
(11)Why HTTP
适用场景:跨语言调用,nodejs、django、rails开发web端应用,后端Java
http、json合适作为跨语言标准,各种语言都有成熟的类库
虽然Dubbo的异步长连接协议效率很高,但是在脚本语言中,这点效率的损失并不重要。
(12)Why Not RESTful
REST 和 dubbo 原有 RPC 架构有区别:
REST需有资源 (Resources) 的定义,用 HTTP 协议的基本操作 GET、POST、PUT、DELETE
Dubbox 需重新定义接口属性,对原有的 Dubbo 接口迁移是较大负担。
场景:RESTful :互联网系统之间调用, RPC 系统内调用
所以使用了和 Dubbo 理念较为一致的 JsonRPC
JSON-RPC 2.0 规范和 JAX-RS 一样,也是一个规范,JAVA 对其的支持可参考jsonrpc4j
适用场景:跨语言调用
三、Motan 中的协议
(1)motan://
等同于 dubbo 协议之于 dubbo,内部用 netty 进行通信,默认hessian序列化器。
适用场景:常规远程调用
(2)injvm://
顾名思义,Provider 和 Consumer 位于同一个 jvm,motan 提供 injvm 协议。jvm内部调用,不经过本地网络,
场景:服务化拆分时,过渡方案使用,通过开关机制本地和远程调用之间切换,过渡后再去除本地实现的引用。
(3)grpc://和yar://
诞生缘起历史遗留问题(跨语言),moton微博开源,内部很多 PHP 应用
场景:局限的跨语言调用
(4)restful://
motan 在0.3.1(2017-07-11) 发布了 restful 协议(和 dubbo 的 rest 协议本质一样),dubbo 默认使用 jetty 作为 http server, motan 使用则是 netty 。主要实现的是 java 对 restful 指定的规范,即 javax.ws.rs 包下的类。
适用场景:跨语言调用
(5)motan2://
motan1.0.0(2017-10-31) 版本发布了 motan2 协议,用于对跨语言的支持,不同于 restful,jsonrpc 这样的通用协议,motan2 把请求的一些元数据作为单独的部分传输,更适合不同语言解析。
适用场景:跨语言调用
Motan is a cross-language remote procedure call(RPC) framework for rapid development of high performance distributed services.
Motan-gois golang implementation.
Motan-PHPis PHP client can interactive with Motan server directly or through Motan-go agent.
Motan-openrestyis a Lua(Luajit) implementation based onOpenresty
从 motan 的 changeLog 以及 github 首页的介绍来看,其致力于打造成一个跨语言的服务治理框架,这倒是比较亦可赛艇的事。
四、面向未来的协议
motan 已经支持 motan2://,计划支持 mcq://,kafka:// …支持更多的协议,以应对复杂的业务场景
参见:http://mp.weixin.qq.com/s/XZVCHZZzCX8wwgNKZtsmcA
http://cmsblogs.com/?p=3879