要了解服務(wù)導(dǎo)出做了什么盾饮,需要了解導(dǎo)出的目的是什么?
dubbo是一款面向接口代理的高性能RPC調(diào)用懒熙,說(shuō)白了就是提供遠(yuǎn)程服務(wù)丘损。
服務(wù)導(dǎo)出需要做的:簡(jiǎn)單說(shuō)就是根據(jù)服務(wù)參數(shù)、服務(wù)協(xié)議構(gòu)建服務(wù)URL工扎,注冊(cè)到注冊(cè)中心徘钥,并啟動(dòng)Server。其中服務(wù)參數(shù)可以動(dòng)態(tài)配置也需要監(jiān)聽(tīng)肢娘。
服務(wù)導(dǎo)出入口
1呈础、onApplicationEvent
org.apache.dubbo.config.spring.ServiceBean#onApplicationEvent
發(fā)布ContextRefreshedEvent,進(jìn)行導(dǎo)出服務(wù)
2橱健、export
org.apache.dubbo.config.spring.ServiceBean#export
調(diào)用父類ServiceConfig導(dǎo)出而钞,之后發(fā)布一個(gè)ServiceBeanExportedEvent
3、export
org.apache.dubbo.config.ServiceConfig#export
①拘荡、檢查更新配置參數(shù)
②臼节、shouldExport檢查服務(wù)是否需要導(dǎo)出
org.apache.dubbo.config.ServiceConfig#shouldExport
③、shouldDelay檢查服務(wù)是否需要延遲發(fā)布
④珊皿、doExport進(jìn)行服務(wù)導(dǎo)出
更新配置
checkAndUpdateSubConfigs
org.apache.dubbo.config.ServiceConfig#checkAndUpdateSubConfigs
1网缝、completeCompoundConfigs
ServiceConfig中的某些屬性如果是空的,那么就從ProviderConfig蟋定、ModuleConfig粉臊、ApplicationConfig中獲取
①、如果配置了ProviderConfig provider溢吻,如果application维费、module果元、registries促王、monitor、protocols而晒、configCenter這些屬性為空的情況下蝇狼,可以從provider中獲取信息并賦值
②、同樣的道理倡怎,如果ModuleConfig module不為空迅耘,可以為registries贱枣、monitor為空的賦值
③、如果ApplicationConfig application不為空颤专,可以為registries纽哥、monitor為空的賦值
2、startConfigCenter
從配置中心獲取配置栖秕,包括應(yīng)用配置和全局配置
①春塌、如果ConfigCenterConfig ConfigCenter配置中心配置不為空,則需要從其他位置獲取配置中心的相關(guān)屬性信息進(jìn)行更新refresh
org.apache.dubbo.config.AbstractConfig#refresh
a簇捍、前綴是prefix = "dubbo.config-center"只壳、id = null 在不同的位置獲取混合的配置CompositeConfiguration
CompositeConfiguration是一個(gè)有序的LinkedList
SystemConfiguration(JVM環(huán)境變量系統(tǒng)配置)、EnvironmentConfiguration(操作系統(tǒng)環(huán)境變量)暑塑、InmemoryConfiguration(配置中心應(yīng)用配置和全局配置)吼句、PropertiesConfiguration(dubbo.properties中的配置)
b、根據(jù)configCenterFirst配置設(shè)置config的位置事格。默認(rèn)true第四個(gè)位置
參數(shù)配置及優(yōu)先級(jí)
SystemConfiguration:是系統(tǒng)環(huán)境變量惕艳,可以在服務(wù)啟動(dòng)時(shí)通過(guò)-D指定參數(shù)
AbstractConfig:是通過(guò)@Service注解配置的參數(shù)
PropertiesConfiguration:是dubbo.properties文件配置的
AppExternalConfiguration和ExternalConfiguration:是在配置中心Dubbo-Admin中配置的,AppXxx是應(yīng)用級(jí)別
配置優(yōu)先級(jí)是:SystemConfiguration -> AppExternalConfiguration -> ExternalConfiguration -> AbstractConfig -> PropertiesConfiguration
如果放到第二個(gè)位置優(yōu)先級(jí)是:SystemConfiguration -->AbstractConfig -> AppExternalConfiguration -> ExternalConfiguration -> -> PropertiesConfiguration
c驹愚、根據(jù)setXX()方法和setParameters()方法進(jìn)行參數(shù)值覆蓋
②尔艇、prepareEnvironment
管理臺(tái)上的動(dòng)態(tài)配置中心,如果是zookeeper么鹤,獲取的就是/dubbo/config/dubbo/dubbo.properties節(jié)點(diǎn)中的內(nèi)容终娃。如果是應(yīng)用級(jí)別的則獲取的就是/dubbo/config/dubbo-demo-consumer-application/dubbo.properties節(jié)點(diǎn)中的內(nèi)容(dubbo-demo-consumer-application應(yīng)用名,這里是以dubbo-demo為例)
③蒸甜、refreshAll
ConfigManager.getInstance().refreshAll()刷新所有配置
org.apache.dubbo.config.context.ConfigManager#refreshAll
3棠耕、checkDefault 從配置中心設(shè)置Provider配置
org.apache.dubbo.config.ServiceConfig#checkDefault
4、checkProtocol 從配置中心設(shè)置Protocol配置
org.apache.dubbo.config.ServiceConfig#convertProtocolIdsToProtocols
①柠新、從配置中心的全局配置獲取dubbo.protocols.的配置項(xiàng)值添加到configedProtocols
②窍荧、從配置中心的應(yīng)用配置獲取dubbo.protocols.的配置項(xiàng)值添加到configedProtocols
③、用恨憎,號(hào)join所有的protocol(configedProtocols)蕊退,并賦值給protocolIds
④、如果protocolIds為空憔恳,說(shuō)明配置中心沒(méi)有配置協(xié)議瓤荔,就取默認(rèn)的協(xié)議
⑤、如果配置中心配置協(xié)議(protocolIds不為空)钥组,就把從配置中心配置的協(xié)議添加到服務(wù)的協(xié)議列表中
5输硝、checkApplication
如果ApplicationConfig為空,則構(gòu)造一個(gè)ApplicationConfig
6程梦、checkRegistry
如果協(xié)議不是injvm本地協(xié)議(isOnlyInJvm)点把,則會(huì)從配置中心獲取Registry配置
7橘荠、refresh 刷新配置中心配置
8、checkMetadataReport 更新MetadataReportConfig中的屬性為優(yōu)先級(jí)最高的配置
9郎逃、檢查當(dāng)前服務(wù)是不是一個(gè)泛化服務(wù)
10哥童、Local、Stub褒翰、Mock
local和stub一樣如蚜,不建議使用了。如果Local存根為true影暴,則存根類為interfaceName + "Local"错邦。如果Stub本地存根為true,則存根類為interfaceName + "Stub"
a型宙、checkStubAndLocal
org.apache.dubbo.config.AbstractInterfaceConfig#checkStubAndLocal
b撬呢、checkMock
服務(wù)導(dǎo)出
doExport
org.apache.dubbo.config.ServiceConfig#doExport
unexported表示:當(dāng)前服務(wù)已經(jīng)被取消了,就不需要再導(dǎo)出了
exported表示:已經(jīng)導(dǎo)出了妆兑,就不再重復(fù)導(dǎo)出了
1魂拦、doExportUrls
org.apache.dubbo.config.ServiceConfig#doExportUrls
①、registryURLs
注冊(cè)服務(wù)也是一個(gè)服務(wù)搁嗓,也會(huì)有對(duì)應(yīng)的url芯勘,通過(guò)調(diào)用該url可以完成服務(wù)注冊(cè)
registry://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=dubbo-demo-provider1-application&dubbo=2.0.2&logger=log4j&pid=3384®istry=zookeeper&release=2.7.0×tamp=1595994447689
②、遍歷protocols協(xié)議
pathKey = group/應(yīng)用名/path服務(wù)名:version
例如:mygroup/dubbo-demo/org.apache.dubbo.demo.DemoService:1.0.1
ProviderMethodModel表示某一個(gè)方法腺逛、方法名所屬的服務(wù)的荷愕,包含實(shí)現(xiàn)類,接口棍矛,以及接口中的各個(gè)方法
ApplicationModel表示應(yīng)用中有哪些服務(wù)提供者和引用了哪些服務(wù)
每種協(xié)議都會(huì)導(dǎo)出一個(gè)單獨(dú)的服務(wù)安疗,并注冊(cè)到各個(gè)注冊(cè)中心
2、doExportUrlsFor1Protocol
org.apache.dubbo.config.ServiceConfig#doExportUrlsFor1Protocol
protocolConfig表示協(xié)議配置够委,registryURLs表示所有的注冊(cè)中心URL
①荐类、如果配置的協(xié)議沒(méi)有配置name,則默認(rèn)為dubbo
②茁帽、map表示服務(wù)url的參數(shù)玉罐,包括監(jiān)控中心、應(yīng)用潘拨、模塊吊输、提供者、協(xié)議战秋、 服務(wù)本身
③璧亚、methods方法參數(shù)處理
④讨韭、METHODS_KEY = methods 參數(shù)添加
⑤脂信、Token參數(shù)
是為了防止服務(wù)被消費(fèi)者直接調(diào)用(偽造http請(qǐng)求)
⑥癣蟋、獲取服務(wù)URL 可以通過(guò)獲取的host和port訪問(wèn)該服務(wù)
服務(wù)url
dubbo://192.168.7.81:20881/org.apache.dubbo.demo.DemoService?anyhost=true&application=dubbo-demo-provider1-application&bean.name=ServiceBean:org.apache.dubbo.demo.DemoService&bind.ip=192.168.7.81&bind.port=20881&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.demo.DemoService&logger=log4j&methods=sayHello&pid=3384&release=2.7.0&side=provider×tamp=1595995315282
⑦、scope導(dǎo)出方式(scope=null進(jìn)行遠(yuǎn)程導(dǎo)出)
scope取值是:null狰闪、remote疯搅、 local、none
如果scope為none,則不會(huì)進(jìn)行任何的服務(wù)導(dǎo)出埋泵,既不會(huì)遠(yuǎn)程幔欧,也不會(huì)本地
如果scope不是remote,則會(huì)進(jìn)行本地導(dǎo)出,會(huì)把當(dāng)前url的protocol改為injvm丽声,然后進(jìn)行導(dǎo)出
如果scope不是local,則會(huì)進(jìn)行遠(yuǎn)程導(dǎo)出
如果是injvm礁蔗,則不需要進(jìn)行注冊(cè)中心注冊(cè)
⑧、為服務(wù)url添加dynamic雁社、monitor浴井、proxy參數(shù),如果存在的話
如果有注冊(cè)中心霉撵,則將服務(wù)注冊(cè)到注冊(cè)中心
⑨磺浙、生成Invoker代理對(duì)象
Invoker 是實(shí)體域,它是 Dubbo 的核心模型徒坡,它代表一個(gè)可執(zhí)行體撕氧,可向它發(fā)起 invoke 調(diào)用。可參考官網(wǎng)架構(gòu)設(shè)計(jì)領(lǐng)域模型
a喇完、生成一個(gè)當(dāng)前服務(wù)接口的代理對(duì)象invoker伦泥。使用代理(默認(rèn)使用javassist)生成一個(gè)Invoker,Invoker表示服務(wù)提供者的代理锦溪,可以使用Invoker的invoke方法執(zhí)行服務(wù)
參數(shù)包含:服務(wù)的實(shí)現(xiàn)者ref=DemoServiceImpl奄喂、服務(wù)接口類interfaceClass=DemoService、服務(wù)的注冊(cè)地址url是
registry://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=dubbo-demo-provider1-application&dubbo=2.0.2&export=dubbo%3A%2F%2F192.168.7.81%3A20881%2Forg.apache.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddubbo-demo-provider1-application%26bean.name%3DServiceBean%3Aorg.apache.dubbo.demo.DemoService%26bind.ip%3D192.168.7.81%26bind.port%3D20881%26deprecated%3Dfalse%26dubbo%3D2.0.2%26dynamic%3Dtrue%26generic%3Dfalse%26interface%3Dorg.apache.dubbo.demo.DemoService%26logger%3Dlog4j%26methods%3DsayHello%26pid%3D4824%26release%3D2.7.0%26side%3Dprovider%26timestamp%3D1596073850978&logger=log4j&pid=4824®istry=zookeeper&release=2.7.0×tamp=1596073850955
生成的注冊(cè)服務(wù)URL是在registryURL和export參數(shù)是服務(wù)url的拼裝
b海洼、DelegateProviderMetaDataInvoker也表示服務(wù)提供者跨新,包括了Invoker和服務(wù)的配置。是對(duì)Invoker的包裹
c坏逢、protocol.export(wrapperInvoker)這是導(dǎo)出的核心域帐,使用了SPI。
使用特定的協(xié)議來(lái)對(duì)服務(wù)進(jìn)行導(dǎo)出是整,這里的協(xié)議是registry肖揣,導(dǎo)出成功后得到一個(gè)Exporter
由于注冊(cè)地址也是服務(wù),所以會(huì)先使用RegistryProtocol進(jìn)行服務(wù)注冊(cè)(服務(wù)導(dǎo)出)浮入,然后注冊(cè)(服務(wù)導(dǎo)出)完了之后龙优,再使用DubboProtocol進(jìn)行導(dǎo)出
自適應(yīng)SPI會(huì)獲取url
org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker#getUrl
⑩、當(dāng)存在注冊(cè)中心時(shí)事秀,是先使用Registy協(xié)議注冊(cè)服務(wù)彤断,然后在使用Http協(xié)議導(dǎo)出服務(wù)野舶。而沒(méi)有注冊(cè)中心時(shí),是直接使用Http協(xié)議導(dǎo)出服務(wù)宰衙。根據(jù)服務(wù)url平道,講服務(wù)的元信息存入元數(shù)據(jù)中心MetadataReportService
export
RegistryProtocol被ProtocolFilterWrapper包裹,ProtocolFilterWrapper被ProtocolListenerWrapper包裹(SPI原理)
RegistryProtocol
1供炼、export
org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper#export
如果協(xié)議是REGISTRY_PROTOCOL(registry)則會(huì)直接走到下一個(gè)protocol實(shí)現(xiàn)類ProtocolFilterWrapper一屋。
如果不是則會(huì)使用ListenerExporterWrapper處理
2、export
org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper#export
ProtocolFilterWrapper導(dǎo)出同樣的道理袋哼,如果是registry則會(huì)直接走到下一個(gè)冀墨。如果不是,則會(huì)調(diào)用buildInvokerChain構(gòu)建執(zhí)行代理鏈
3涛贯、export
org.apache.dubbo.registry.integration.RegistryProtocol#export
①轧苫、獲取registryUrl 將registry://xxx?xx=xx®istry=zookeeper 轉(zhuǎn)為 zookeeper://xx
zookeeper://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=dubbo-demo-provider1-application&dubbo=2.0.2&export=dubbo%3A%2F%2F192.168.7.81%3A20881%2Forg.apache.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddubbo-demo-provider1-application%26bean.name%3DServiceBean%3Aorg.apache.dubbo.demo.DemoService%26bind.ip%3D192.168.7.81%26bind.port%3D20881%26deprecated%3Dfalse%26dubbo%3D2.0.2%26dynamic%3Dtrue%26generic%3Dfalse%26interface%3Dorg.apache.dubbo.demo.DemoService%26logger%3Dlog4j%26methods%3DsayHello%26pid%3D1072%26release%3D2.7.0%26side%3Dprovider%26timestamp%3D1596076187605&logger=log4j&pid=1072&release=2.7.0×tamp=1596076187072
②、獲取providerUrl 服務(wù)提供者url
dubbo://192.168.7.81:20881/org.apache.dubbo.demo.DemoService?anyhost=true&application=dubbo-demo-provider1-application&bean.name=ServiceBean:org.apache.dubbo.demo.DemoService&bind.ip=192.168.7.81&bind.port=20881&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.demo.DemoService&logger=log4j&methods=sayHello&pid=1072&release=2.7.0&side=provider×tamp=1596076187605
③疫蔓、生成overrideSubscribeUrl含懊,與監(jiān)聽(tīng)有關(guān)
在服務(wù)提供者url的基礎(chǔ)上,生成一個(gè)overrideSubscribeUrl衅胀,協(xié)議為provider://岔乔,增加參數(shù)category=configurators&check=false
overrideSubscribeUrl是用來(lái)對(duì)動(dòng)態(tài)配置監(jiān)聽(tīng)的,需要監(jiān)聽(tīng)的服務(wù)和監(jiān)聽(tīng)的類型(configurators滚躯, 老版本)
一個(gè)overrideSubscribeUrl對(duì)應(yīng)一個(gè)OverrideListener雏门,用來(lái)監(jiān)聽(tīng)overrideSubscribeUrl變化事件
provider://192.168.7.81:20881/org.apache.dubbo.demo.DemoService?anyhost=true&application=dubbo-demo-provider1-application&bean.name=ServiceBean:org.apache.dubbo.demo.DemoService&bind.ip=192.168.7.81&bind.port=20881&category=configurators&check=false&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.demo.DemoService&logger=log4j&methods=sayHello&pid=1072&release=2.7.0&side=provider×tamp=1596076187605
④、doLocalExport導(dǎo)出
此時(shí)服務(wù)協(xié)議是dubbo掸掏,DubboProtocol被ProtocolFilterWrapper包裹茁影,ProtocolFilterWrapper被ProtocolListenerWrapper包裹
DubboProtocol
1、export
org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper#export
返回結(jié)果被ListenerExporterWrapper包裹
2丧凤、export
org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper#export
①霹抛、buildInvokerChain
org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper#buildInvokerChain
根據(jù)url獲取filter年碘,根據(jù)url中的parameters匹配key所對(duì)應(yīng)的filter,也會(huì)匹配group
EchoFilter、ClassLoaderFilter余掖、GenericFilter作谭、ContextFilter硼讽、TraceFilter捉偏、TimeoutFilter、MonitorFilter农渊、ExceptionFilter
返回包裹了Filter的CallbackRegistrationInvoker
3患蹂、export
org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol#export
獲取url、獲取key、isStubSupportEvent=false传于、isCallbackservice=false
開(kāi)啟Server囱挑。dubbo協(xié)議是NettyServer。dubbo協(xié)議的mina,netty格了,http協(xié)議的jetty,servlet等看铆,默認(rèn)為netty
org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol#createServer
其中創(chuàng)建Server徽鼎,最重要的是通過(guò)url綁定端口盛末,和對(duì)應(yīng)的請(qǐng)求處理器。requestHandler是請(qǐng)求處理器否淤,類型為ExchangeHandler悄但。表示從url的端口接收到請(qǐng)求后,requestHandler來(lái)進(jìn)行處理
4石抡、register
org.apache.dubbo.registry.integration.RegistryProtocol#export
在調(diào)用doLocalExport方法進(jìn)入DubboProtocol協(xié)議開(kāi)啟Server之后檐嚣,便會(huì)調(diào)用RegistryProtocol的register注冊(cè)到注冊(cè)中心zookeeper中
registry表示注冊(cè)中心,registeredProviderUrl表示存入到注冊(cè)中心去的providerUrl,會(huì)對(duì)其中的參數(shù)進(jìn)行簡(jiǎn)化
providerInvokerWrapper表示服務(wù)提供者Invoker啰扛、該服務(wù)對(duì)應(yīng)的注冊(cè)中心地址嚎京、簡(jiǎn)化后的服務(wù)registeredProviderUrl的包裝類
①、register
org.apache.dubbo.registry.integration.RegistryProtocol#register
②隐解、register
org.apache.dubbo.registry.support.FailbackRegistry#register
③鞍帝、doRegister
調(diào)用zkClient.create,注冊(cè)到zookeeper中
動(dòng)態(tài)配置監(jiān)聽(tīng)
在服務(wù)導(dǎo)出過(guò)程中煞茫,需要對(duì)動(dòng)態(tài)配置中心的數(shù)據(jù)進(jìn)行監(jiān)聽(tīng)帕涌。如果發(fā)生更改,可以及時(shí)做出反映续徽。
這里用到了Zookeeper的Watcher機(jī)制蚓曼。
1、配置中心的路徑與動(dòng)態(tài)配置路徑是不相同的钦扭,這里需要區(qū)分開(kāi)來(lái)
配置中心的路徑是:
①纫版、應(yīng)用:/dubbo/config/dubbo/org.apache.dubbo.demo.DemoService/dubbo.properties節(jié)點(diǎn)的內(nèi)容
②、全局:/dubbo/config/dubbo/dubbo.properties節(jié)點(diǎn)的內(nèi)容
2客情、對(duì)于動(dòng)態(tài)配置的監(jiān)聽(tīng)有版本的差別
在2.7之前捎琐,只可以對(duì)單個(gè)服務(wù)進(jìn)行監(jiān)聽(tīng),不可以對(duì)應(yīng)用監(jiān)聽(tīng)
/dubbo/org.apache.dubbo.demo.DemoService/configurators/* 只對(duì)路徑名字監(jiān)聽(tīng)裹匙,不監(jiān)聽(tīng)內(nèi)容
在2.7之后瑞凑,服務(wù)和應(yīng)用都可以監(jiān)聽(tīng)
服務(wù): /dubbo/config/dubbo/org.apache.dubbo.demo.DemoService.configurators 節(jié)點(diǎn)的內(nèi)容
應(yīng)用: /dubbo/config/dubbo/dubbo-demo-provider-application.configurators 節(jié)點(diǎn)的內(nèi)容
3、監(jiān)聽(tīng)時(shí)機(jī)RegistryProtocol#export
org.apache.dubbo.registry.integration.RegistryProtocol#export
2.6之后版本監(jiān)聽(tīng)器原理
0概页、overrideUrlWithConfig
org.apache.dubbo.registry.integration.RegistryProtocol#overrideUrlWithConfig
providerConfigurationListener是RegistryProtocol的一個(gè)屬性值籽御,在創(chuàng)建RegistryProtocol類時(shí),便會(huì)得到這個(gè)應(yīng)用配置的監(jiān)聽(tīng)器
1、ProviderConfigurationListener 應(yīng)用監(jiān)聽(tīng)器
應(yīng)用配置技掏,providerConfigurationListener是在屬性那里直接初始化好的铃将,providerConfigurationListener會(huì)監(jiān)聽(tīng)配置中心的應(yīng)用配置信息變動(dòng)
org.apache.dubbo.registry.integration.RegistryProtocol.ProviderConfigurationListener#ProviderConfigurationListener
org.apache.dubbo.registry.integration.AbstractConfiguratorListener#initWith
①、獲取dynamicConfiguration
②哑梳、指定路徑添加監(jiān)聽(tīng)器addListener
org.apache.dubbo.configcenter.DynamicConfiguration#addListener
org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfiguration#addListener
③劲阎、獲取路徑getPathKey
org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfiguration#getPathKey
所以,key值是dubbo-demo-provider1-application.configurators的監(jiān)聽(tīng)路徑是
/dubbo/config/dubbo/dubbo-demo-provider1-application.configurators
rawConfig表示從配置中心獲取當(dāng)前應(yīng)用的動(dòng)態(tài)配置數(shù)據(jù)鸠真,如果存在應(yīng)用配置信息則根據(jù)配置信息生成Configurator
④悯仙、genConfiguratorsFromRawRule
org.apache.dubbo.registry.integration.AbstractConfiguratorListener#genConfiguratorsFromRawRule
先把應(yīng)用或服務(wù)配置轉(zhuǎn)成url,再根據(jù)url生成對(duì)應(yīng)的Configurator
2吠卷、ServiceConfigurationListener 服務(wù)監(jiān)聽(tīng)器
ServiceConfigurationListener會(huì)監(jiān)聽(tīng)配置中心的服務(wù)信息配置信息變動(dòng)锡垄,每注冊(cè)一個(gè)服務(wù)都會(huì)生成一個(gè)服務(wù)監(jiān)聽(tīng)器
org.apache.dubbo.registry.integration.RegistryProtocol.ServiceConfigurationListener#ServiceConfigurationListener
org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfiguration#getPathKey
key是org.apache.dubbo.demo.DemoService::.configurators,得到的監(jiān)聽(tīng)路徑是/dubbo/config/dubbo/org.apache.dubbo.demo.DemoService::.configurators
3祭隔、把服務(wù)監(jiān)聽(tīng)添加到serviceConfigurationListeners集合中
2.6以及之前版本監(jiān)聽(tīng)器原理
org.apache.dubbo.registry.support.FailbackRegistry#subscribe
org.apache.dubbo.registry.zookeeper.ZookeeperRegistry#doSubscribe
進(jìn)行訂閱货岭,先看父類的subscribe方法。訂閱所有服務(wù)
單獨(dú)訂閱某一個(gè)服務(wù)疾渴,根據(jù)監(jiān)聽(tīng)地址去拿listeners千贯,如果沒(méi)有則生成
添加跟zookeeper相關(guān)的ChildListener
這里的urls就是從現(xiàn)在所引入的服務(wù)的目錄下查到的url,比如下面這個(gè)三個(gè)目錄下的路徑(這里會(huì)在服務(wù)引入時(shí)搞坝,有這些值)
/dubbo/org.apache.dubbo.demo.DemoService/providers
/dubbo/org.apache.dubbo.demo.DemoService/configurators
/dubbo/org.apache.dubbo.demo.DemoService/routers
OverrideListener觸發(fā)
OverrideListener實(shí)現(xiàn)了NotifyListener搔谴,OverrideListener訂閱的subscribeUrl發(fā)生改變OverrideListener將會(huì)接收到通知
1、notify
org.apache.dubbo.registry.integration.RegistryProtocol.OverrideListener#notify
對(duì)發(fā)生了變化的url進(jìn)行過(guò)濾瞄沙,只獲取url是override協(xié)議或參數(shù)category=onfigurators的url
根據(jù)Override協(xié)議修改
2己沛、doOverrideIfNecessary
org.apache.dubbo.registry.integration.RegistryProtocol.OverrideListener#doOverrideIfNecessary
根據(jù)configurators修改url
修改過(guò)的newUrl和目前的currentUrl不相同,則重新按newUrl導(dǎo)出
3距境、reExport
org.apache.dubbo.registry.integration.RegistryProtocol#reExport
根據(jù)newInvokerUrl獲取exporter進(jìn)行導(dǎo)出申尼、得到最新的注冊(cè)registryUrl。如果新的服務(wù)url和這個(gè)服務(wù)之前的服務(wù)url不相等垫桂,則需要把新的服務(wù)url注冊(cè)到注冊(cè)中心师幕。
4、process
ProviderConfigurationListener和ServiceConfigurationListener都實(shí)現(xiàn)了AbstractConfiguratorListener诬滩,所以如果配置發(fā)生了改變將會(huì)觸發(fā)org.apache.dubbo.registry.integration.AbstractConfiguratorListener#process方法
org.apache.dubbo.registry.integration.RegistryProtocol.OverrideListener#doOverrideIfNecessary
會(huì)調(diào)用子類doOverrideIfNecessary方法
Exporter結(jié)構(gòu)
org.apache.dubbo.registry.integration.RegistryProtocol#doLocalExport調(diào)用之后得到的exporter從外到內(nèi)依次是
RegistryProtocol$ExporterChangeableWrapper霹粥、ListenerExporterWrapper、DubboExporter
在org.apache.dubbo.registry.integration.RegistryProtocol#export返回結(jié)果又被DestroyableExporter包裹疼鸟。
1后控、DestroyableExporter
org.apache.dubbo.registry.integration.RegistryProtocol.DestroyableExporter#unexport
2、ExporterChangeableWrapper
org.apache.dubbo.registry.integration.RegistryProtocol.ExporterChangeableWrapper#unexport
從注冊(cè)中心刪除服務(wù)URL空镜、解綁當(dāng)前服務(wù)的監(jiān)聽(tīng)器Listener
3浩淘、ListenerExporterWrapper
org.apache.dubbo.rpc.listener.ListenerExporterWrapper#unexport
在unexport對(duì)應(yīng)服務(wù)之后捌朴,把服務(wù)監(jiān)聽(tīng)器移除
4、AbstractExporter
org.apache.dubbo.rpc.protocol.AbstractExporter#unexport
這幾個(gè)Exporter主要在于getInvoker和unexport方法
總結(jié):
dubbo服務(wù)導(dǎo)出的核心就是根據(jù)各種位置的配置構(gòu)建服務(wù)url张抄,并注冊(cè)到注冊(cè)中心砂蔽。
還有一點(diǎn)是服務(wù)導(dǎo)出生成的Export結(jié)構(gòu)是為了服務(wù)消費(fèi)端進(jìn)行調(diào)用的。
其中署惯,開(kāi)啟服務(wù)也是為了與服務(wù)消費(fèi)端進(jìn)行調(diào)用信息的傳輸左驾。