Durable Functions のベスト プラクティスと診断ツール
この記事では、Durable Functions を使用する際のいくつかのベスト プラクティスについて詳しく説明します。 また、開発、テスト、運用環境での使用中に問題を診断するのに役立つさまざまなツールについて説明します。
ベスト プラクティス
最新バージョンの Durable Functions 拡張機能と SDK を使用する
Durable Functions を実行するために関数アプリで使用するコンポーネントは 2 つあります。 1 つは、対象のプログラミング言語を使用してオーケストレーター、アクティビティ、エンティティの関数を記述できる Durable Functions SDK です。 もう 1 つは "Durable 拡張機能" です。これは、コードを実際に実行するランタイム コンポーネントです。 .NET インプロセス アプリを除き、この SDK と拡張機能は個別にバージョン管理されます。
最新の拡張機能と SDK によって最新状態を保てば、アプリケーションで、最新のパフォーマンスの向上、機能、バグ修正からの利点が得られます。 最新バージョンにアップグレードすると、Microsoft が最新の診断テレメトリを確実に収集できるようにもなり、Azure でサポート ケースを開いたときの調査プロセスを迅速化する助けになります。
- 最新のバージョンの拡張機能を取得する手順については、「Durable Functions 拡張機能のバージョンをアップグレードする」を参照してください。
- 最新バージョンの SDK を使用していることを確認するには、使用している言語のパッケージ マネージャーを調べます。
Durable Functions のコード制約に従う
オーケストレーター コードの再生動作によって、オーケストレーター関数に記述できるコードの種類に制約が生まれます。 例として、オーケストレーター関数では、再生のたびに同じ結果が生成されるように決定論的 API を使用する必要があるという制約があります。
注意
Durable Functions の Roslyn アナライザーは、C# ユーザーが Durable Functions 固有のコード制約に準拠するようにガイドするライブ コード アナライザーです。 Visual Studio や Visual Studio Code で Roslyn アナライザーを有効にする方法については、「Durable Functions の Roslyn アナライザー」を参照してください。
プログラミング言語の Azure Functions パフォーマンス設定について理解を深める
"既定の設定を使用" すると、選択する言語ランタイムによって関数に厳格なコンカレンシー制限が課される場合があります。 たとえば、特定の VM で実行することが許可される関数は一度に 1 つだけです。 こうした制限は、通常、言語のコンカレンシーとパフォーマンスの設定を "微調整" することで緩和できます。 Durable Functions アプリケーションのパフォーマンスを最適化しようとしている場合は、これらの設定について理解を深める必要があります。
以下は、パフォーマンスとコンカレンシーの設定を微調整すると利点がある場合が多いいくつかの言語の包括的でない一覧と、それを行う場合のガイドラインです。
アプリごとに一意のタスク ハブ名を保証する
複数の Durable Function アプリで同じストレージ アカウントを共有できます。 既定では、アプリの名前がタスク ハブ名として使用されるため、タスク ハブの誤った共有が確実に行われなくなります。 host.json でアプリのタスク ハブ名を明示的に構成する必要がある場合は、名前が "一意" であることを確認する必要があります。 このようにしないと、複数のアプリがメッセージをめぐって競合し、その結果、オーケストレーションが Pending または Running の状態で予期せず "スタック" するなど、未定義の動作が発生する可能性があります。
唯一の例外は、同じアプリの "コピー" を複数のリージョンにデプロイする場合です。この場合、コピーに対して同じタスク ハブを使用できます。
実行中のオーケストレーターにコード変更をデプロイするときにはガイダンスに従う
アプリケーションの存続期間中に関数が追加、削除、変更されることは避けられません。 よくある破壊的変更の例としては、アクティビティやエンティティの関数シグネチャの変更、オーケストレーター ロジックの変更などがあります。 これらの変更は、まだ実行中のオーケストレーションに影響する場合は問題です。 正しくデプロイされていない場合、コードの変更により、非決定論的なエラーでオーケストレーションが失敗し、無期限にスタックしてパフォーマンスが低下するなどの状態に至る可能性があります。実行中のオーケストレーションに影響する可能性のあるコード変更を行うときには、推奨される軽減策を参照してください。
関数の入力と出力は可能な限り小さく保つ
Durable Functions API との間で大きな入力と出力をやり取りすると、メモリの問題が発生する可能性があります。
Durable Functions API への入力と出力は、オーケストレーション履歴内へとシリアル化されます。 これは、大きな入力と出力は、時間の経過と共に、オーケストレーター履歴が無限に拡大する大きな要因となり、再生中にメモリ例外を発生させるリスクがあることを意味します。
API への大きな入力と出力の影響を緩和するために、いくつかの作業をサブオーケストレーターに委任することも選択できます。 これは、履歴のメモリ負荷を 1 つのオーケストレーターから複数のオーケストレーターに負荷分散するのに役立つため、個々の履歴のメモリ占有領域が小さく保たれます。
つまり、"大きな" データを処理するためのベスト プラクティスは、それを外部ストレージに保持し、必要な場合にのみ、そのデータをアクティビティ内で具体化することです。 データ自体を Durable Functions API の入力や出力として通信する代わりにこのアプローチを取ると、アクティビティで必要なときに外部ストレージからそのデータを取得できる軽量な識別子を渡すことができます。
エンティティ データを小さく保つ
Durable Functions API への入力と出力の場合と同様に、エンティティの明示的な状態が大きすぎる場合、メモリの問題が発生する可能性があります。 特に、エンティティ状態は、要求に応じてストレージからシリアル化およびシリアル化解除する必要があるため、状態が大きいと、各呼び出しにシリアル化の待機時間が追加されます。 そのため、エンティティで大規模なデータを追跡する必要がある場合は、データを外部ストレージにオフロードし、必要に応じてストレージからデータを具現化できるエンティティ内の軽量の識別子を追跡することをお勧めします。
Durable Functions のコンカレンシー設定を微調整する
効率を高めるために、1 つのワーカー インスタンスで複数の作業項目を同時に実行できます。 ただし、同時に処理する作業項目が多すぎると、CPU 容量やネットワーク接続などのリソースが枯渇するリスクがあります。多くの場合、作業項目のスケーリングと制限は自動的に処理されるため、これは問題にならないはずです。 とは言え、パフォーマンスの問題 (オーケストレーターが、完了するのに時間がかかりすぎる、保留中でスタックしているなど) が発生している場合や、パフォーマンス テストを行っている場合は、host.json ファイルでコンカレンシーの制限を構成できます。
注意
これは、Azure Functions でお使いの言語ランタイムのパフォーマンスやコンカレンシー設定を微調整する代わりにはなりません。 Durable Functions のコンカレンシー設定では、特定の VM に一度に割り当て可能な作業量のみが決定されますが、VM 内で動作する処理の並列度は決定されません。 後者のためには、言語ランタイムのパフォーマンス設定を微調整する必要があります。
外部イベントに一意の名前を使用する
アクティビティ関数と同様に、外部イベントには "少なくとも 1 回の" 配信保証があります。 つまり、特定の "まれな" 条件 (再起動、スケーリング、クラッシュなどで発生することがあります) で、アプリケーションが同じ外部イベントの重複を受け取ることがあります。 そのため、外部イベントにはオーケストレーターで手動で重複を排除できる ID を含めることをお勧めします。
Note
MSSQL ストレージ プロバイダーは外部イベントを使用し、オーケストレーターの状態をトランザクションとして更新します。そのため、既定の Azure Storage ストレージ プロバイダーとは異なり、そのバックエンドでは重複イベントのリスクはないはずです。 ただし、バックエンド間でコードを移植できるように、外部イベントには一意の名前を付けることをお勧めします。
ストレス テストに投資する
パフォーマンスに関連するものと同様に、アプリの理想的なコンカレンシー設定とアーキテクチャは、最終的にはアプリケーションのワークロードによって決まります。 そのため、予想されるワークロードをシミュレートするパフォーマンス テスト ハーネスに投資し、それを使ってアプリのパフォーマンスと信頼性の実験を実行することをユーザーにお勧めします。
入力、出力、例外における機密データを回避する
Durable Functions API への入出力 (例外を含む) は、選択したストレージ プロバイダーに永続的に保存されます。 これらの入力、出力、または例外に機密データ (秘密情報、接続文字列、個人を特定できる情報など) が含まれている場合、ストレージ プロバイダーのリソースに読み取りアクセスできるユーザーである場合は、それらを入手できます。 機密データを安全に扱うには、アクティビティ関数内で、Azure Key Vault または環境変数からデータを取得し、そのデータをオーケストレーターやエンティティに直接通信しないことが推奨されます。 これにより、機密データがストレージ リソースに漏れるのを防ぐことができます。
Note
このガイダンスは CallHttp
オーケストレーター API にも適用され、その要求と応答のペイロードもストレージに永続化されます。 対象となる HTTP エンドポイントに認証が必要で、それが機密である可能性がある場合は、ユーザーがアクティビティ内で HTTP 呼び出しを実装するか、CallHttp
で提供される埋め込みのマネージド ID のサポートを使用することをお勧めします。
ヒント
同様に、(Application Insights などで) シークレットを含むデータをログに記録しないようにしてください。ログを読み取ることができるユーザーであれば、シークレットを入手できます。
診断ツール
問題の診断に役立つツールがいくつかあります。
Durable Functions と Durable Task Framework のログ
Durable Functions 拡張機能
Durable 拡張機能では、オーケストレーションの実行をエンドツーエンドでトレースできる追跡イベントが生成されます。 これらの追跡イベントは、Azure portal で Application Insights 分析ツールを使って検出および照会できます。 生成される追跡データの詳細レベルは、host.json ファイルの logger
(Functions 1.x) または logging
(Functions 2.0) セクションで構成できます。 構成の詳細を参照してください。
Durable Task Framework
Durable 拡張機能の v 2.3.0 以降では、基になる Durable Task Framework (DTFx) によって出力されたログもコレクションに使用できます。 これらのログを有効にする方法の詳細を参照してください。
Azure portal
問題の診断と解決
Azure Functions アプリ診断は、Azure portal にある、アプリケーションの潜在的な問題を監視して診断するための便利なリソースです。 診断に基づく問題の解決に役立つ提案も提供されます。 「Azure Function アプリ診断」を参照してください。
Durable Functions オーケストレーション トレース
Azure portal には、各オーケストレーション インスタンスの状態を理解し、エンドツーエンドの実行をトレースするのに役立つオーケストレーション トレースの詳細が用意されています。 Azure Functions アプリ内の関数の一覧を確認すると、トレースへのリンクが含まれる [モニター] 列が表示されます。 お使いのアプリでこの情報を取得するには、Applications Insights を有効にする必要があります。
Durable Functions 監視拡張機能
これは、オーケストレーション インスタンスを監視、管理、デバッグするための UI を提供する Visual Studio Code 拡張機能です。
Roslyn アナライザー
Durable Functions の Roslyn アナライザーは、C# ユーザーが Durable Functions 固有のコード制約に準拠するようにガイドするライブ コード アナライザーです。 Visual Studio や Visual Studio Code で Roslyn アナライザーを有効にする方法については、「Durable Functions の Roslyn アナライザー」を参照してください。
サポート
質問とサポートについては、以下のいずれかの GitHub リポジトリでイシューを開くことができます。 Azure のバグを報告する場合は、影響を受けたインスタンスの ID、問題を示している時間範囲 (UTC)、アプリケーション名 (可能な場合)、デプロイ リージョンなどの情報を含めると、調査が大幅にスピードアップされます。