<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                provider端當`scope`不為`remote`時,都需要將服務發布到本地,發布到本地時使用的時injvm協議,是指服務器發布方和引用方的程序在同一個jvm中執行。 而consumer端中,從2.2.0開始,每個服務默認都會在本地暴露。在引用服務的時候,默認優先引用本地服務。如果希望引用遠程服務可以使用一下配置強制引用遠程服務。 ``` <dubbo:reference ... scope="remote" /> ``` ## 流程 injvm協議的過程是dubbo中最簡單的協議,但除了沒有注冊中心外,還是可以對其基本流程進行全面的了解。 ![injvm流程](http://www.uxiaowo.com/dubbo/Injvm.png) ## 1.發布到injvm協議 發布到invjm協議時,會先修改url的協議,host和port ``` URL local = URL.valueOf(url.toFullString()) .setProtocol(Constants.LOCAL_PROTOCOL) .setHost(LOCALHOST) .setPort(0); ``` 然后,ExtensionLoader動態獲取Protocol接口時,使用的是InjvmProtocol,會被包裝為 ``` |- ProtocolFilterWrapper |- ProtocolListenerWrapper |- InjvmProtocol ``` ProtocolFilterWrapper:主要用來生成調用鏈,內部的buildInvokerChain方法會查找Filter的實現類,查找group為provider的,并根據order排序,將這些Filter連接成一個調用鏈 InvokerChain,最終調用已經生成的Invoker ``` EchoFilter -> ClassloaderFilter -> GenericFilter -> ContextFilter -> TraceFilter -> TimeoutFilter -> MonitorFilter -> ExceptionFilter -> AbstractProxyInvoker類 ``` ProtocolListenerWrapper:主要用來添加監聽事件。首先調用InjvmProtocol的export,直接返回InjvmExporter;之后查找ExporterListener的實現類,最后將這兩者封裝為ListenerExporterWrapper并返回。 InjvmProtocol中定義了一個exporterMap,內部保存了服務名與Exporter的對應關系 到此為止,就已經發布到本地了。 ## 2. 引用 如果未強制指定遠程服務,會首先從本地查找服務,查找的入口是Spring的context的getBean方法獲取實例,其會通過兩個步驟獲取指定接口的實例:創建Invoker和獲取proxy代理對象。 ``` Invoker<DemoService> consuerInvoker = protocol.refer(DemoService.class, url); DemoService service = proxyFactory.getProxy(consuerInvoker); ``` 在引用服務流程中,我們已經分析了獲取Proxy對象的過程,每個協議獲取Invoker的方式不同,對于injvm協議來說,protocol被包裝為: ``` |- ProtocolFilterWrapper |- ProtocolListenerWrapper |- InjvmProtocol ``` ProtocolFilterWrapper和ProtocolListenerWrapper的功能還是構建Filter鏈和添加監聽事件,不同的是,對ProtocolFilterWrapper來說,consumer使用的refer方法,引用`group = Constants.CONSUMER`,而provider端使用的是export,使用了`group = Constants.PROVIDER`,這些都是在實現類的注解中進行配置。 對ProtocolListenerWrapper來說,provider使用的`exporter.listener`,而consumer使用的`invoker.listener` InjvmProtocol的refer中會創建一個InjvmInvoker并返回 ``` public <T> Invoker<T> refer(Class<T> serviceType, URL url) throws RpcException { return new InjvmInvoker<T>(serviceType, url, url.getServiceKey(), exporterMap); } ``` InjvmInvoker內部記錄了Class類型,url,服務名和exporterMap(保存了服務名與exporter對象的映射) ``` public Result doInvoke(Invocation invocation) throws Throwable { Exporter<?> exporter = InjvmProtocol.getExporter(exporterMap, getUrl()); if (exporter == null) { throw new RpcException("Service [" + key + "] not found."); } RpcContext.getContext().setRemoteAddress(NetUtils.LOCALHOST, 0); return exporter.getInvoker().invoke(invocation); } ``` ## 測試程序 了解了injvm協議的發布和引用過程后,我們可以對這個過程進行測試,在測試中,我們加入一對Listener和一對Filter。 PExporterListener實現了ExporterListener,在provider發布服務時使用 ``` public class PExporterListener implements ExporterListener { public void exported(Exporter<?> exporter) throws RpcException { System.out.println("[PExporterListener][exported]:" + exporter.getInvoker().getUrl()); } public void unexported(Exporter<?> exporter) { System.out.println("[PExporterListener][unexported]" + exporter.getInvoker().getUrl()); } } ``` CExporterListener實現了InvokerListener,在consumer調用時使用 ``` public class CExporterListener implements InvokerListener { public void referred(Invoker<?> invoker) throws RpcException { System.out.println("[CExporterListener][referred]:" + invoker.getUrl()); } public void destroyed(Invoker<?> invoker) { System.out.println("[CExporterListener][destroyed]:" + invoker.getUrl()); } } ``` PFilter實現了Filter接口,注解@Activate指定了在provider端使用 ``` @Activate(group = Constants.PROVIDER, order = -120000) public class PFilter implements Filter{ public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { System.out.println("[PFilter][invoke]" + invocation.getMethodName()); return invoker.invoke(invocation); } } ``` CFilter實現了Filter接口,注解@Activate指定了在consumer端使用 ``` @Activate(group = Constants.CONSUMER, order = -120000) public class CFilter implements Filter{ public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { System.out.println("[CFilter][invoke]" + invocation.getMethodName()); return invoker.invoke(invocation); } } ``` 下面是測試程序: ``` public static void main(String[] args) { ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getDefaultExtension(); Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); // 創建url URL url = new URL("injvm","127.0.0.1",0); url= url.setPath(DemoService.class.getName()); url = url.addParameter(Constants.EXPORTER_LISTENER_KEY, "provider.listener"); url = url.addParameter(Constants.INVOKER_LISTENER_KEY, "consumer.listener"); // 發布服務1.創建export invoker Invoker<DemoService> invoker = proxyFactory.getInvoker(new DemoServiceImpl(),DemoService.class,url); // 發布服務2.發布到injvm協議 Exporter<DemoService> exporter = protocol.export(invoker); // 可以取消發布,會拋出異常 // exporter.unexport();//Service [com.alibaba.dubbo.demo.DemoService] not found. // 引用服務1.創建ref Invoker Invoker<DemoService> consuerInvoker = protocol.refer(DemoService.class, url); // 引用服務2.創建代理對象 DemoService service = proxyFactory.getProxy(consuerInvoker); System.out.println(service.sayHello("world")); // 執行調用 } ``` 輸出為: ``` [04/12/17 09:44:15:015 CST] main INFO logger.LoggerFactory: using logger: com.alibaba.dubbo.common.logger.log4j.Log4jLoggerAdapter [PExporterListener][exported]:injvm://127.0.0.1/com.alibaba.dubbo.demo.DemoService?exporter.listener=provider.listener&invoker.listener=consumer.listener [CExporterListener][referred]:injvm://127.0.0.1/com.alibaba.dubbo.demo.DemoService?exporter.listener=provider.listener&invoker.listener=consumer.listener [CFilter][invoke]sayHello [PFilter][invoke]sayHello Hello world ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看