Motan 優(yōu)雅關(guān)機(jī)

在寫start-motan時(shí),已經(jīng)加入自動(dòng)注冊的功能,自然要考慮服務(wù)下線的功能,其在github上也寫如何優(yōu)化關(guān)機(jī),下面嘗試在start中加入該功能。

官方說:待關(guān)閉節(jié)點(diǎn)需要調(diào)用以下代碼,建議通過servlet或業(yè)務(wù)的管理模塊進(jìn)行該調(diào)用。

MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true)

同時(shí)官方在注解的例子中說:在使用注冊中心時(shí)要主動(dòng)調(diào)用下面代碼:

MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true);

注冊和反注冊調(diào)用的兩段代碼一樣....

進(jìn)去翻了下代碼,總嚼著反注冊怎么著也要傳個(gè)false進(jìn)來

    public void onValueChanged(String key, Boolean value) {
        if (key != null && value != null) {
             if (value) {  // 傳入值為true時(shí)執(zhí)行
                 available(null);
             } else {  // 傳入值為false時(shí)執(zhí)行
                 unavailable(null);
             }
         }
     }
    // 最終的操作
    @Override
    protected void doAvailable(URL url) {
        try{
            serverLock.lock();
            if (url == null) {
                availableServices.addAll(getRegisteredServiceUrls());
                for (URL u : getRegisteredServiceUrls()) {
                    removeNode(u, ZkNodeType.AVAILABLE_SERVER);
                    removeNode(u, ZkNodeType.UNAVAILABLE_SERVER);
                    createNode(u, ZkNodeType.AVAILABLE_SERVER);
                }
            } else {
                availableServices.add(url);
                removeNode(url, ZkNodeType.AVAILABLE_SERVER);
                removeNode(url, ZkNodeType.UNAVAILABLE_SERVER);
                createNode(url, ZkNodeType.AVAILABLE_SERVER);
            }
        } finally {
            serverLock.unlock();
        }
    }

    @Override
    protected void doUnavailable(URL url) {
        try{
            serverLock.lock();
            if (url == null) {
                availableServices.removeAll(getRegisteredServiceUrls());
                for (URL u : getRegisteredServiceUrls()) {
                    removeNode(u, ZkNodeType.AVAILABLE_SERVER);
                    removeNode(u, ZkNodeType.UNAVAILABLE_SERVER);
                    createNode(u, ZkNodeType.UNAVAILABLE_SERVER);
                }
            } else {
                availableServices.remove(url);
                removeNode(url, ZkNodeType.AVAILABLE_SERVER);
                removeNode(url, ZkNodeType.UNAVAILABLE_SERVER);
                createNode(url, ZkNodeType.UNAVAILABLE_SERVER);
            }
        } finally {
            serverLock.unlock();
        }
    }

下面測試下不同的傳值的實(shí)際結(jié)果
先加入一個(gè)關(guān)閉回調(diào),加個(gè)斷點(diǎn)。

   Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
     try {
MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, false);
     } catch (Exception e) {
      e.printStackTrace();
     }
    }
   });

通過測試,無論傳入的是true,還是false,服務(wù)都取消了。
只要執(zhí)行這個(gè)命令kill pid,即使不執(zhí)行setSwitcherValue方法,暴露的服務(wù)也給反注冊了。
查看zk命令行:

// 服務(wù)剛啟動(dòng)時(shí)
[zk: localhost:2181(CONNECTED) 24] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
[192.168.1.100:8888]
// 執(zhí)行 kill pid時(shí),注冊的服務(wù)直接消失
[zk: localhost:2181(CONNECTED) 25] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
[]

為啥會(huì)這樣?看打印信息是從spring發(fā)起的,后續(xù)看這塊代碼時(shí)再研究下。

到這的話,優(yōu)雅關(guān)機(jī)也能實(shí)現(xiàn)了。
kill pid時(shí),處理下線程池等相關(guān)的關(guān)閉;再獲取到本服務(wù)內(nèi)的剩余調(diào)用數(shù),等待現(xiàn)有的請(qǐng)求處理完。不知道Motan是否有直接拿到調(diào)用數(shù)的功能,還沒看管理后臺(tái)。


只是,通過這種方式關(guān)閉服務(wù),跟蹤代碼在doUnavailable方法中實(shí)際并未執(zhí)行任何有效代碼,所以還是按照官方說明的方法測試一下「建議通過servlet或業(yè)務(wù)的管理模塊進(jìn)行該調(diào)用」

偷個(gè)懶,來個(gè)一錘子買賣,在原有代碼中加點(diǎn)料,調(diào)用服務(wù)時(shí),先反注冊,然后再返回結(jié)果:

 public String say(String val) {
  MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, false);
  return "hello " + val;
 }

先上結(jié)果:

  • 傳true,該服務(wù)可多次正常調(diào)用,毫無問題
// 服務(wù)啟動(dòng)時(shí)
[zk: localhost:2181(CONNECTED) 27] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
[192.168.1.100:8888]
// 調(diào)用setSwitcherValue后(傳值為true)
[zk: localhost:2181(CONNECTED) 28] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
[192.168.1.100:8888]
  • 傳false,該服務(wù)可多次正常調(diào)用,毫無問題
// 服務(wù)啟動(dòng)時(shí)
[zk: localhost:2181(CONNECTED) 29] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
[192.168.1.100:8888]
// 調(diào)用setSwitcherValue后(傳值為false)
[zk: localhost:2181(CONNECTED) 30] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
[]

從結(jié)果可以看出來,優(yōu)雅關(guān)閉服務(wù),是需要傳入false的,這個(gè)應(yīng)該是官方文檔寫錯(cuò)了。
只是,在服務(wù)已消失的情況下,客戶端依然可以發(fā)起請(qǐng)求,并能正常收到結(jié)果。按我理解應(yīng)該是收到不到結(jié)果才對(duì),畢竟只配了一個(gè)服務(wù),該服務(wù)下線應(yīng)通知客戶端該服務(wù)不可用的,實(shí)際上還能使用,這是為什么....

然后又啟動(dòng)一個(gè)客戶端,此時(shí)報(bào)錯(cuò)了error_message: ClusterSupport No service urls for the refer,對(duì)于這個(gè)結(jié)果沒有任何問題,畢竟已無服務(wù)了。


難道是只有一個(gè)服務(wù)它就不通知了?那就啟動(dòng)兩個(gè)服務(wù),其中一個(gè)服務(wù)調(diào)用后反注冊,另一個(gè)不做處理,并且打印不同的消息以確定是哪個(gè)服務(wù)響應(yīng)。

// 啟動(dòng)兩個(gè)服務(wù)
[zk: localhost:2181(CONNECTED) 32] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
[192.168.1.100:8888, 192.168.1.103:8888]

通過調(diào)用測試,當(dāng)其中一個(gè)服務(wù)反注冊后,后面的請(qǐng)求均發(fā)送到正常的服務(wù)器,也意味著,反注冊后的服務(wù)是不會(huì)再收到客戶端請(qǐng)求的。(只有一個(gè)服務(wù)時(shí)無論是否反注冊依然會(huì)收到請(qǐng)求)


  • addShutdownHook,命令行關(guān)服務(wù)
  • 通過jmx對(duì)外暴露
  • 通過http等方法

綜合還是使用前兩個(gè)來實(shí)現(xiàn),命令行也要能優(yōu)雅關(guān)機(jī),然后也可通過jmx遠(yuǎn)程優(yōu)雅關(guān)機(jī)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 概述 一個(gè)第三方的分布式服務(wù)程序, 為別的分布式程序服務(wù),存儲(chǔ)的都是狀態(tài)數(shù)據(jù) 數(shù)據(jù)保管(分布式中每一臺(tái)的狀態(tài)...
    如果仲有聽日閱讀 1,518評(píng)論 2 0
  • 一、Nginx/keepalived/lvs的介紹 1.nginx 1.1.nginx簡介 Nginx是一個(gè)自由、...
    Java幫幫閱讀 1,625評(píng)論 0 5
  • ... 一、相關(guān)概念 中間件:為分布式系統(tǒng)提供協(xié)調(diào)服務(wù)的組件,如專門用于計(jì)算服務(wù)的機(jī)器就是一個(gè)計(jì)算型中間件,還有專...
    帥可兒妞閱讀 554評(píng)論 0 0
  • 加油親愛的自己,今天在回來的車上悟到一句話“這人生呀,其實(shí)就是一場科目二考試,到什么點(diǎn)干什么,否則下一場重來”。明...
    211_e40c閱讀 329評(píng)論 0 0
  • DAY1 《親密關(guān)系》 一、親密關(guān)系的本質(zhì) 二、月暈現(xiàn)象 1. 吸引磁場 2. 期望與要求 三、幻滅階段 1. 偏...
    以后2019閱讀 261評(píng)論 0 0

友情鏈接更多精彩內(nèi)容