マイクロサービス分散アーキテクチャでエレガントなパブリッシングを実現するにはどうすればよいでしょうか?

この記事では主に、Spring Cloud マイクロサービス アーキテクチャでのサービス バージョンのアップグレードおよびデプロイメント プロセス中に API がエラーを報告しないようにする方法について説明します。

バックグラウンド:

1. バージョンのリリースにより現在のサービスが利用できなくなり、「システムがビジー状態です。後でもう一度お試しください」などのユーザー エクスペリエンスに影響を及ぼすヒューズ メッセージが返されます。

2. リクエストのリンクが途中で中断され、リクエストの前半のデータは正しいが、後半のデータが正しくないため、データの混乱が発生します。

3. 状況 2 によって引き起こされる問題の場合、研究開発担当者は問題の特定とデータの修復に多くの時間を費やす必要があります。

実装アイデア:

1. eureka 登録センターからリリース サービスを削除し、サービスのトラフィックがなくなってからサービスをリリースします。

2. 他のサービスをトリガーしてサービス リストを更新し、リリース サービスのリクエストを停止し、リリース サービスにトラフィックがないようにします。

3. リリース サービスが開始されたら、他のサービスをトリガーしてサービス リストを更新し、リリース サービスを要求し、リリース サービスにトラフィックを共有させます。

以下は簡単なデモの例です。B1 のバージョンをリリースしたいと考えています。

1. Eurekaのサービス発見メカニズム

まずはeurekaのサービス発見メカニズムを理解しましょう

マイクロサービスで最終的にリクエストを開始するコンポーネントはリボン (独自のサービス リストを持つ) です。バージョン サービスが eureka のデフォルトのサービス検出メカニズムに従ってリリースされる場合、0 ~ 270 秒かかり、A1 または A2 も送信しますB1 へのリクエスト、B1 はシャットダウンから再起動までの期間にリクエストを処理できないため、A1 または A2 の内部ヒューズ メカニズムがトリガーされます (「システムがビジーです。後でもう一度お試しください」など)。

リリースによって引き起こされるこの種のヒューズについては、実際にはそれを回避することができます。

2. エレガントなリリース

1. eureka から B1 を削除し、サービスにトラフィックがなくなったら B1 を解放します。

ここのB1はeurekaからは削除されていますが、B1はまだ正常に動作しており、ip+portメソッドを使ってB1のAPIを直接リクエストすれば正常に処理できます。

B1とB2はBサービスクラスタのノードであるため、B1起動後に自動的にeurekaに登録され、トラフィックを分散した後、B2に対しても同様のリリース処理を行います(サービスAのリリースも同様です)

プロセス全体を通じて、トラフィックを発生させずにサービスを再起動します。これは、マイクロサービスのリクエスト リンク全体には影響しません。

2. サービスからログオフする方法

1) readOnlyCacheMapを無効にする

eureka.server.use-read-only-response-cache: false

無効になっていない場合、通常のアクティブなオフラインは readWriteCacheMap に直接同期されますが、readOnlyCacheMap には同期されません。30 秒の差が生じる可能性があります。eureka クライアントによってプルされたサービス リストにはまだ B1 が存在し、B1 は同期できません。すぐに削除される

2) DiscoveryClient.shutdown()を実行します。

DiscoveryClient.shutdown() を呼び出して eureka からアクティブにログオフする API を定義します。

そして、MQ (ここでは Rabbitmq を使用しています) を使用して、他のすべてのサービスにブロードキャスト メッセージを送信し、このサービスがオフラインであることを他のサービスに伝え、リボン サービス リストをすぐに更新し、このサービスにリクエストを送信しないようにします。

なぜここで eureka クライアントのサービスリストを更新するのでしょうか? リボンのサービス リスト データは eureka クライアントからのサービス リストであるため (前の図を参照)

3) その他のオフライン (現時点では MQ コンシューマのみを処理する必要があります。プロジェクトで他の処理が必要な場合は、それを参照することもできます)

B1 は API リクエストを処理しなくなりましたが、B1 の MQ コンシューマは依然としてデータを消費しています。コンシューマがデータの処理を停止すると、B1 で問題が発生します。どうすればよいですか?

オフライン B1 のすべての MQ コンシューマ

4) サービスの開始後、他のサービスにサービス リストを更新するように通知し、トラフィックを迅速に取得します。

この手順は必要ありません。サービスがサービス リストを自動的に同期するまで待つこともできます。この場合、一定の遅延が発生する可能性があります。次のノードをデプロイするまで待つ必要があります。

3. アプリケーション

主に上記の /offline インターフェイスを呼び出します (同期ブロッキングを維持するようにしてください。非同期非ブロッキングに変更すると、サービスがオフラインになる前にプロセスが強制終了され、例外が発生する可能性があります)。

使用法 1: http://localhost:8881/offline を直接リクエストします。プロセスを強制終了し、応答が成功した後に再起動できます。

使用法 2: jenkins のデプロイメントと組み合わせて、http://localhost:8881/offline をシェル スクリプトに追加し、jenkins のビルド プロセス中にシェル スクリプトを実行し、プロセスを強制終了して、ビルドの完了後に再起動します。

どうでしょうか?役に立つと思ったら、遠慮せずに始めてください。

添付ファイル: 関連するコード ディレクトリ

github:https://github.com/897665787/springcloud-template

gitee:https://gitee.com/jq_di/springcloud-template

springcloud-template
└── template-eureka
     eureka.server.use-read-only-response-cache: false -- 禁用readOnlyCacheMap
└── template-framework
     └── deploy
          └── DeployController -- 部署相关接口(用于优雅发版)
          └── MQAutoRefresh -- MQ自动刷新注册列表(如果使用了MQ,可以利用MQ广播消息自动刷新)
          └── RefreshHandler -- 刷新处理器
          └── StartupApplicationRunner -- 服务启动成功执行

おすすめ

転載: blog.csdn.net/w13528476101/article/details/126678975