Dubbo3 協(xié)議拓展

2022-04-22 11:52 更新

擴展說明

RPC 協(xié)議擴展,封裝遠程調(diào)用細節(jié)。

契約:

  • 當用戶調(diào)用 refer() 所返回的 Invoker 對象的 invoke() 方法時,協(xié)議需相應執(zhí)行同 URL 遠端 export() 傳入的 Invoker 對象的 invoke() 方法。
  • 其中,refer() 返回的 Invoker 由協(xié)議實現(xiàn),協(xié)議通常需要在此 Invoker 中發(fā)送遠程請求,export() 傳入的 Invoker 由框架實現(xiàn)并傳入,協(xié)議不需要關心。

注意:

  • 協(xié)議不關心業(yè)務接口的透明代理,以 Invoker 為中心,由外層將 Invoker 轉(zhuǎn)換為業(yè)務接口。
  • 協(xié)議不一定要是 TCP 網(wǎng)絡通訊,比如通過共享文件,IPC 進程間通訊等。

擴展接口

  • org.apache.dubbo.rpc.Protocol
  • org.apache.dubbo.rpc.Exporter
  • org.apache.dubbo.rpc.Invoker
public interface Protocol {
    /**
     * 暴露遠程服務:<br>
     * 1. 協(xié)議在接收請求時,應記錄請求來源方地址信息:RpcContext.getContext().setRemoteAddress();<br>
     * 2. export()必須是冪等的,也就是暴露同一個URL的Invoker兩次,和暴露一次沒有區(qū)別。<br>
     * 3. export()傳入的Invoker由框架實現(xiàn)并傳入,協(xié)議不需要關心。<br>
     * 
     * @param <T> 服務的類型
     * @param invoker 服務的執(zhí)行體
     * @return exporter 暴露服務的引用,用于取消暴露
     * @throws RpcException 當暴露服務出錯時拋出,比如端口已占用
     */
    <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
 
    /**
     * 引用遠程服務:<br>
     * 1. 當用戶調(diào)用refer()所返回的Invoker對象的invoke()方法時,協(xié)議需相應執(zhí)行同URL遠端export()傳入的Invoker對象的invoke()方法。<br>
     * 2. refer()返回的Invoker由協(xié)議實現(xiàn),協(xié)議通常需要在此Invoker中發(fā)送遠程請求。<br>
     * 3. 當url中有設置check=false時,連接失敗不能拋出異常,需內(nèi)部自動恢復。<br>
     * 
     * @param <T> 服務的類型
     * @param type 服務的類型
     * @param url 遠程服務的URL地址
     * @return invoker 服務的本地代理
     * @throws RpcException 當連接服務提供方失敗時拋出
     */
    <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
 
}

擴展配置

<!-- 聲明協(xié)議,如果沒有配置id,將以name為id -->
<dubbo:protocol id="xxx1" name="xxx" />
<!-- 引用協(xié)議,如果沒有配置protocol屬性,將在ApplicationContext中自動掃描protocol配置 -->
<dubbo:service protocol="xxx1" />
<!-- 引用協(xié)議缺省值,當<dubbo:service>沒有配置prototol屬性時,使用此配置 -->
<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項目結構:

src
 |-main
    |-java
        |-com
            |-xxx
                |-XxxProtocol.java (實現(xiàn)Protocol接口)
                |-XxxExporter.java (實現(xiàn)Exporter接口)
                |-XxxInvoker.java (實現(xiàn)Invoker接口)
    |-resources
        |-META-INF
            |-dubbo
                |-org.apache.dubbo.rpc.Protocol (純文本文件,內(nèi)容為:xxx=com.xxx.XxxProtocol)

XxxProtocol.java:

package com.xxx;
 
import org.apache.dubbo.rpc.Protocol;
 
public class XxxProtocol implements Protocol {
    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
        return new XxxExporter(invoker);
    }
    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
        return new XxxInvoker(type, url);
    }
}

XxxExporter.java:

package com.xxx;
 
import org.apache.dubbo.rpc.support.AbstractExporter;
 
public class XxxExporter<T> extends AbstractExporter<T> {
    public XxxExporter(Invoker<T> invoker) throws RemotingException{
        super(invoker);
        // ...
    }
    public void unexport() {
        super.unexport();
        // ...
    }
}

XxxInvoker.java:

package com.xxx;
 
import org.apache.dubbo.rpc.support.AbstractInvoker;
 
public class XxxInvoker<T> extends AbstractInvoker<T> {
    public XxxInvoker(Class<T> type, URL url) throws RemotingException{
        super(type, url);
    }
    
    @Override
    protected Result doInvoke(Invocation invocation) throws Throwable {
        // ...
    }
}

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

xxx=com.xxx.XxxProtocol


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號