はじめに
本記事では、Azure Durable Functions を使用して開発・運用されている方向けに、デプロイスロットを併用する環境で発生する「リクエストが別スロットにルーティングされる事象」について解説します。 特に、本番と検証で同一のストレージアカウントを利用している場合は注意が必要です。
Azure Durable Functionsとは
Azure Durable FunctionsはAzure Functionsの拡張機能です。 詳細は以下の記事をご参照ください。
事象
Azure Durable Functions において2つのスロット(production と staging)で運用をしていました。
上記構成においてstagingスロット上のアプリにリクエストしていたにも関わらず、オーケストレーター関数がproductionのアクティビティ関数を実行する事象が発生していたため調査を行いました。
原因
Durable Functions では、状態管理およびオーケストレーション処理に Azure Storage(Queue や Table)を使用しています。
このとき、本番と検証のスロットで同一のストレージアカウントおよび同一の TaskHubName を利用している場合、Durable Functions のステート情報が混在し、スロット間でリクエストが交差してしまうことがあります。
詳細は以下の Stack Overflow のディスカッションもご参照ください:
Azure Durable Functions invoked in mixed slots
対策
1. host.json の Task Hub 名をスロットごとに分ける
Durable Functions では host.json ファイルで durableTask.hubName を指定できます。スロットごとに異なる名前を明示的に設定することで、ステートの混在を防止できます。
{
"version": "2.0",
"extensions": {
"durableTask": {
"hubName": "MyAppHub-Staging"
}
}
}
例:
- 本番スロット:
MyAppHub-Prod - 検証スロット:
MyAppHub-Staging
2. ストレージアカウントをスロットごとに分離する
アプリケーション設定(AzureWebJobsStorage)で指定するストレージアカウントをスロット単位で分けることで、Queue や Table の衝突を回避できます。
- 本番用ストレージアカウント:
myappprodstorage - 検証用ストレージアカウント:
myappstagestorage
ストレージを完全に分離することで、Durable Functions によるすべての状態管理リソースも明確に分かれ、安全な運用が可能になります。
スロットごとにストレージアカウントを分ける場合、Azure Functionsのアプリケーション設定でAzureWebJobsStorageに対象のストレージアカウントの接続文字列を設定します。
ただし、このままだとスロットスワップ時に検証環境のストレージアカウント設定が本番スロットに移ってしまいます。 これを防ぐために、デプロイメント設定を使用します。
デプロイメント設定(Deployment setting)とは?
デプロイメント設定とは、スロット間のスワップ時に値が変わらない設定のことです。 Azure Functionsなどのアプリの「設定(App Settings)」で、この設定を有効にできます。
**Sticky(スティッキー)**とは、「くっついている」という意味です。 スロットをスワップしても、その設定が元のスロットに残る(移動しない)ことを指します。
おわりに
Durable Functions におけるスロット運用では、ステート管理の共有を避けることが非常に重要です。タスクハブ名の変更やストレージアカウントの分離といった設計を徹底することで、意図しないスロット間のルーティングを防ぐことができます。
安定した本番運用を行うためにも、スロット構成と Durable Functions の設定について見直すことを推奨します。