このエントリは2024/11/05現在の情報に基づいています。将来の機能追加や変更に伴い、記載内容からの解離が発生する可能性があります。
問い合わせ
お初の方から以下のようなお問い合わせをもらった。
Service Busを東西日本リージョンで冗長化しているのだが、メッセージレプリケーションを実現するためにFunctionsを作成・構成するのが面倒である(気持ちはわかる)。Geo-replicationというのがPublic Previewということを小耳に挟んだのだが、これってメッセージレプリケーションの代用になるものか?
彼らの構成を聞いたところ、以下のよう。なかなかゴージャスである。SQL DatabaseはFail over groupを構成済み、とのこと。同じような仕組みがService Busで取れないのがちょっとあれ、ということ。

Service BusのGeo-replicationがあるにはあるが…
そのものずばりの機能が現在Previewで提供されているが、彼らの環境では制約に抵触しているために利用できない。鋭意開発中とのことなので、期待してまちましょう(近いうちに一般提供してもらいたいものであるが、果たして)。
Azure Service Bus geo レプリケーション (プレビュー) / Azure Service Bus Geo-Replication (Preview)
https://learn.microsoft.com/azure/service-bus-messaging/service-bus-geo-replication
似たものとして、Geo-Disaster Recoveryという機能があるが、これはMetadataのみのフェールオーバーで、メッセージのレプリケーションは実施しない。そのため、メッセージはFunctionsを使ったReplicationを構成して担保するしかない。
Azure Service Bus の geo ディザスター リカバリー / Azure Service Bus Geo-Disaster Recovery
https://learn.microsoft.com/azure/service-bus-messaging/service-bus-geo-dr
メッセージ レプリケーションとリージョン間フェデレーション / Message replication and cross-region federation
https://learn.microsoft.com/azure/service-bus-messaging/service-bus-federation-overview
彼らの環境では使えない理由
Geo-replicationの注意点は以下のあたり。詳細は上記ドキュメントの【重要】に記載がある。以下に一部を記載しておく。
Azure Service Bus geo レプリケーション (プレビュー) / Azure Service Bus Geo-Replication (Preview)
https://learn.microsoft.com/azure/service-bus-messaging/service-bus-geo-replication
- Premium SKUでのみ利用可
- Preview時点の制限
- Secondaryは1個のみ
- リージョン制限あり(Japan East/Westは利用可能)
- Geo Disaster Recoveryとの併用不可
- Private Endpointなど、VNETのAdvanced featuresは使えない
この問い合わせ主の場合は、以下の理由から、現時点では利用ができない旨の回答済み(もちろん、Previewであることも伝えている)。
- 環境内でPrivate Endpointを使っていることから、現時点では利用できない
どういう動作をするのか?
確かにこの問い合わせ主の環境では利用できないが、動作確認はできるのでやっておいた。構成方法はドキュメントにある通りで、特別に補足する部分はない。
- Portalからだとチェックボックスに✅を入れる
- Bicep/ARM template/TerraForm (
AzAPIprovider) でgeoDataReplicationプロパティを構成する
Microsoft.ServiceBus namespaces 2023-01-01-preview
https://learn.microsoft.com/azure/templates/microsoft.servicebus/2023-01-01-preview/namespaces
レプリケーションは、同期型、非同期型の2種類。
| 種類 | 特徴 | 備考 |
|---|---|---|
| 同期型 | Secondaryでのコミットを待つため、Paired regionでの操作完了までのレイテンシが発生する(このレイテンシを許容できないならば非同期にするしかない) | |
| 非同期型 | 通常のSingle regionのレイテンシと同じだが、レプリケーション遅延が発生するので、その遅延の許容範囲を考慮・指定する必要がある。 | レプリケーションの最大タイムラグは Portalの場合は分単位、Bicepからは秒単位での指定( maxReplicationLagDurationInSeconds)が可能(最小5分、最大1日)。 |
非同期の場合、遅延の最大タイムラグを指定できるが、この値の最小値は5分。そのため、非機能要件と照らし合わせながら設定する必要がある。
同期非同期の変更は作成後でも可能だが、Geo-replication無効状態で作成したService Bus名前空間で、Geo-replicationを有効化したい場合、Preview時点では「レガシーの名前空間だと変更できません」というメッセージとともにエラーで返ってくるので、作成時に有効化しておく必要がある。

Geo-replication有効化状態で作成したService Bus名前空間で一度無効化し、再度有効化することは可能。
試してみる
Queue/Topicにメッセージを投げ込むテストクライアントを作成しておき、送受信中に強制フェールオーバーさせてみる、というシナリオを使う。両端のテストクライアントはFunctionsで作成する。Functionsからログを出力できるようにしておき、どのデータをPush/Pullしたか、例外が発生したか否かを把握できるようにしておく。

フェールオーバー時には接続が切れるので、Enqueue/Dequeue時にエラーが発生する(例えばSecondaryへの転送時にフェールオーバーが発生すれば、同期型であればエラーが返る)。こうしたエラーを救えるように、接続を再作成したり、リトライしたり、といった仕組みは入れておく必要があるが、幸いにして、Functionsでは再試行や再試行ポリシーが利用できる。
Azure Functions のエラー処理と再試行 / Azure Functions error handling and retries
https://learn.microsoft.com/azure/azure-functions/functions-bindings-error-pages
Service Bus trigger/output bindingの場合、host.jsonで設定する(デフォルトでは3回の再試行)。詳細は以下のURLに記載がある。
host.json 設定 / host.json settings
https://learn.microsoft.com/azure/azure-functions/functions-bindings-service-bus#hostjson-settings
で、実際に試した結果、以下のように動作することを確認した。
- フェールオーバー後も同じFQDNでアクセスできる
- 同期型であれば、レプリケーションの漏れは起こらない(HTTP triggerで送り込んでいるので、Service Bus Output Bindingで再試行してもEnqueueできなかった場合には500が返る)。
- 非同期の場合は、レプリケーションの遅延があるため、一部のメッセージがレプリケーションされなかったり、重複が発生したりする
フェールオーバーに要する時間は、およそ1分から2分ほど。ドキュメントには「最大で数分」という記載があるので、まぁこんなものかな、という感じ。