Motanエレガントシャットダウン

5568 ワード

start-motanを書く際には、自動登録機能が組み込まれているので、当然サービスラインオフの機能も考慮し、githubでもシャットダウンを最適化する方法を書いているので、startにこの機能を加えてみましょう.
公式には、ノードを閉じるには以下のコードを呼び出す必要があります.servletまたはビジネスの管理モジュールで呼び出すことをお勧めします.
MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true)

また、公式は注釈の例で、登録センターを使用するときに次のコードをアクティブに呼び出すと述べています.
MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true);

登録と逆登録呼び出しの2つのコードは同じです....
中に入ってコードをひっくり返して、いつも反登録を噛んでどうしてもfalseを伝えなければなりません
    public void onValueChanged(String key, Boolean value) {
        if (key != null && value != null) {
             if (value) {  //     true   
                 available(null);
             } else {  //     false   
                 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();
        }
    }

次のテストでは、異なる伝値の実際の結果をテストし、まず閉じたコールバックを追加し、ブレークポイントを追加します.
   Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
     try {
MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, false);
     } catch (Exception e) {
      e.printStackTrace();
     }
    }
   });

テストにより、trueが送信されてもfalseが送信されても、サービスはキャンセルされました.このコマンドkill pidを実行すれば、setSwitcherValueメソッドを実行しなくても、露出したサービスは逆登録されます.zkコマンドラインを表示するには、次の手順に従います.
//       
[zk: localhost:2181(CONNECTED) 24] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
[192.168.1.100:8888]
//    kill pid ,         
[zk: localhost:2181(CONNECTED) 25] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
[]

どうしてこんなことになったの?印刷情報がspringから始まったのを見て、後でこのコードを見てから検討します.
ここまで来れば、優雅なシャットダウンも実現できますし、kill pidの場合は、シャットダウンコール方法を数秒休眠させ、既存業務が終わってからカチッとすればいいのです.あるいは、本サービス内のトラフィックスレッド数を取得し、これに基づいて閉じることができます.Motanにこの機能があるかどうかはわかりませんが、まだ管理バックグラウンドを見ていません.
ただし、このようにサービスをオフにすることで、トレースコードはdoUnavailableメソッドで実際に有効なコードが実行されていないので、公式に説明した方法で「servletまたはビジネスの管理モジュールで呼び出すことを推奨する」とテストします.
怠け者を盗んで、ハンマーで商売をして、元のコードに材料を加えて、サービスを呼び出すときは、まず逆登録してから、結果を返します.
 public String say(String val) {
  MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, false);
  return "hello " + val;
 }

先行結果:
  • はtrueを伝え、このサービスは複数回正常に呼び出すことができ、問題はありません
  • //      
    [zk: localhost:2181(CONNECTED) 27] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
    [192.168.1.100:8888]
    //   setSwitcherValue (   true)
    [zk: localhost:2181(CONNECTED) 28] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
    [192.168.1.100:8888]
    
  • はfalseを伝え、このサービスは何度も正常に呼び出すことができ、問題はありません
  • //      
    [zk: localhost:2181(CONNECTED) 29] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
    [192.168.1.100:8888]
    //   setSwitcherValue (   false)
    [zk: localhost:2181(CONNECTED) 30] ls /motan/default_rpc/com.github.chenxing2.demo.api.IMotanDemo/server
    []
    

    結果から分かるように、優雅にサービスを閉じるにはfalseに伝える必要があります.これは公式ドキュメントが間違っているはずです.ただし、サービスが消えた場合でも、クライアントはリクエストを開始し、結果を正常に受信することができます.私の理解では、结果が得られないはずです.结局、サービスは1つしかありません.このサービスは下线でクライアントにこのサービスが利用できないことを通知しなければなりません.実际にはまだ使用できます.これはなぜですか.
    次にクライアントを起動し、error_をエラーしました.Message:ClusterSupport No service urls for the refer、この結果には何の問題もありません.結局、サービスはありません.
    1つのサービスだけが通知されないのではないでしょうか.では、2つのサービスが起動され、そのうちの1つが呼び出されて逆登録され、もう1つは処理されず、どのサービス応答であるかを決定するために異なるメッセージが印刷されます.
    //       
    [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]
    

    テストを呼び出すことで、1つのサービスが逆登録されると、後続のリクエストは正常なサーバに送信されます.つまり、逆登録されたサービスはクライアントリクエストを受信しません.(1つのサービスのみの場合、逆登録の有無にかかわらずリクエストが受信されます)
  • addShutdownHook、コマンドラインオフサービス
  • jmxによる
  • の対外曝露
  • http等により
  • 統合は前の2つを使用して実現し、コマンドラインも優雅にシャットダウンし、jmxリモートで優雅にシャットダウンすることができます.