1. 程式人生 > >10. Dubbo原理解析-Listener & filter

10. Dubbo原理解析-Listener & filter

Listener

ExporterListener:

dubbo在服務暴露(exporter)以及銷燬暴露(unexporter)服務的過程中提供了回撥視窗,供使用者做業務處理。ProtocolListenerWrapper在暴露過程中構建了監聽器鏈

public class ProtocolListenerWrapper implements Protocol {

   public <T> Exporter<T> export(Invoker<T>invoker)throws RpcException {

    ……. //註冊中心程式碼

     return

newListenerExporterWrapper<T>(protocol.export(invoker),                Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(ExporterListener.class).getActivateExtension(invoker.getUrl(),Constants.EXPORTER_LISTENER_KEY)));

}

}

1.      根據Dubbo的SPI擴充套件機制獲取所有實現了ExporterListener的監聽器listeners

2.      Protocol.export(invoker)暴露服務返回結果exporter物件

3.      ListenerExporterWrapper裝飾exporter, 在構造器中遍歷listeners構建export的監聽鏈

4.      ListenerExporterWrapper實現Exproter<T>介面,在unexport方法實現中構建unexport的監聽鏈

InvokerListener:

dubbo在服務引用(refer)以及銷燬引用(destroy)服務的過程中提供了回撥視窗,供使用者做業務處理。ProtocolListenerWrapper在暴露過程中構建了監聽器鏈

public <T> Invoker<T> refer(Class<T> type,URL url)throws RpcException {

returnnew ListenerInvokerWrapper<T>(protocol.refer(type, url),               Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(InvokerListener.class).getActivateExtension(url,Constants.INVOKER_LISTENER_KEY)));

}

1.      根據Dubbo的SPI擴充套件機制獲取所有實現了InvokerListener的監聽器listeners

2.      Protocol.refer(type, url)暴露服務返回結果invoker物件

  3. ListenerInvokerWrapper裝飾invoker, 在構造器中遍歷listeners構建referer的監聽鏈3.      ListenerInvokerWrapper裝飾invoker, 在構造器中遍歷listeners構建referer的監聽鏈

4.      ListenerInvokerWrapper實現Invoker<T>介面,在destory方法實現中構建destory的監聽鏈

Dubbo的開源版本中沒有監聽的實現,但是開放了口子,業務方如有需要可以利用這個功能實現特定的業務

Filter

Filter:是一種遞迴的鏈式呼叫,用來在遠端呼叫真正執行的前後加入一些邏輯,跟aop的攔截器servlet中filter概念一樣的

Filter介面定義

@SPI

public interface Filter {

   Result invoke(Invoker<?> invoker,Invocation invocation) throws RpcException;

}

ProtocolFilterWrapper:在服務的暴露與引用的過程中根據KEY是PROVIDER還是CONSUMER來構建服務提供者與消費者的呼叫過濾器鏈

public <T> Exporter<T> export(Invoker<T>invoker)throws RpcException {

return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));

}

public <T> Invoker<T> refer(Class<T> type,URL url)throws RpcException {

     return buildInvokerChain(protocol.refer(type, url),Constants.REFERENCE_FILTER_KEY, Constants.CONSUMER);

}

Filter的實現類需要打上@Activate註解, @Activate的group屬性是個string陣列,我們可以通過這個屬性來指定這個filter是在consumer, provider還是兩者情況下啟用,所謂啟用就是能夠被獲取,組成filter鏈

List<Filter> filters =ExtensionLoader.getExtensionLoader(Filter.class).getAct ivateExtension(invoker.getUrl(),key, group);

Key就是SERVICE_FILTER_KEY還是REFERENCE_FILTER_KEY

Group就是consumer或者provider

構建filter鏈,當我們獲取啟用的filter集合後就通過buildInvokerChain方法來構建

for (int i = filters.size() - 1; i >= 0; i --) {

      final Filter filter = filters.get(i);

      final Invoker<T> next = last;

      last = new Invoker<T>() {

            public Result invoke(Invocation invocation)throws RpcException {

                 return filter.invoke(next, invocation);

            }

           。。。。。。。 //其他方法

       };

 }

以上程式碼展示了構建filter鏈的過程

Dubbo內容提供了大量內部實現,用來實現呼叫過程額外功能, 如向監控中心傳送呼叫資料, Tps限流等等, 每個filer專注一塊功能。使用者同樣可以通過Dubbo的SPI擴充套件機制現在自己的功能