深度解析dubbo在线运维Qos
文章目錄
-
-
- 1. dubbo的Qos
- 2.dubbo Qos簡單使用
-
- 2.1 ls
- 2.2 online
- 2.3 offline
- 2.4 help
- 2.5 quit
- 3.dubbo Qos 源碼剖析
-
- 3.1 Qos服務(wù)器創(chuàng)建時(shí)機(jī)
- 3.2 QosProtocolWrapper
- 3.3 com.alibaba.dubbo.qos.server.Server
- 3.4 com.alibaba.dubbo.qos.server.handler.QosProcessHandler
- 3.4 BaseCommand
-
- 3.4.1 ls
- 3.4.2 online
- 3.4.3 offline
- 3.4.4 help
- 3.4.5 quit
- 4.總結(jié)
-
注:本文基于dubbo v2.6.1
1. dubbo的Qos
QoS的英文全稱為"Quality of Service",中文名為"服務(wù)質(zhì)量"。在dubbo 2.5.8 新版本增加了 QOS 模塊,提供了新的 telnet 命令支持。dubbo管它叫在線運(yùn)維命令,我們可以通過它能夠看到服務(wù)提供者狀態(tài),服務(wù)調(diào)用者狀態(tài),現(xiàn)在dubbo提供了 ls , online,offline,help ,quit命令。
命令
用途
ls
能夠列出來該實(shí)例服務(wù)提供者與調(diào)用者狀態(tài)
online
服務(wù)上線,可以指定某個(gè)接口,也可以什么也不指定,這樣就是全部
offline
服務(wù)下線,可以指定某個(gè)接口,也可以什么也不指定,這樣就是全部
help
查看命令的用途,不帶參數(shù)顯示全部命令,帶參數(shù)只顯示指定的
quit
退出Qos
2.dubbo Qos簡單使用
我們可以在dubbo的配置文件配置參數(shù),我這里是使用的xml的形式,其他形式可以看下官網(wǎng)文檔:官網(wǎng)文檔(文檔講的很詳細(xì),而且是中文)
<dubbo:application name="dubbo-consumer"><dubbo:parameter key="qos.enable" value="true"/><dubbo:parameter key="qos.accept.foreign.ip" value="false"/><dubbo:parameter key="qos.port" value="8108"/> </dubbo:application>qos.enable :表示是否開始Qos
qos.accept.foreign.ip: 允許訪問的ip,缺省就是false,表示任何ip都可訪問
qos.port: Qos提供服務(wù)的端口
接下來我啟動(dòng)服務(wù),然后在終端上使用telnet的方式連接dubbo Qos
2.1 ls
可以看到服務(wù)提供服務(wù)與調(diào)用服務(wù)的狀態(tài)
這個(gè) Provider Service Name 就是服務(wù)提供者名字 , PUB 就是狀態(tài) N是未注冊,就是沒有注冊到注冊中心,其實(shí)服務(wù)下線功能就是從注冊中心unregister ,Y表示服務(wù)在線,就是注冊到注冊中心了。
2.2 online
服務(wù)上線,就是將服務(wù)注冊到注冊中心上去,后面可以帶個(gè)參數(shù),參數(shù)是指定具體上線的接口,不帶參數(shù)表示全部服務(wù)接口(這個(gè)得是你標(biāo)識(shí)的,比如說使用了dubbo @Service注解)都注冊到注冊中心去。
我們ls小節(jié)的時(shí)候可以看到com.xuzhaocai.dubbo.provider.IUserInfoService 是N,我們可以使用online來進(jìn)行服務(wù)上線
我們可以看到服務(wù)狀態(tài)是Y了,這其實(shí)就是注冊中心 調(diào)用register(),我們在后面可以看到具體代碼實(shí)現(xiàn)。
2.3 offline
offline 是服務(wù)下線,跟online一個(gè)使用方法,這里就不再贅述了。
2.4 help
幫助,可以指定具體的cmd,這樣就顯示指定cmd的幫助
不指定的話顯示全部的命令
2.5 quit
退出Qos,你不用這個(gè)quit可以試試,看看能不能退出去,我mac直接使用ctrl+c 反正不行。
注: 我這里就不再詳細(xì)說明這個(gè)用法了,這東西官網(wǎng)文檔很詳細(xì),而且使用也簡單,主要是場景 ,直接源碼搞起
3.dubbo Qos 源碼剖析
3.1 Qos服務(wù)器創(chuàng)建時(shí)機(jī)
其實(shí)在dubbo進(jìn)行服務(wù)暴露與服務(wù)引用的時(shí)候,我們都見過Exporter<?> exporter = protocol.export(wrapperInvoker); (com.alibaba.dubbo.config.ServiceConfig#doExportUrlsFor1Protocol)或者refprotocol.refer(interfaceClass, urls.get(0));(com.alibaba.dubbo.config.ReferenceConfig#createProxy) ,我們知道這個(gè)protocol成員是這個(gè)樣子
根據(jù)dubbo spi 自適應(yīng)的規(guī)則,實(shí)際上執(zhí)行的是 url中protocol 參數(shù)值對(duì)應(yīng)的那個(gè)實(shí)現(xiàn)類,我們這個(gè)場景下就是RegistryProtocol 實(shí)現(xiàn)類,然后dubbo spi 還會(huì)幫你setter 注入 ,wrapper 包裝
我們可以看下都有哪些Protocol 包裝實(shí)現(xiàn)類
v2.6.1 這個(gè)版本就這些。
我們獲得的RegistryProtocol對(duì)象,其實(shí)外面是包了這幾個(gè)wrapper類,就像下圖這個(gè)樣子(當(dāng)然這個(gè)順序不一定是這個(gè)樣子的,他這邊沒有對(duì)順序做要求)
所以我們在服務(wù)暴露或者服務(wù)引用的時(shí)候,就會(huì)走這個(gè)QosProtocolWrapper類。
3.2 QosProtocolWrapper
我們可以看到export與refer方法,判斷如果protocol=registry,接著進(jìn)入這個(gè)startQosServer(url)
看下這 startQosServer方法。
這個(gè)方法中我們可以看到就是判斷qos.enable 啟動(dòng)參數(shù),然后 判斷是否已經(jīng)啟動(dòng),這個(gè)玩意一個(gè)服務(wù)實(shí)例就只能啟動(dòng)一次,再就是獲得一個(gè)Server對(duì)象,將用戶設(shè)置的一些參數(shù)值設(shè)置進(jìn)去,然后調(diào)用start方法。
我們來看下這個(gè)Server類
3.3 com.alibaba.dubbo.qos.server.Server
我們這里是創(chuàng)建了一個(gè)netty的server,開始的時(shí)候使用cas判斷啟動(dòng)狀態(tài),添加了一個(gè)QosProcessHandler消息處理類,我們的命令就是到這里面處理的。我們看下這個(gè)QosProcessHandler 類,傳入?yún)?shù)就是welcome歡迎語跟允許的ip。
我們來看下的這個(gè)QosProcessHandler消息處理類
3.4 com.alibaba.dubbo.qos.server.handler.QosProcessHandler
當(dāng)消息連接上的時(shí)候,會(huì)調(diào)用channelActive方法,我們可以看到,它將這個(gè)welcome 歡迎語與 dubbo> 這個(gè)開始頭發(fā)出去了。
也就是這個(gè)東西
接著我們再輸入命令的時(shí)候,就會(huì)到decode 方法中,首先判斷buffer里面有沒有能讀的字節(jié),如果沒有直接返回,獲取一個(gè)字節(jié),判斷是不是http請(qǐng)求,因?yàn)镈ubbo Qos 是支持http 與telnet的。
這里就會(huì)相應(yīng)的添加handler,我們可以看到,他這個(gè)handler是動(dòng)態(tài)添加與刪除的,每一次訪問都要添加與刪除。
我們這里使用的是telnet ,我們看下telnet的是怎樣實(shí)現(xiàn)的,http 的也就同理了。
接下來我們看下這個(gè)TelnetProcessHandler 處理類,那四個(gè)都是netty的,做相應(yīng)輔助功能的,比如說使用行解析,使用utf-8解碼,然后空閑時(shí)間,TelnetProcessHandler 是主要處理我們命令的
這里首先判斷消息是不是空,空消息就將 dubbo>這個(gè)返回給客戶端
然后將消息解析成 CommandContext, 也就是CommandContext commandContext = TelnetCommandDecoder.decode(msg); 這句,就是將消息解析成cmd與參數(shù),調(diào)用CommandContext工廠創(chuàng)建CommandContext 對(duì)象。
接著就是使用CommandExecutor 執(zhí)行這個(gè)命令,也就是這句String result = commandExecutor.execute(commandContext);
我們來看下這個(gè)DefaultCommandExecutor的execute方法,先是通過命令獲取對(duì)應(yīng)的BaseCommand實(shí)現(xiàn)類,沒有找到對(duì)應(yīng)的話就拋出NoSuch的異常。有的話直接調(diào)用execute執(zhí)行。
這個(gè)BaseCommand我們后面再說,這個(gè)執(zhí)行結(jié)果返回,接著回到TelnetProcessHandler 的channelRead0方法中,如果這個(gè)執(zhí)行結(jié)果是close的話,就寫回"BYE! ";這個(gè)字符串,并且添加ChannelFutureListener.CLOSE 這個(gè)listener。
如果是正常執(zhí)行結(jié)果的話,寫回去就可以了。
現(xiàn)在我們來看下這個(gè)BaseCommand的定義以它的子類們
3.4 BaseCommand
這個(gè)是就是命令的接口,是基于dubbo spi的,所有Qos命令都要實(shí)現(xiàn)它,然后重寫execute方法。
看下它的實(shí)現(xiàn)類
下面我們就挨個(gè)看看
3.4.1 ls
ls 這個(gè)命令是獲取該實(shí)例服務(wù)提供者接口與調(diào)用者接口及狀態(tài)。
我們來看看代碼實(shí)現(xiàn)
調(diào)用了listProvider()獲取了服務(wù)提供者接口,調(diào)用了服務(wù)調(diào)用者接口。
我們這里拿獲取服務(wù)提供者接口看看:
這邊有兩個(gè)點(diǎn): 一個(gè)是通過ApplicationModel 獲取所有的provider,這個(gè)ApplicationModel 類,里面其實(shí)維護(hù)了幾個(gè)map,其中就有本實(shí)例服務(wù)提供者與服務(wù)調(diào)用者接口列表,當(dāng)我們在暴露服務(wù)完成的時(shí)候,就會(huì)向ApplicationModel 這個(gè)類里面添加對(duì)應(yīng)的服務(wù)提供者的信息,也就是走的這個(gè)方法
每當(dāng)我們服務(wù)引用完,創(chuàng)建完proxy代理類的時(shí)候,就會(huì)往ApplicationModel 這個(gè)類里面添加對(duì)應(yīng)的服務(wù)調(diào)用者的信息,也就是走的這個(gè)方法
所以我們就能拿到本實(shí)例的服務(wù)提供者接口了。接著往下看就是創(chuàng)建TTable ,是兩列的,然后遍歷服務(wù)提供者接口列表添加行。
到最后就是rendering 渲染了,在循環(huán)的時(shí)候其實(shí)還有一個(gè)點(diǎn),使用isReg(providerModel.getServiceName()) “Y” : “N”) 是否在線,這里面判斷的其實(shí)還是invoker包裝類的isReg,注冊到注冊中心后設(shè)置這個(gè)標(biāo)識(shí)。
同理本實(shí)例服務(wù)提供者也是這個(gè)樣子獲取的,到這里我們這個(gè)ls命令處理就完成了。
3.4.2 online
com.alibaba.dubbo.qos.command.impl.Online 服務(wù)上線。
這個(gè)online 命令使用參數(shù)的,如果用戶沒有指定,就是.*,在下面匹配上就會(huì)匹配到。
首先是判斷參數(shù),接著就是從ApplicationModel 獲取本實(shí)例服務(wù)提供者列表,遍歷,看看是否符合你傳過來的參數(shù),,符合就設(shè)置hasService = true,接著就是根據(jù)serviceName從本地注冊表中獲取對(duì)應(yīng)的ProviderInvokerWrapper列表,遍歷判斷如果對(duì)應(yīng)的狀態(tài)是在線的(這里還是判斷的isReg),就跳過,否則獲取對(duì)應(yīng)的注冊中心,進(jìn)行注冊,同時(shí)將isReg狀態(tài)設(shè)置成true。
3.4.3 offline
com.alibaba.dubbo.qos.command.impl.Offline 服務(wù)下線,我們看下代碼,它這個(gè)與online差不多,它這個(gè)循環(huán)判斷服務(wù)沒有在線就跳過去,在線的就調(diào)用注冊中心的unregister()方法進(jìn)行服務(wù)下線,同時(shí)設(shè)置isReg服務(wù)在線狀態(tài)為false。
3.4.4 help
com.alibaba.dubbo.qos.command.impl.Help 幫助文檔作用,可以傳參數(shù) 指定需要幫助的命令,也可以不指定,那就是顯示全部命令的幫助。直接上代碼
我們看下這行所有命令的,這個(gè)指定命令的原理也差不多
就是使用CommandHelper.getAllCommandClass() 獲取所有的BaseCommand 子類class對(duì)象,他這個(gè)使用dubbo spi獲取所有子類的
然后獲取子類上面的@Cmd注解,就像offline上面這個(gè),name就是命令,summary就是說明 ,example 就是列子
3.4.5 quit
com.alibaba.dubbo.qos.command.impl.Quit 退出 ,這就是直接返回了close,然后TelnetProcessHandler就會(huì)處理這個(gè)close進(jìn)行退出。
4.總結(jié)
到這里我們dubbo 在線運(yùn)維Qos 就解析完成了,概括一下,首先是講了 dubbo Qos ,然后簡單使用了一下,最后就是咱們的源碼解析了,從Qos服務(wù)器啟動(dòng)時(shí)機(jī)到每一個(gè)commad命令的執(zhí)行原理。這個(gè)Qos 使用簡單,主要還是它的使用場景,正如dubbo 官方文檔說的,服務(wù)上線 服務(wù)下線的使用場景。
總結(jié)
以上是生活随笔為你收集整理的深度解析dubbo在线运维Qos的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 晶圆凸点技术概述
- 下一篇: JS移动DOM节点,将某节点下所有子节点