ローリングアップグレードまたはノード再起動時に、ApsaraMQ for RocketMQ はグレースフルシャットダウンを実行し、ストレージノードがオフラインになる前にアクティブ接続を徐々に切断し、処理中のメッセージを確実に永続化します。これにより、メッセージの損失を防止し、クライアント側のエラーを回避するとともに、プロデューサーおよびコンシューマーの動作を最小限の中断で継続できます。
仕組み
ストレージノードの再起動が必要になると、ApsaraMQ for RocketMQ は 2 つの位相でシャットダウンを調整します:
書き込みの一時停止
再起動開始前に、ブローカーは対象ストレージノードへの新規書き込み操作のルーティングを停止します。プロデューサーによって既に送信されたメッセージは、ノードがオフラインになる前に完全に永続化されます。このため、計画メンテナンス中におけるメッセージの損失は発生しません。つまり、シャットダウン直前のノードには新たなデータが書き込まれません。
GOAWAY を用いた接続の徐断
ブローカーは、対象ノードに接続しているすべてのクライアントに対して GOAWAY フレーム(HTTP/2 仕様で定義)を送信します。クライアントがこの信号を受信すると、以下の処理を行います。
現在の接続上で進行中のリクエストを完了します。
別の利用可能なノードへ新しい接続を開きます。
クライアントが突然切断されるのではなく事前に通知されるため、処理中のリクエストは正常に完了し、作業の喪失もありません。
GOAWAY の処理は ApsaraMQ for RocketMQ クライアント SDK に組み込まれています。ご使用の SDK バージョンが以下に示す最低要件を満たしていれば、アプリケーションレベルでのコード変更を伴わず、自動的に再接続が行われます。
プロデューサーおよびコンシューマーへの影響
| 役割 | グレースフルシャットダウン中の動作 |
|---|---|
| プロデューサー | 送信済みのすべてのメッセージが正常に処理されます。書き込みの一時停止フェーズにより、ノードがオフラインになる前にすべてのメッセージが確実に永続化されます。 |
| コンシューマー | ほとんどのメッセージは中断なく消費されます。ただし、トランジション期間中の一時的な状態により、コンシューマオフセットのコミットが失敗することがあり、再起動中のノード上の一部のメッセージが再配信される場合があります。 |
SDK のバージョン要件
グレースフルシャットダウンを利用するには、クライアント SDK が GOAWAY フレームをサポートしている必要があります。ご使用の SDK バージョンが以下の最低要件を満たしていることを確認してください。
| 言語 | 最低バージョン | 参照 |
|---|---|---|
| Java(gRPC プロトコル) | 5.0.7 | Java 向け SDK |
| Java(Remoting プロトコル) | 5.3.1 | Java 向け SDK |
| Go | 5.1.0-rc.1 | Go 向け SDK |
| Python | 5.0.4 | Python 向け SDK |
| C++ | 5.0.2 | C++ 向け SDK |
| C# | 5.1.0 | C# 向け SDK |
ご使用の SDK バージョンが上記の最低要件より古い場合、クライアントは GOAWAY フレームを処理できません。その結果、ノード再起動時に旧バージョンの SDK を使用するクライアント接続が突然切断され、一時的なエラーまたはメッセージの再配信が発生する可能性があります。
注意事項
クライアント側の構成は不要です。 グレースフルシャットダウンはサーバー側の機能です。対応する SDK バージョンへのアップグレードのみが必須の対応となります。
コンシューマーを冪等性対応で設計してください。 トランジション期間中の一時的な状態によりコンシューマオフセットのコミットが失敗する可能性があるため、一部のメッセージが再配信されることがあります。したがって、コンシューマーの処理ロジックは同一メッセージを複数回安全に処理できるよう設計してください。
SDK バージョンを積極的に監視してください。 新規サービスの追加や依存関係の更新を行う際には、RocketMQ クライアント SDK が引き続き最低バージョン要件を満たしていることを確認し、グレースフルシャットダウン機能の継続的な利用を確保してください。