日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

dubbo请求调用过程分析

發布時間:2025/4/16 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 dubbo请求调用过程分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

服務消費方發起請求

?

當服務的消費方引用了某遠程服務,服務的應用方在spring的配置實例如下:

?

<dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService"?/>

?

demoService實例其實是代理工廠生產的代理對象(大家可以參考代理那部分生成的偽代碼),在代碼中調用demoService.sayHello(“world!”)時,

?

1.????? 將方法名方法參數傳入InvokerInvocationHandler的invoke方

?

對于Object中的方法toString, hashCode, equals直接調用invoker的對應方法,

?

這里對于Object的方法需要被遠程調用嗎?調用了是不是報錯比默認處理更好呢??

?

遠程調用層是以Invocation, Result為中心, 這里根據要調用的方法以及傳入的參數構建RpcInvocation對象,作為Invoker的入參

?

2.????? MockClusterInvoker根據參數提供了三種調用策略

?

不需要mock, 直接調用FailoverClusterInvoker

?

強制mock,調用mock

?

先調FailoverClusterInvoker,調用失敗在mock、

?

3.????? FailoverClusterInvoker默認調用策略

?

通過目錄服務查找到所有訂閱的服務提供者的Invoker對象

?

路由服務根據策略來過濾選擇調用的Invokers

?

通過負載均衡策略LoadBalance來選擇一個Invoker

?

4.????? 執行選擇的Invoker.inoker(invocation)

?

經過監聽器鏈,默認沒有

?

經過過濾器鏈,內置實現了很多

?

執行到遠程調用的DubboInvoker

?

5.????? DubboInvoker

?

根據url 也就是根據服務提供者的長連接,這里封裝成交互層對象ExchangeClient供這里調用

?

判斷遠程調用類型同步,異步還是oneway模式

?

ExchangeClient發起遠程調用,底層remoting不在這里描述了

?

獲取調用結果:

?

??????? Oneway返回空RpcResult

?

??????? 異步,直接返回空RpcResult, ResponseFuture回調

?

??????? 同步, ResponseFuture模式同步轉異步,等待響應返回

?

?

?

?

?

服務提供方接收調用請求

?

同樣我們也是rpc調用層DubboProtocol層開始分析,對于通信層remoting的數據接收反序列等等過程不做分析。

?

DubboProtocol的requestHandler是ExchangeHandler的實現,是remoting層接收數據后的回調。

?

requestHandler.replay方法接收請求消息,這里只處理遠程調用消息Invocation。

?

1.????? 通過Invocation獲取服務名和端口組成serviceKey=com.alibaba.dubbo.demo.DemoService:20880, 從DubboProtocol的exproterMap中獲取暴露服務的DubboExporter, 在從dubboExporter 獲取invoker返回

?

2.????? 經過過濾器鏈

?

3.????? 經過監聽器鏈

?

4.????? 到達執行真正調用的invoker, 這個invoker由代理工廠ProxyFactory.getInvoker(demoService, DemoService.class, registryUrl)創建,具體請看代理那部分介紹。

?

調用demoService實例方法,將結果封裝成RpcResult返回

?

5.????? 交換層構建Response,通過Remoting層編碼傳輸將結果響應給調用方

?

?

?

?

?

服務消費方發起遠程調用的底層通信

?

?

服務提供方接收請求并響應的底層通信

?

一:provider提供方

?



?

ClassPathXmlApplicationContext <init>(構造方法)

?

-> ClassPathXmlApplicationContext refresh()

?

-> ClassPathXmlApplicationContext finishRefresh()

?

-> AbstractApplicationContext publishEvent()

?

-> ServiceBean onApplicationEvent()

?

-> ServiceConfig doExport()

?

#構造dubbo對象 application provider module protocol registry service reference consume等

?

?

?

-> ServiceConfig doExportUrls #導出URL,獲取注冊中心RegistryConfig

?

#注冊中心:registry://10.199.101.228:2181/com.alibaba.dubbo.registry.RegistryService?application=demo&backup=10.199.101.227:2181,10.199.101.229:2181&dubbo=2.4.9&pid=8045&registry=zookeeper&timestamp=1491546077803

?

?

?

-> ServiceConfig doExportUrlsFor1Protocol()

?

#需要暴露 dubbo://10.199.66.242:20880/com.unj.dubbotest.provider.DemoService?anyhost=true&application=dubbo_demo_provider&dubbo=2.4.9&interface=com.unj.dubbotest.provider.DemoService&methods=sayHello,getUsers&pid=8045&revision=0.0.1&side=provider&timestamp=1491546674441&version=0.0.1

?

?

?

-> ServiceConfig exportLocal()

?

-> Exporter<?> exporter = protocol.export(proxyFactory.getInvoker(ref, (Class) interfaceClass, local));

?

#暴露Invoker<XxxService>調用服務代理類

?

?

?

-> proxyFactory.getInvoker(ref, (Class) interfaceClass, local)

?

#返回 AbstractProxyInvoker代理ProxyInvoker<XxxService>

?

public abstract class AbstractProxyInvoker<T> implements Invoker<T> {

?

private final T proxy; //代理目標實例 XxxServiceImpl

?

private final Class<T> type;

?

private final URL url;

?

}

?

-> InvokerInvocationHandler.invoke()

?

#invoker.invoke(new RpcInvocation(method, args)).recreate();

?

?

?

-> DubboProtocol export(Invoker<T> invoker)

?

# 返回暴露Exporter<T>

?

public class DubboExporter<T> extends AbstractExporter<T> {

?

private final String key; //com.unj.dubbotest.provider.DemoService:0.0.1:20880

?

private final Map<String, Exporter<?>> exporterMap;

?

public DubboExporter(Invoker<T> invoker, String key, Map<String, Exporter<?>> exporterMap){

?

super(invoker);

?

this.key = key;

?

this.exporterMap = exporterMap;

?

}

?

?

?

-> DubboProtocol openServer(url)

?

#url dubbo://10.199.66.242:20880/com.unj.dubbotest.provider.DemoService?anyhost=true&application=dubbo_demo&dubbo=2.4.9&interface=com.unj.dubbotest.provider.DemoService&methods=sayHello,getUsers&pid=8045&revision=0.0.1&side=provider&timestamp=1491546674441&version=0.0.

?

#serverMap.put(key, createServer(url)); key:10.199.66.242:20880 value:ExchangeServer

?

?

?

-> DubboProtocol createServer(URL url)

?

#返回HeaderExchangeServer,添加參數列表 如心跳,心跳時間

?

-> Exchangers.bind(url, requestHandler);

?

#返回HeaderExchangeServer,getTransporter()獲取的實例來源于配置,默認返回一個NettyTransporter

?

-> HeaderExchangeServer.bind(URL url, ExchangeHandler handler);

?

?

?

-> HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))));

?

#HeaderExchangeServer包裝實例NettyServer

?

?

?

-> NettyTransporter.bind(URL url, ChannelHandler listener)

?

#return new NettyServer(url, listener)

?

?

?

-> NettyServer.doOpen();

?

#打開socket監聽端口準備接收消息

?

#ServerBootstrap bind(getBindAddress())綁定地址端口

?

#RpcInvocation 具體類名、方法名、調用參數

?

#DubboInvoker – 執行具體的遠程調用,包含初始化信息如client

?

#Protocol – 服務地址的發布和訂閱

?

#Exporter – 暴露服務的引用,或取消暴露

?

?

?

二:consume(消費方):

?

->ReferenceConfig.init

?

#consume端啟動初始化

?

->DubboProtocol.refer

?

#根據參數url,接口等構建Invoker

?

->JavassistProxyFactory.getProxy(Invoker<T> invoker, Class<?>[] interfaces)

?

#構建代理對象Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));

?

?

?

->DemoService.say(String hello);#真正調用時候

?

->InvokerInvocationHandler.invoke(Object proxy, Method method, Object[] args)

?

#invoker.invoke(new RpcInvocation(method, args)).recreate();RpcInvocation包裝參數方法名

?

->DubboInvoker.doInovke(final Invocation invocation)

?

#統一代理調用

?

->ExchangeClient.send(invocation, isSent);

?

->HeaderExchangeChannel.request(Object request, int timeout)

?

->NettyChannel.send(Object message, boolean sent)

?

?

?

三:dubbo 底層通訊:NettyClient <-- 異步NIO傳輸 socket監聽-> NettyServer

?

?

?

四:consume --> provider 調用過程:

?

-> NettyServer->NettyHandler.messageReceived #接收消息處理器

?

-> MultiMessageHandler->HeartbeatHandler->AllChannelHandler->DecodeHandler->HeaderExchangeHandler->DubboProtocol$requestHandler

?

#NettyServer啟動時候綁定MultiMessageHandler

?

#DubboProtocol.getServers() 檢索serverMap獲取Exporter<?>

?

#DubboProtocol.getServers() 檢索serverMap獲取ExchangeServer

?

-> ExchangeHandlerAdapter.reply

?

#真正獲取Invoker,將傳入message 轉換 invocation

?

-> invoker.invoke(invocation)

?

-> JavassistProxyFactory$AbstractProxyInvoker.doInvoke

?

#服務端Invoker代理 AbstractProxyInvoker調用目標引用service
原文鏈接:[http://wely.iteye.com/blog/2378164]

總結

以上是生活随笔為你收集整理的dubbo请求调用过程分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。