Dubbo——服務(wù)調(diào)用、服務(wù)暴露忽刽、服務(wù)引用過(guò)程

Dubbo

整體架構(gòu)

image-20200905202820262
image-20200905202931254

1天揖、InvokerInvocationHandler jdk動(dòng)態(tài)代理

5夺欲、RegistryDirector返回Invokers
Router分為:Script 腳本路由、Condition 條件路由

6今膊、通過(guò)MockInvokersSelector的route方法(getNormalInvokers)拿到能正常執(zhí)行的invokers

8些阅、當(dāng)回到AbstractClusterInvoker后,執(zhí)行(默認(rèn)FailoverClusterInvoker斑唬,根據(jù)配置的是市埋,F(xiàn)ailfast Cluster(快速失敗),Failsafe Cluster(失敗安全),Failback Cluster(失敗自動(dòng)恢復(fù)),Forking Cluster(并行調(diào)用多個(gè)服務(wù)器,只要一個(gè)成功即返回),Broadcast Cluster(廣播調(diào)用所有提供者恕刘,逐個(gè)調(diào)用缤谎,任意一臺(tái)報(bào)錯(cuò)則報(bào)錯(cuò)))doInvoker方法

9、FailoverClusterInvoker調(diào)用AbstractClusterInvoker的select方法

10、執(zhí)行doSelect方法

11、調(diào)用AbstractLoadbalance的select方法

12斗躏、根據(jù)配置的負(fù)載均衡策略調(diào)用對(duì)應(yīng)的(如RoundRobinLoadBalance)類(lèi)的doSelect方法

13静汤、返回invokers.get()方法

14、調(diào)用FailoverClusterInvoker的invoke方法

  • Directory中找出本次集群中的全部invokers
  • Router中,將上一步的全部invokers挑選出能正常執(zhí)行的invokers
  • LoadBalance中,將上一步的能正常的執(zhí)行invokers中,根據(jù)配置的負(fù)載均衡策略,挑選出需要執(zhí)行的invoker

Director接口

  • StaticDirectory Invoker通過(guò)構(gòu)造函數(shù)傳入银择,所以不是動(dòng)態(tài)變化的,用的較少。
  • RegistryDirectory 實(shí)現(xiàn)了NotifyListener接口姻政,notify方法就是注冊(cè)中心的回調(diào),可以根據(jù)注冊(cè)中心動(dòng)態(tài)變化

均繼承自抽象類(lèi)AbstractDirectory

Directory 代表多個(gè) Invoker岂嗓,可以把它看成 List<Invoker> ,但與 List 不同的是汁展,它的值可能是動(dòng)態(tài)變化的,比如注冊(cè)中心推送變更

Directory獲取invoker是從methodInvokerMap中獲取的厌殉,主要都是讀操作,那它的寫(xiě)操作是在什么時(shí)候?qū)懙哪?就是在回調(diào)方法notify的時(shí)候操作的食绿,也就是注冊(cè)中心有變化,則更新methodInvokerMapurlInvokerMap的值

Router接口

  • MockInvokersSelector
  • ConditionRouter
  • ScriptRouter

ScriptRouter:腳本路由規(guī)則 支持 JDK 腳本引擎的所有腳本,比如:javascript, jruby, groovy 等公罕,通過(guò) type=javascript 參數(shù)設(shè)置腳本類(lèi)型器紧,缺省為 javascript。

ConditionRouter(條件路由)

根據(jù)dubbo-admin配置的路由規(guī)則來(lái)過(guò)濾相關(guān)的invoker楼眷,當(dāng)我們對(duì)路由規(guī)則點(diǎn)擊啟用铲汪,就會(huì)觸發(fā)RegistryDirectory類(lèi)的notify方法。

img

notify方法調(diào)用refreshInvoker方法罐柳。

route方法的實(shí)現(xiàn)類(lèi)為ConditionRoute 根據(jù)條件進(jìn)行過(guò)濾

1掌腰、調(diào)用mathThen方法

2、調(diào)用matchCondition方法

3张吉、調(diào)用isMatch判斷

4齿梁、調(diào)用isMatchGlobPattern方法

Cluster

Cluster 將 Directory 中的多個(gè) Invoker 偽裝成一個(gè) Invoker,對(duì)上層透明,偽裝過(guò)程包含了容錯(cuò)邏輯勺择,調(diào)用失敗后创南,重試另一個(gè)

? 集群模塊是服務(wù)提供者和服務(wù)消費(fèi)者的中間層,為服務(wù)消費(fèi)者屏蔽了服務(wù)提供者的情況酵幕,這樣服務(wù)消費(fèi)者就可以專(zhuān)心處理遠(yuǎn)程調(diào)用相關(guān)事宜扰藕。比如發(fā)請(qǐng)求,接受服務(wù)提供者返回的數(shù)據(jù)等芳撒。這就是Dubbo Cluster集群的作用邓深。

<dubbo:service cluster="failsafe" />

通過(guò)cluster來(lái)指定集群容錯(cuò)方式

其實(shí)就是應(yīng)對(duì)出錯(cuò)情況采取的策略

img
  • MergeableCluster 分組聚合 按組合并返回結(jié)果,用group區(qū)分笔刹,比如消費(fèi)者需要從每種group中調(diào)用一次返回結(jié)果芥备,合并結(jié)果返回。
  • AvailableCluster 可用的舌菜,遍歷所有的Invokers萌壳,判斷isAvalible,只要一個(gè)有為true的直接調(diào)用返回日月,否則就拋出異常袱瓮。
  • ForkingCluster 并行調(diào)用多個(gè)服務(wù)器,只要一個(gè)成功即返回
  • FailfastCluster 快速失敗爱咬,只發(fā)起一次調(diào)用尺借,失敗立即報(bào)錯(cuò),通常用于非冪等性的寫(xiě)操作精拟,比如新增
  • MockClusterWrapper 本地mock用于服務(wù)降級(jí)燎斩,如果服務(wù)提供方全部掛掉后,客戶(hù)端通過(guò)mock返回授權(quán)失敗
  • FailoverCluster 失敗自動(dòng)切換蜂绎,當(dāng)出現(xiàn)失敗時(shí)重試其他服務(wù)器栅表,通常用于讀操作,可通過(guò)retries來(lái)設(shè)置重試次數(shù)师枣。所以如果是讀接口怪瓶,適合用FailoverCluster,如果是寫(xiě)接口践美,適合FailfastCluster
  • FailbackCluster 失敗自動(dòng)恢復(fù)劳殖,后臺(tái)記錄失敗請(qǐng)求,定時(shí)重發(fā)拨脉,通常用于消息通知操作
  • FailsafeCluster 失敗安全,出現(xiàn)異常時(shí)宣增,直接忽略玫膀,通常用于寫(xiě)入審計(jì)日志等操作。
  • BroadcastCluster 廣播調(diào)用所有提供者爹脾,逐個(gè)調(diào)用帖旨,任意一臺(tái)報(bào)錯(cuò)則報(bào)錯(cuò)箕昭,通常用于通知所有提供者更新緩存或者日志等本地資源信息。

粘滯鏈接

用于有狀態(tài)服務(wù)解阅,盡可能讓客戶(hù)端總是向同一提供者發(fā)起調(diào)用落竹,除非提供者掛了,再連另一臺(tái)货抄,自動(dòng)開(kāi)啟延遲鏈接述召,以減少長(zhǎng)接數(shù)

<dubbo:referenc id="xxxService" interface="com.xxx.xxx" sticky="true"

LoadBalance

  • RandomLoadBalance 隨機(jī) 按權(quán)重設(shè)置隨機(jī)概率
  • RoundRobinLoadBalance 輪詢(xún),按權(quán)重設(shè)置輪詢(xún)比率
  • LeastActiveLoadBalance 最少活躍數(shù) 根據(jù)當(dāng)前連接數(shù)來(lái)分配蟹地,越慢的提供者收到越少的請(qǐng)求积暖。
  • ConsistenHashLoadaBalance 一致性哈希 相同參數(shù)的請(qǐng)求總是發(fā)到同一提供者,如果一臺(tái)機(jī)器掛了怪与,則平攤分發(fā)到虛擬節(jié)點(diǎn)夺刑,默認(rèn)只對(duì)第一個(gè)參數(shù)做hash,默認(rèn)160個(gè)虛擬節(jié)點(diǎn)

自定義負(fù)載均衡算法——原理:

? 啟動(dòng)時(shí)服務(wù)提供者將當(dāng)前進(jìn)程啟動(dòng)時(shí)間注冊(cè)到ZK分别;服務(wù)消費(fèi)者發(fā)現(xiàn)該節(jié)點(diǎn)后計(jì)算服務(wù)啟動(dòng)時(shí)間(相對(duì)當(dāng)前時(shí)間)遍愿,在默認(rèn)預(yù)熱時(shí)間的前20%時(shí)間內(nèi),該節(jié)點(diǎn)權(quán)重始終固定為2耘斩,這樣客戶(hù)端的負(fù)載均衡器只會(huì)分發(fā)極少的請(qǐng)求至節(jié)點(diǎn)沼填。

? 在預(yù)熱時(shí)間之后的80%時(shí)間內(nèi),該節(jié)點(diǎn)權(quán)重將隨著時(shí)間的推移而線性增長(zhǎng)煌往;待預(yù)熱時(shí)間到期后倾哺,權(quán)重自動(dòng)恢復(fù)為默認(rèn)值100;負(fù)載均衡器的內(nèi)核是一個(gè)標(biāo)準(zhǔn)的WLC算法模塊刽脖,即加權(quán)最少連接算法羞海;

? 如果某個(gè)節(jié)點(diǎn)Hang住或宕機(jī),其權(quán)重會(huì)迅速自動(dòng)調(diào)節(jié)降低曲管,避免持續(xù)性影響却邓;當(dāng)節(jié)點(diǎn)下線時(shí),服務(wù)端提前觸發(fā)權(quán)重調(diào)節(jié)院水,重載默認(rèn)權(quán)重至1并發(fā)布到注冊(cè)中心腊徙,服務(wù)消費(fèi)者將迅速感知到該事件;
服務(wù)提供者優(yōu)雅下線步驟(注意這套邏輯僅在服務(wù)端執(zhí)行)在ok.htm?down=true對(duì)應(yīng)的controller中加入下列邏輯檬某,注意要判斷down是否為true撬腾,因?yàn)檎?lái)說(shuō)false表示啟動(dòng)驗(yàn)證而不是關(guān)機(jī)

  • 調(diào)用smartServerHelper.setOverrideWeight(1);將當(dāng)前服務(wù)端的權(quán)重設(shè)置為1恢恼;等待5秒民傻;
  • 調(diào)用smartServerHelper.prepareShutdown();將當(dāng)前服務(wù)端置為臨時(shí)禁用(當(dāng)進(jìn)程結(jié)束后該狀態(tài)會(huì)被自動(dòng)清除)
  • 等待1秒;
  • 正常關(guān)閉進(jìn)程漓踢;
  • 在關(guān)機(jī)腳本(一般為shutdown)的stop方法中牵署,調(diào)用/ok.htm?down=true

服務(wù)者消費(fèi)者配置

<dubbo:consumer loadbalance="smart"/>

dubbo服務(wù)支持參數(shù)動(dòng)態(tài)調(diào)整,例如動(dòng)態(tài)調(diào)整權(quán)重喧半,但dubbo實(shí)現(xiàn)方式較為特殊奴迅,并不是常規(guī)思路。

普通狀態(tài)
默認(rèn)情況下挺据,任意一臺(tái)dubbo服務(wù)端上線后會(huì)注冊(cè)到配置中心(zk)取具,路徑為/<group>/<service>/providers

節(jié)點(diǎn)名為完整的服務(wù)URI,類(lèi)似下面

dubbo%3A%2F%2F10.57.17.156%3A20880%2Fcn.tongdun.arch.dbench.IDbenchService%3Fanyhost%3Dtrue%26application%3Ddbench%26default.remote.timestamp%3D1553248880792%26dubbo%3D2.8.4%26generic%3Dfalse%26interface%3Dcn.tongdun.arch.dbench.IDbenchService%26methods%3DgetTotalPayloadSize%2CtestWithSleep%26pid%3D798%26revision%3D1.0%26side%3Dprovider%26timestamp%3D1553248881596%26version%3D1.0.1%26warmup%3D600000
這個(gè)節(jié)點(diǎn)本身是具有瞬時(shí)性和不變性吴菠,機(jī)器下線時(shí)將自動(dòng)刪除者填,那dubbo怎么保存動(dòng)態(tài)修改的值呢?

覆蓋狀態(tài)
對(duì)于動(dòng)態(tài)配置做葵,dubbo將在zk的 /<group>/<service>/configurators 路徑下單獨(dú)發(fā)布一條URI占哟,例如調(diào)整某臺(tái)機(jī)器權(quán)重后,會(huì)產(chǎn)生下面的節(jié)點(diǎn)override%3A%2F%2F10.57.17.156%3A20880%2Fcn.tongdun.arch.dbench.IDbenchService%3Fcategory%3Dconfigurators%26dynamic%3Dtrue%26version%3D1.0.1%26weight%3D1
這個(gè)節(jié)點(diǎn)不具備瞬時(shí)性(跟普通狀態(tài)的節(jié)點(diǎn)不一樣)酿矢,也就是說(shuō)這條動(dòng)態(tài)配置一經(jīng)發(fā)布榨乎,不會(huì)自動(dòng)刪除。

另外瘫筐,可以任意發(fā)布多條動(dòng)態(tài)配置蜜暑,最終體現(xiàn)在zk里的順序是隨機(jī)的。

客戶(hù)端
客戶(hù)端訂閱服務(wù)后策肝,會(huì)去zk拉取普通狀態(tài)節(jié)點(diǎn)和覆蓋狀態(tài)下的所有節(jié)點(diǎn)肛捍,將所有的狀態(tài)的節(jié)點(diǎn)進(jìn)行疊加后,得到最終的訂閱配置數(shù)據(jù)之众。

因此如果發(fā)布了動(dòng)態(tài)配置而不刪除拙毫,則可能會(huì)導(dǎo)致客戶(hù)端得到的配置錯(cuò)亂,造成不可預(yù)料之后果

服務(wù)暴露原理

  • 暴露本地服務(wù)
  • 暴露遠(yuǎn)程服務(wù)
  • 啟動(dòng)netty
  • 連接zookeeper
  • 到zookeeper注冊(cè)
  • 監(jiān)聽(tīng)zookeeper
img
img

? ServiceConfig類(lèi)拿到對(duì)外提供服務(wù)的實(shí)際類(lèi)ref棺禾,然后通過(guò)ProxyFactory類(lèi)的getInvoker方法使用ref生成一個(gè)AbstractProxyInvoker實(shí)例缀蹄,到這一步就完成具體服務(wù)到Invoker的轉(zhuǎn)換(javassistProxyFacory、JdkProxyFactory)膘婶,接著要做Invoker轉(zhuǎn)換到Export的過(guò)程

? 服務(wù)發(fā)布:本地暴露缺前、遠(yuǎn)程暴露

? 為什么會(huì)有本地暴露遠(yuǎn)程暴露呢?不從場(chǎng)景考慮討論技術(shù)的沒(méi)有意義是.在dubbo中我們一個(gè)服務(wù)可能既是Provider,又是Consumer,因此就存在他自己調(diào)用自己服務(wù)的情況,如果再通過(guò)網(wǎng)絡(luò)去訪問(wèn),那自然是舍近求遠(yuǎn),因此他是有本地暴露服務(wù)的這個(gè)設(shè)計(jì).從這里我們就知道這個(gè)兩者的區(qū)別

  • 本地暴露是暴露在JVM中,不需要網(wǎng)絡(luò)通信. url是inJvm開(kāi)頭
  • 遠(yuǎn)程暴露是將ip,端口等信息暴露給遠(yuǎn)程客戶(hù)端,調(diào)用時(shí)需要網(wǎng)絡(luò)通信.url是registry開(kāi)頭

本地暴露:

img

遠(yuǎn)程暴露

img
img

ServiceConfig ------> ref

ProxyFactory --------> Javassist、JDK動(dòng)態(tài)代理

Invoker ----------> AbstractProxyInvoker

Protocol --------> Dubbo悬襟、injvm等

Exporter

1衅码、spring啟動(dòng),解析配置文件

2脊岳、創(chuàng)建dubbo標(biāo)簽解析器

3逝段、解析dubbo標(biāo)簽

4筛璧、ServiceBean解析

5、容器創(chuàng)建完成惹恃,觸發(fā)ContextRefrestEvent

6、export暴露服務(wù)

7棺牧、duExportUrls

8巫糙、doExportUrlsFor1Protocol

  • JavassistProxyFactory模式原理:創(chuàng)建Wrapper子類(lèi),在子類(lèi)中實(shí)現(xiàn)invokeMethod方法颊乘,方法體內(nèi)會(huì)為每個(gè)ref方法都做方法名和方法參數(shù)匹配校驗(yàn)参淹,如果匹配則直接調(diào)用即可,相比JDKProxyFactory省去了反射調(diào)用的開(kāi)銷(xiāo)乏悄。
  • JDKProxyFactory:通過(guò)反射獲取真實(shí)對(duì)象的方法浙值,然后調(diào)用即可。

9檩小、getInvoker

10开呐、protocol.export

11、開(kāi)啟服務(wù)器 openServer()如nettyServer

12规求、注冊(cè)服務(wù)到注冊(cè)中心 registerProvider

getRegistry() 方法根據(jù)注冊(cè)中心類(lèi)型(默認(rèn) Zookeeper)獲取注冊(cè)中心客戶(hù)端筐付,由注冊(cè)中心客戶(hù)端實(shí)例來(lái)進(jìn)行真正的服務(wù)注冊(cè)。注冊(cè)中心客戶(hù)端將節(jié)點(diǎn)注冊(cè)到注冊(cè)中心阻肿,同時(shí)訂閱對(duì)應(yīng)的 override 數(shù)據(jù)瓦戚,實(shí)時(shí)監(jiān)聽(tīng)服務(wù)的屬性變動(dòng)實(shí)現(xiàn)動(dòng)態(tài)配置功能。最終返回的 Exporter 實(shí)現(xiàn)了 unexport() 方法丛塌,這樣在服務(wù)下線時(shí)清理相關(guān)資源较解。

  1. 委托具體協(xié)議(Dubbo)進(jìn)行服務(wù)暴露,創(chuàng)建NettyServer監(jiān)聽(tīng)端口和保存服務(wù)實(shí)例赴邻。
  2. 創(chuàng)建注冊(cè)中心對(duì)象印衔,與注冊(cè)中心創(chuàng)建TCP連接。
  3. 注冊(cè)服務(wù)元數(shù)據(jù)到注冊(cè)中心乍楚。
  4. 訂閱configuators節(jié)點(diǎn)当编,監(jiān)聽(tīng)服務(wù)動(dòng)態(tài)屬性變更事件。
  5. 服務(wù)銷(xiāo)毀收尾工作徒溪,比如關(guān)閉端口忿偷、反注冊(cè)服務(wù)信息等。

Filter 在服務(wù)暴露前臊泌,做攔截器初始化鲤桥,在加載所有攔截器時(shí)會(huì)過(guò)濾支隊(duì)provider生效的數(shù)據(jù)。

ZK連接

dubbo中zookeeper做注冊(cè)中心,如果注冊(cè)中心集群都掛掉,那發(fā)布者和訂閱者還能通信嗎?

可以渠概。zookeeper的信息會(huì)緩存到本地作為一個(gè)緩存文件,并且轉(zhuǎn)換成properties對(duì)象方便使用茶凳。建立線程池嫂拴,定時(shí)檢測(cè)并連接注冊(cè)中心,失敗了就重連贮喧。

創(chuàng)建節(jié)點(diǎn)

注冊(cè)服務(wù)到zk其實(shí)就是在zk上創(chuàng)建臨時(shí)節(jié)點(diǎn)筒狠,當(dāng)節(jié)點(diǎn)下線或者down掉時(shí),即會(huì)刪除臨時(shí)節(jié)點(diǎn)箱沦,從而使服務(wù)從可用列表中剔除辩恼。

持久節(jié)點(diǎn)

所謂持久節(jié)點(diǎn),是指在節(jié)點(diǎn)創(chuàng)建后,就一直存在,直到有刪除操作來(lái)主動(dòng)清除這個(gè)節(jié)點(diǎn),也就是說(shuō)不會(huì)因?yàn)閯?chuàng)建該節(jié)點(diǎn)的客戶(hù)端會(huì)話失效而消失

臨時(shí)節(jié)點(diǎn)

臨時(shí)節(jié)點(diǎn)的生命周期和客戶(hù)端會(huì)話綁定,也就是說(shuō),如果客戶(hù)端會(huì)話失效,那么這個(gè)節(jié)點(diǎn)就會(huì)自動(dòng)被清除掉

img

1、export的時(shí)候進(jìn)行zk訂閱

2谓形、設(shè)置監(jiān)聽(tīng)回調(diào)的地址灶伊,回調(diào)給FailbackRegistry的notify

3、創(chuàng)建持久節(jié)點(diǎn)

4寒跳、設(shè)置對(duì)該節(jié)點(diǎn)的監(jiān)聽(tīng)

5聘萨、更新新的服務(wù)信息,服務(wù)啟動(dòng)和節(jié)點(diǎn)更新回調(diào)童太,都會(huì)調(diào)用到這里

6米辐、更新緩存文件

7、對(duì)比新舊信息是否有變化康愤,有則重新暴露服務(wù)

服務(wù)暴露總結(jié):

img
img

服務(wù)降級(jí)

為什么需要服務(wù)降級(jí)

高并發(fā)大業(yè)務(wù)量情況下儡循,暫時(shí)屏蔽邊緣業(yè)務(wù)

怎么做?

MockClusterInvoker

  • no mock 直接調(diào)用
  • force:direct mock 直接不調(diào)用征冷,返回一個(gè)之前設(shè)置的值
  • fail-mock 調(diào)用失敗后择膝,返回一個(gè)設(shè)置的值

服務(wù)引用

img

Dubbo 服務(wù)引用的時(shí)機(jī)有兩個(gè),第一個(gè)是在 Spring 容器調(diào)用 ReferenceBean 的 afterPropertiesSet 方法時(shí)引用服務(wù)检激,第二個(gè)是在 ReferenceBean 對(duì)應(yīng)的服務(wù)被注入到其他類(lèi)中時(shí)引用肴捉。這兩個(gè)引用服務(wù)的時(shí)機(jī)區(qū)別在于,第一個(gè)是餓漢式的叔收,第二個(gè)是懶漢式的齿穗。默認(rèn)情況下,Dubbo 使用懶漢式引用服務(wù)饺律。如果需要使用餓漢式窃页,可通過(guò)配置 <dubbo:reference> 的 init 屬性開(kāi)啟。下面我們按照 Dubbo 默認(rèn)配置進(jìn)行分析复濒,整個(gè)分析過(guò)程從 ReferenceBean 的 getObject 方法開(kāi)始脖卖。當(dāng)我們的服務(wù)被注入到其他類(lèi)中時(shí),Spring 會(huì)第一時(shí)間調(diào)用 getObject 方法巧颈,并由該方法執(zhí)行服務(wù)引用邏輯畦木。按照慣例,在進(jìn)行具體工作之前砸泛,需先進(jìn)行配置檢查與收集工作十籍。接著根據(jù)收集到的信息決定服務(wù)用的方式蛆封,有三種,第一種是引用本地 (JVM) 服務(wù)勾栗,第二是通過(guò)直連方式引用遠(yuǎn)程服務(wù)惨篱,第三是通過(guò)注冊(cè)中心引用遠(yuǎn)程服務(wù)。不管是哪種引用方式围俘,最后都會(huì)得到一個(gè) Invoker 實(shí)例妒蛇。如果有多個(gè)注冊(cè)中心,多個(gè)服務(wù)提供者楷拳,這個(gè)時(shí)候會(huì)得到一組 Invoker 實(shí)例,此時(shí)需要通過(guò)集群管理類(lèi) Cluster 將多個(gè) Invoker 合并成一個(gè)實(shí)例吏奸。合并后的 Invoker 實(shí)例已經(jīng)具備調(diào)用本地或遠(yuǎn)程服務(wù)的能力了欢揖,但并不能將此實(shí)例暴露給用戶(hù)使用,這會(huì)對(duì)用戶(hù)業(yè)務(wù)代碼造成侵入奋蔚。此時(shí)框架還需要通過(guò)代理工廠類(lèi) (ProxyFactory) 為服務(wù)接口生成代理類(lèi)她混,并讓代理類(lèi)去調(diào)用 Invoker 邏輯。避免了 Dubbo 框架代碼對(duì)業(yè)務(wù)代碼的侵入泊碑,同時(shí)也讓框架更容易使用坤按。

  • 將spring的schemas標(biāo)簽信息轉(zhuǎn)換ReferenceBean,然后通過(guò)這個(gè)bean的信息,連接、訂閱zookeeper節(jié)點(diǎn)信息創(chuàng)建一個(gè)invoker
  • invoker的信息創(chuàng)建一個(gè)動(dòng)態(tài)代理對(duì)象(createProxy)
  • 1馒过、加載配置中心拼裝成urls
  • 2臭脓、遍歷urls調(diào)用refProtocol創(chuàng)建遠(yuǎn)程的動(dòng)態(tài)代理Invoker
  • 3、調(diào)用proxyFacotry創(chuàng)建服務(wù)代理(javassistProxyFacotry)
img
img

SPI

? SPI 全稱(chēng)為 Service Provider Interface腹忽,是一種服務(wù)發(fā)現(xiàn)機(jī)制来累。SPI 的本質(zhì)是將接口實(shí)現(xiàn)類(lèi)的全限定名配置在文件中,并由服務(wù)加載器讀取配置文件窘奏,加載實(shí)現(xiàn)類(lèi)嘹锁。這樣可以在運(yùn)行時(shí),動(dòng)態(tài)為接口替換實(shí)現(xiàn)類(lèi)着裹。正因此特性领猾,我們可以很容易的通過(guò) SPI 機(jī)制為我們的程序提供拓展功能。SPI 機(jī)制在第三方框架中也有所應(yīng)用骇扇,比如 Dubbo 就是通過(guò) SPI 機(jī)制加載所有的組件摔竿。不過(guò),Dubbo 并未使用 Java 原生的 SPI 機(jī)制匠题,而是對(duì)其進(jìn)行了增強(qiáng)拯坟,使其能夠更好的滿(mǎn)足需求。在 Dubbo 中韭山,SPI 是一個(gè)非常重要的模塊郁季±淅#基于 SPI,我們可以很容易的對(duì) Dubbo 進(jìn)行拓展梦裂。如果大家想要學(xué)習(xí) Dubbo 的源碼似枕,SPI 機(jī)制務(wù)必弄懂。接下來(lái)年柠,我們先來(lái)了解一下 Java SPI 與 Dubbo SPI 的用法凿歼,然后再來(lái)分析 Dubbo SPI 的源碼。

image-20200905202628624
image-20200905202647690
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冗恨,一起剝皮案震驚了整個(gè)濱河市答憔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌掀抹,老刑警劉巖虐拓,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異傲武,居然都是意外死亡蓉驹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)揪利,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)态兴,“玉大人,你說(shuō)我怎么就攤上這事疟位≌叭螅” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵甜刻,是天一觀的道長(zhǎng)敢订。 經(jīng)常有香客問(wèn)我,道長(zhǎng)罢吃,這世上最難降的妖魔是什么楚午? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮尿招,結(jié)果婚禮上矾柜,老公的妹妹穿的比我還像新娘。我一直安慰自己就谜,他們只是感情好怪蔑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著丧荐,像睡著了一般缆瓣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上虹统,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天弓坞,我揣著相機(jī)與錄音隧甚,去河邊找鬼。 笑死渡冻,一個(gè)胖子當(dāng)著我的面吹牛戚扳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播族吻,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼帽借,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了超歌?” 一聲冷哼從身側(cè)響起砍艾,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎巍举,沒(méi)想到半個(gè)月后辐董,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡禀综,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了苔严。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片定枷。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖届氢,靈堂內(nèi)的尸體忽然破棺而出欠窒,到底是詐尸還是另有隱情,我是刑警寧澤退子,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布岖妄,位于F島的核電站,受9級(jí)特大地震影響寂祥,放射性物質(zhì)發(fā)生泄漏荐虐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一丸凭、第九天 我趴在偏房一處隱蔽的房頂上張望福扬。 院中可真熱鬧,春花似錦惜犀、人聲如沸铛碑。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)汽烦。三九已至,卻和暖如春莉御,著一層夾襖步出監(jiān)牢的瞬間撇吞,已是汗流浹背俗冻。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留梢夯,地道東北人言疗。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像颂砸,于是被迫代替她去往敵國(guó)和親噪奄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350