协议扩展

协议扩展

扩展说明

RPC 协议扩展,封装远程调用细节。

契约:

  • 当用户调用 refer() 所返回的 Invoker 对象的 invoke() 方法时,协议需相应执行同 URL 远端 export() 传入的 Invoker 对象的 invoke() 方法。
  • 其中,refer() 返回的 Invoker 由协议实现,协议通常需要在此 Invoker 中发送远程请求,export() 传入的 Invoker 由框架实现并传入,协议不需要关心。

注意

  • 协议不关心业务接口的透明代理,以 Invoker 为中心,由外层将 Invoker 转换为业务接口。
  • 协议不一定要是 TCP 网络通讯,比如通过共享文件,IPC 进程间通讯等。

扩展接口

  • org.apache.dubbo.rpc.Protocol
  • org.apache.dubbo.rpc.Exporter
  • org.apache.dubbo.rpc.Invoker
  1. public interface Protocol {
  2. /**
  3. * 暴露远程服务:<br>
  4. * 1. 协议在接收请求时,应记录请求来源方地址信息:RpcContext.getContext().setRemoteAddress();<br>
  5. * 2. export()必须是幂等的,也就是暴露同一个URL的Invoker两次,和暴露一次没有区别。<br>
  6. * 3. export()传入的Invoker由框架实现并传入,协议不需要关心。<br>
  7. *
  8. * @param <T> 服务的类型
  9. * @param invoker 服务的执行体
  10. * @return exporter 暴露服务的引用,用于取消暴露
  11. * @throws RpcException 当暴露服务出错时抛出,比如端口已占用
  12. */
  13. <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
  14. /**
  15. * 引用远程服务:<br>
  16. * 1. 当用户调用refer()所返回的Invoker对象的invoke()方法时,协议需相应执行同URL远端export()传入的Invoker对象的invoke()方法。<br>
  17. * 2. refer()返回的Invoker由协议实现,协议通常需要在此Invoker中发送远程请求。<br>
  18. * 3. 当url中有设置check=false时,连接失败不能抛出异常,需内部自动恢复。<br>
  19. *
  20. * @param <T> 服务的类型
  21. * @param type 服务的类型
  22. * @param url 远程服务的URL地址
  23. * @return invoker 服务的本地代理
  24. * @throws RpcException 当连接服务提供方失败时抛出
  25. */
  26. <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
  27. }

扩展配置

  1. <!-- 声明协议,如果没有配置id,将以name为id -->
  2. <dubbo:protocol id="xxx1" name="xxx" />
  3. <!-- 引用协议,如果没有配置protocol属性,将在ApplicationContext中自动扫描protocol配置 -->
  4. <dubbo:service protocol="xxx1" />
  5. <!-- 引用协议缺省值,当<dubbo:service>没有配置prototol属性时,使用此配置 -->
  6. <dubbo:provider protocol="xxx1" />

已知扩展

  • org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol
  • org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol
  • org.apache.dubbo.rpc.protocol.rmi.RmiProtocol
  • org.apache.dubbo.rpc.protocol.http.HttpProtocol
  • org.apache.dubbo.rpc.protocol.http.hessian.HessianProtocol
  • org.apache.dubbo.rpc.support.MockProtocol

扩展示例

Maven项目结构:

  1. src
  2. |-main
  3. |-java
  4. |-com
  5. |-xxx
  6. |-XxxProtocol.java (实现Protocol接口)
  7. |-XxxExporter.java (实现Exporter接口)
  8. |-XxxInvoker.java (实现Invoker接口)
  9. |-resources
  10. |-META-INF
  11. |-dubbo
  12. |-org.apache.dubbo.rpc.Protocol (纯文本文件,内容为:xxx=com.xxx.XxxProtocol)

XxxProtocol.java:

  1. package com.xxx;
  2. import org.apache.dubbo.rpc.Protocol;
  3. public class XxxProtocol implements Protocol {
  4. public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
  5. return new XxxExporter(invoker);
  6. }
  7. public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
  8. return new XxxInvoker(type, url);
  9. }
  10. }

XxxExporter.java:

  1. package com.xxx;
  2. import org.apache.dubbo.rpc.support.AbstractExporter;
  3. public class XxxExporter<T> extends AbstractExporter<T> {
  4. public XxxExporter(Invoker<T> invoker) throws RemotingException{
  5. super(invoker);
  6. // ...
  7. }
  8. public void unexport() {
  9. super.unexport();
  10. // ...
  11. }
  12. }

XxxInvoker.java:

  1. package com.xxx;
  2. import org.apache.dubbo.rpc.support.AbstractInvoker;
  3. public class XxxInvoker<T> extends AbstractInvoker<T> {
  4. public XxxInvoker(Class<T> type, URL url) throws RemotingException{
  5. super(type, url);
  6. }
  7. @Override
  8. protected Result doInvoke(Invocation invocation) throws Throwable {
  9. // ...
  10. }
  11. }

META-INF/dubbo/org.apache.dubbo.rpc.Protocol:

  1. xxx=com.xxx.XxxProtocol

最后修改 June 28, 2023: Update protocol.md (#2704) (b50d79ceea0)