分離ワーカー モデルで C# Azure Functions を実行するためのガイド
この記事は、Azure Functions を .NET で、分離ワーカー モデルを使用して扱うための入門となるものです。 このモデルでは、他のランタイム コンポーネントとは独立して .NET のバージョンをプロジェクトのターゲットとすることができます。 サポートされている特定の .NET バージョンの詳細については、「サポートされているバージョン」を参照してください。
次のリンクを使用すると .NET 分離ワーカー モデル関数の構築を今すぐ開始できます。
作業の開始 | 概念 | サンプル |
---|---|---|
分離ワーカー モデル プロジェクトを Azure にデプロイする方法について学ぶには、「Azure Functions へのデプロイ」を参照してください。
分離ワーカー モデルの利点
.NET クラス ライブラリ関数の実行モードは 2 つあり、1 つは Functions ホスト ランタイムと同じプロセス内 ("インプロセス") で実行、もう 1 つは分離ワーカー プロセス内で実行するというものです。 .NET 関数を分離ワーカー プロセスで実行すると、次のような利点を利用できます。
- 競合が少ない: 関数は独立したプロセスの中で実行されるため、アプリで使用されるアセンブリが、ホスト プロセスで使用される同じアセンブリの別のバージョンと競合することはありません。
- プロセスの完全制御: 開発者がアプリの起動を制御できます。つまり、使用される構成と起動されるミドルウェアを開発者が制御できます。
- 標準の依存関係の挿入: 開発者がプロセスを完全制御できるので、現在の .NET 動作を使用して依存関係の挿入や関数アプリへのミドルウェアの組み込みを行うことができます。
- .NET のバージョンの柔軟性: ホスト プロセスの外部で実行されるため、Functions ランタイムでネイティブにサポートされていないバージョンの .NET (これには .NET Framework も含まれます) 上で関数を実行できます。
既存の C# 関数アプリがインプロセスで実行されている場合に、これらの利点を活用するには、そのアプリを移行する必要があります。 詳細については、「.NET アプリをインプロセス モデルから分離ワーカー モデルに移行する」を参照してください。
2 つのモード間の総合的な比較については、インプロセスと分離ワーカー プロセスの .NET Azure Functions の違いに関するページを参照してください。
サポートされているバージョン
Functions ランタイムの各バージョンでは、.NET の特定のバージョンがサポートされています。 Functions のバージョンの詳細については、「Azure Functions ランタイム バージョンの概要」を参照してください。 バージョンのサポートは、関数がインプロセスで実行されるか、分離ワーカー プロセスで実行されるかによっても異なります。
Note
関数アプリで使用される Functions ランタイム バージョンを変更する方法については、「現在のランタイム バージョンの表示と更新」を参照してください。
次の表は、特定のバージョンの Functions と共に使用できる最上位レベルの .NET と .NET Framework を示しています。
Functions ランタイムのバージョン | 分離ワーカー モデル | インプロセス モデル4 |
---|---|---|
Functions 4.x1 | .NET 9.0 .NET 8.0 .NET Framework 4.82 |
.NET 8.0 |
Functions 1.x3 | 該当なし | .NET Framework 4.8 |
1 .NET 6 は、以前は両方のモデルでサポートされていましたが、2024 年 11 月 12 日に公式サポートが終了しました。 .NET 7 は、以前は分離ワーカー モデルでサポートされていましたが、2024 年 5 月 14 日に公式サポートが終了しました。
2 ビルド プロセスには .NET SDK も必要です。
3 Azure Functions ランタイムのバージョン 1.x のサポートは、2026 年 9 月 14 日に終了します。 詳細については、こちらのサポートに関するお知らせを参照してください。 引き続き完全なサポートを受けるには、アプリをバージョン 4.x に移行する必要があります。
4 インプロセス モデルのサポートは、2026 年 11 月 10 日に終了します。 詳細については、こちらのサポートに関するお知らせを参照してください。 完全なサポートを受け続けるには、分離ワーカー モデルにアプリを移行する必要があります。
特定の古いマイナー バージョンの削除など、Azure Functions リリースに関する最新のニュースについては、Azure App Service のお知らせを閲覧してください。
プロジェクト構造
分離ワーカー モデルを使用する Azure Functions 用 .NET プロジェクトは、基本的には、サポートされる .NET ランタイムをターゲットとする .NET コンソール アプリ プロジェクトです。 以下は、.NET 分離プロジェクトで必要となる基本的なファイルです。
- プロジェクトと依存関係を定義する C# プロジェクト ファイル (.csproj)
- アプリのエントリ ポイントである Program.cs ファイル。
- 関数を定義するすべてのコード ファイル。
- プロジェクト内の関数に共通する構成を定義する host.json ファイル。
- プロジェクトをマシン上でローカルに実行するときに使用される環境変数を定義する local.settings.json ファイル。
詳細な例については、.NET 8 サンプル プロジェクトと .NET Framework 4.8 サンプル プロジェクトを参照してください。
パッケージ参照
分離ワーカー モデルを使用する Azure Functions 用 .NET プロジェクトでは、コア機能とバインド拡張機能の両方に対して、一意のパッケージ セットが使用されます。
コア パッケージ
.NET 関数を分離ワーカー プロセスで実行するには、次のパッケージが必要です。
バージョン 2.x
2.x バージョンのコア パッケージでは、サポートされるフレームワークが変更され、これらの新しいバージョンからの新しい .NET API のサポートが追加されます。 .NET 9 以降をターゲットとする場合、アプリでは両方のパッケージのバージョン 2.0.0 以降を参照する必要があります。
2.x バージョンに更新するときは、次の変更に注意してください。
- Microsoft.Azure.Functions.Worker.Sdk のバージョン 2.0.0 以降:
- SDK には、SDK コンテナー ビルドの既定の構成が含まれています。
- SDK には、Azure Functions Core Tools がインストールされている場合の
dotnet run
のサポートが含まれています。 Windows では、NPM 以外のメカニズムを使用して Core Tools をインストールする必要があります。
- Microsoft.Azure.Functions.Worker のバージョン 2.0.0 以降:
- このバージョンで
IHostApplicationBuilder
のサポートが追加されます。 このガイドの例の中には、IHostApplicationBuilder
を使用する代替方法を示すタブが含まれているものがあります。 これらの例には 2.x バージョンが必要です。 - 開発環境で実行するときは、サービス プロバイダー スコープ検証が既定で含まれます。 この動作は、ASP.NET Core と一致します。
EnableUserCodeException
オプションは既定で有効化されます。 このプロパティは、現在では非推奨となっています。IncludeEmptyEntriesInMessagePayload
オプションは既定で有効化されます。 このオプションが有効のときは、コレクションを表すトリガー ペイロードには常に空のエントリが含まれます。 たとえば、メッセージが本文なしで送信された場合でも、トリガー データを表すstring[]
の中に空のエントリが存在します。 この空のエントリを含めることによって、関数が参照するメタデータ配列との相互参照が容易になります。 この動作を無効にするには、WorkerOptions
サービス構成の中でIncludeEmptyEntriesInMessagePayload
をfalse
に設定します。ILoggerExtensions
クラスの名前がFunctionsLoggerExtensions
に変更されます。 この名前変更の結果、LogMetric()
をILogger
インスタンスに対して使用するときのあいまい呼び出しエラーが回避されます。HttpResponseData
を使用するアプリでは、WriteAsJsonAsync()
メソッドは状態コードを200 OK
に設定しなくなりました。 1.x では、設定されていた他のエラー コードがこれによって上書きされていました。
- このバージョンで
- 2.x バージョンでは、.NET 5 TFM のサポートが削除されます。
拡張機能パッケージ
.NET 分離ワーカー プロセス関数はさまざまなバインドの種類を使用するため、バインド拡張機能パッケージの一意のセットが必要になります。
これらの拡張機能パッケージは、Microsoft.Azure.Functions.Worker.Extensions にあります。
スタートアップと構成
分離ワーカー モデルを使用するときは、開発する関数アプリのスタートアップにアクセスできますが、これは通常は Program.cs
にあります。 各自のホスト インスタンスの作成と開始は、お客様が担当します。 そのため、自分のアプリの構成パイプラインに直接アクセスすることもできます。 .NET Functions 分離ワーカー プロセスでは、構成の追加、依存関係の挿入、および独自のミドルウェアの実行がはるかに簡単になります。
次のコードは HostBuilder パイプラインの例を示します。
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(s =>
{
s.AddApplicationInsightsTelemetryWorkerService();
s.ConfigureFunctionsApplicationInsights();
s.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();
s.Configure<LoggerFilterOptions>(options =>
{
// The Application Insights SDK adds a default logging filter that instructs ILogger to capture only Warning and more severe logs. Application Insights requires an explicit override.
// Log levels can also be configured using appsettings.json. For more information, see https://learn.microsoft.com/en-us/azure/azure-monitor/app/worker-service#ilogger-logs
LoggerFilterRule? toRemove = options.Rules.FirstOrDefault(rule => rule.ProviderName
== "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
if (toRemove is not null)
{
options.Rules.Remove(toRemove);
}
});
})
.Build();
このコードでは using Microsoft.Extensions.DependencyInjection;
が必要です。
IHostBuilder
上の Build()
を呼び出す前に、以下の操作を行う必要があります。
- ASP.NET Core 統合を使用している場合は
ConfigureFunctionsWebApplication()
を呼び出し、それ以外の場合はConfigureFunctionsWorkerDefaults()
を呼び出します。 これらのオプションの詳細については、「HTTP トリガー」を参照してください。
アプリケーションのプログラミングに F# を使用する場合は、一部のトリガーおよびバインド拡張機能に追加の構成が必要になります。 BLOB 拡張機能、テーブル拡張機能、Cosmos DB 拡張機能を F# アプリで使用する予定がある場合は、これらの拡張機能のセットアップのドキュメントを参照してください。 - プロジェクトで必要なサービスまたはアプリ構成を構成します。 詳細については「構成」を参照してください。
Application Insights を使用する予定の場合は、ConfigureServices()
デリゲートでAddApplicationInsightsTelemetryWorkerService()
とConfigureFunctionsApplicationInsights()
を呼び出す必要があります。 詳細については、「Application Insights」を参照してください。
プロジェクトのターゲットが .NET Framework 4.8 の場合は、HostBuilder を作成する前に FunctionsDebugger.Enable();
を追加する必要もあります。 これは、Main()
メソッドの最初の行である必要があります。 詳細については、「.NET Framework をターゲットにするときのデバッグ」を参照してください。
HostBuilder は、完全に初期化された IHost
インスタンスを構築して返すために使用されます。このインスタンスを非同期で実行して関数アプリを起動します。
await host.RunAsync();
構成
使用するビルダーの種類によって、アプリケーションをどのように構成できるかが決まります。
ConfigureFunctionsWorkerDefaults メソッドを使用して、関数アプリの実行に必要な設定を追加します。 このメソッドには、次の機能が含まれています。
- コンバーターの既定のセット。
- プロパティ名の大文字と小文字の区別を無視するための既定の JsonSerializerOptions への設定。
- Azure Functions ログとの統合。
- 出力バインディング ミドルウェアと機能。
- 関数の実行ミドルウェア。
- 既定の gRPC サポート。
.ConfigureFunctionsWorkerDefaults()
ホスト ビルダー パイプラインにアクセスできるということは、初期化中にあらゆるアプリ固有の構成を設定できることも意味します。 ConfigureAppConfiguration メソッドを HostBuilder に対して 1 回または複数回呼び出して、開発するコードに必要な任意の構成ソースを追加できます。 アプリ構成について詳しくは、「ASP.NET Core の構成」を参照してください。
これらの構成が適用されるのは、開発者が作成するワーカー コードのみであり、Functions ホストやトリガーとバインドの構成に直接影響を与えることはありません。 Functions ホストまたはトリガーおよびバインド構成に変更を加えるには、この場合も host.json ファイルを使用する必要があります。
Note
カスタム構成ソースは、トリガーとバインドの構成には使用できません。 トリガーとバインドの構成は、アプリケーション コードだけでなく、Functions プラットフォームからも利用できる必要があります。 この構成は、アプリケーション設定、Key Vault 参照、または App Configuration 参照機能を通して指定できます。
依存関係の挿入
分離ワーカー モデルでは、標準の .NET メカニズムを使用してサービスが挿入されます。
HostBuilder
を使用するときは、ConfigureServices をホスト ビルダーに対して呼び出し、IServiceCollection の拡張メソッドを使用して特定のサービスを挿入します。 次の例では、シングルトン サービスの依存関係を挿入します。
.ConfigureServices(services =>
{
services.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();
})
このコードでは using Microsoft.Extensions.DependencyInjection;
が必要です。 詳細については、「ASP.NET Core での依存関係の挿入」を参照してください。
Azure クライアントを登録する
依存関係の挿入は、他の Azure サービスと対話するために使用できます。 Microsoft.Extensions.Azure パッケージを使って、Azure SDK for .NET からクライアントを挿入できます。 パッケージをインストールした後、Program.cs
のサービス コレクションで AddAzureClients()
を呼び出してクライアントを登録します。 次の例では、Azure BLOB の名前付きクライアントを構成します。
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices((hostContext, services) =>
{
services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddBlobServiceClient(hostContext.Configuration.GetSection("MyStorageConnection"))
.WithName("copierOutputBlob");
});
})
.Build();
host.Run();
次の例は、この登録と SDK タイプを使って、挿入されたクライアントを使って、あるコンテナーから別のコンテナーに BLOB コンテンツをストリームとしてコピーする方法を示しています。
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Logging;
namespace MyFunctionApp
{
public class BlobCopier
{
private readonly ILogger<BlobCopier> _logger;
private readonly BlobContainerClient _copyContainerClient;
public BlobCopier(ILogger<BlobCopier> logger, IAzureClientFactory<BlobServiceClient> blobClientFactory)
{
_logger = logger;
_copyContainerClient = blobClientFactory.CreateClient("copierOutputBlob").GetBlobContainerClient("samples-workitems-copy");
_copyContainerClient.CreateIfNotExists();
}
[Function("BlobCopier")]
public async Task Run([BlobTrigger("samples-workitems/{name}", Connection = "MyStorageConnection")] Stream myBlob, string name)
{
await _copyContainerClient.UploadBlobAsync(name, myBlob);
_logger.LogInformation($"Blob {name} copied!");
}
}
}
この例の ILogger<T>
も依存関係の挿入を通じて取得されたものであり、したがって自動的に登録されます。 ログ記録の構成オプションの詳細については、「ログ記録」を参照してください。
ヒント
この例では、Program.cs
と関数の両方でクライアント名のリテラル文字列を使いました。 代わりに、関数クラスで定義された共有定数文字列の使用を検討してください。 たとえば、public const string CopyStorageClientName = nameof(_copyContainerClient);
を追加し、両方の場所で BlobCopier.CopyStorageClientName
を参照できます。 同様に、Program.cs
ではなく関数を使って構成セクション名を定義することもできます。
ミドルウェア
分離ワーカー モデルはでは、ASP.NET にあるものと同様のモデルを使用して、ミドルウェア登録もサポートしています。 このモデルを使用すると、呼び出しパイプラインにロジックを挿入したり、関数の実行前と実行後にロジックを挿入したりすることができます。
ConfigureFunctionsWorkerDefaults 拡張メソッドには、次の例に示すように、独自のミドルウェアを登録できるオーバーロードがあります。
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(workerApplication =>
{
// Register our custom middlewares with the worker
workerApplication.UseMiddleware<ExceptionHandlingMiddleware>();
workerApplication.UseMiddleware<MyCustomMiddleware>();
workerApplication.UseWhen<StampHttpHeaderMiddleware>((context) =>
{
// We want to use this middleware only for http trigger invocations.
return context.FunctionDefinition.InputBindings.Values
.First(a => a.Type.EndsWith("Trigger")).Type == "httpTrigger";
});
})
.Build();
UseWhen
拡張メソッドを使用して、条件付きで実行されるミドルウェアを登録できます。 ブール値を返す述語をこのメソッドに渡す必要があります。述語の戻り値が true
のとき、ミドルウェアは呼び出し処理パイプラインに参加します。
FunctionContext に対する次の拡張メソッドにより、分離モデルでのミドルウェアの処理が簡単になります。
メソッド | 説明 |
---|---|
GetHttpRequestDataAsync |
HTTP トリガーによって呼び出されたときに HttpRequestData インスタンスを取得します。 このメソッドは、要求ヘッダーや Cookie などのメッセージ データを読み取るときに便利な ValueTask<HttpRequestData?> のインスタンスを返します。 |
GetHttpResponseData |
HTTP トリガーによって呼び出されたときに HttpResponseData インスタンスを取得します。 |
GetInvocationResult |
現在の関数実行の結果を表す InvocationResult のインスタンスを取得します。 Value プロパティを使用して、必要に応じて値を取得または設定します。 |
GetOutputBindings |
現在の関数実行の出力バインド エントリを取得します。 このメソッドの結果の各エントリの型は OutputBindingData です。 Value プロパティを使用して、必要に応じて値を取得または設定できます。 |
BindInputAsync |
要求された BindingMetadata インスタンスの入力バインド項目をバインドします。 たとえば、ミドルウェアで使用する必要のある BlobInput 入力バインドを持つ関数があるときに、このメソッドを使用できます。 |
これは関数の実行中に HttpRequestData
インスタンスを読み取り、HttpResponseData
インスタンスを更新するミドルウェア実装の例です。
internal sealed class StampHttpHeaderMiddleware : IFunctionsWorkerMiddleware
{
public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
{
var requestData = await context.GetHttpRequestDataAsync();
string correlationId;
if (requestData!.Headers.TryGetValues("x-correlationId", out var values))
{
correlationId = values.First();
}
else
{
correlationId = Guid.NewGuid().ToString();
}
await next(context);
context.GetHttpResponseData()?.Headers.Add("x-correlationId", correlationId);
}
}
このミドルウェアは、特定の要求ヘッダー (x-correlationId) の存在を確認し、存在するときはヘッダー値を使用して応答ヘッダーをスタンプします。 それ以外の場合は、新しい GUID 値を生成し、それを使用して応答ヘッダーをスタンプします。 関数アプリでカスタム ミドルウェアを使用する詳細な例については、カスタム ミドルウェアのリファレンス サンプルを参照してください。
JSON シリアル化のカスタマイズ
分離ワーカー モデルは既定では System.Text.Json
を使用します。 Program.cs
ファイルの一部としてサービスを構成することで、シリアライザーの動作をカスタマイズできます。 このセクションの内容は汎用のシリアル化であり、ASP.NET Core 統合での HTTP トリガー JSON のシリアル化には影響しません。これは別に構成する必要があります。
次の例は、ConfigureFunctionsWebApplication
を使用してこれを示していますが、ConfigureFunctionsWorkerDefaults
でも機能します。
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication((IFunctionsWorkerApplicationBuilder builder) =>
{
builder.Services.Configure<JsonSerializerOptions>(jsonSerializerOptions =>
{
jsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
jsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
jsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
// override the default value
jsonSerializerOptions.PropertyNameCaseInsensitive = false;
});
})
.Build();
host.Run();
代わりに、JSON.NET (Newtonsoft.Json
) をシリアル化に使用することもできます。 これを行うには、Microsoft.Azure.Core.NewtonsoftJson
パッケージをインストールすることになります。 次に、サービス登録で、WorkerOptions
構成で Serializer
プロパティを再割り当てします。 次の例は、ConfigureFunctionsWebApplication
を使用してこれを示していますが、ConfigureFunctionsWorkerDefaults
でも機能します。
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication((IFunctionsWorkerApplicationBuilder builder) =>
{
builder.Services.Configure<WorkerOptions>(workerOptions =>
{
var settings = NewtonsoftJsonObjectSerializer.CreateJsonSerializerSettings();
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
settings.NullValueHandling = NullValueHandling.Ignore;
workerOptions.Serializer = new NewtonsoftJsonObjectSerializer(settings);
});
})
.Build();
host.Run();
関数として認識されるメソッド
関数メソッドは、次の例に示すように、 Function
属性がメソッドに適用され、トリガー属性が入力パラメーターに適用されたパブリック クラスのパブリック メソッドです:
[Function(nameof(QueueFunction))]
[QueueOutput("output-queue")]
public string[] Run([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)
トリガー属性は、トリガーの種類を指定し、メソッド パラメーターに入力データをバインドします。 前の例の関数はキュー メッセージによってトリガーされ、そのキュー メッセージは myQueueItem
パラメーターでメソッドに渡されます。
Function
属性は、関数のエントリ ポイントとしてメソッドをマークします。 名前はプロジェクト内で一意であり、文字で始まり、英数字、_
、-
のみが含まれ、127 文字以下にする必要があります。 プロジェクト テンプレートでは、多くの場合、Run
という名前のメソッドが作成されますが、有効な C# メソッド名であればメソッド名として使用できます。 このメソッドは、パブリック クラスのパブリック メンバーである必要があります。 依存関係の挿入を介してサービスを渡すことができるように、通常はインスタンス メソッド必要があります。
関数のパラメーター
次のようなパラメータを関数メソッド シグネチャの一部として含めることができます。
- バインド。パラメータを属性として修飾することによって、バインドであることが指定されます。 関数には、トリガー パラメータが厳密に 1 つ含まれている必要があります。
- 実行コンテキスト オブジェクト。現在の呼び出しに関する情報を提供します。
- キャンセル トークン。グレースフル シャットダウンに使用されます。
実行コンテキスト
.NET 分離は FunctionContext オブジェクトを関数メソッドに渡します。 このオブジェクトを使用すれば、ログに書き込む ILoggerILogger
インスタンスを取得できます。これは、GetLogger メソッドを呼び出して ILogger
文字列を指定することで実行します。 このコンテキストを使用すると、依存関係の挿入を使用する必要なく ILogger
を取得できます。 詳細については、「ログ」を参照してください。
キャンセル トークン
関数は CancellationToken パラメーターを受け付けることができます。これにより、オペレーティング システムは、その関数をいつ終了しようとしているかをコードに通知できます。 この通知を使用すれば、関数が予期せず終了してデータが不整合な状態になることを防止できます。
分離ワーカー プロセスで実行されているときは、.NET 関数でキャンセル トークンがサポートされます。 次の例では、取り消し要求が受信されたときに例外が生成されます。
[Function(nameof(ThrowOnCancellation))]
public async Task ThrowOnCancellation(
[EventHubTrigger("sample-workitem-1", Connection = "EventHubConnection")] string[] messages,
FunctionContext context,
CancellationToken cancellationToken)
{
_logger.LogInformation("C# EventHub {functionName} trigger function processing a request.", nameof(ThrowOnCancellation));
foreach (var message in messages)
{
cancellationToken.ThrowIfCancellationRequested();
await Task.Delay(6000); // task delay to simulate message processing
_logger.LogInformation("Message '{msg}' was processed.", message);
}
}
次の例では、取り消し要求が受信されたときにクリーンアップ アクションが実行されます。
[Function(nameof(HandleCancellationCleanup))]
public async Task HandleCancellationCleanup(
[EventHubTrigger("sample-workitem-2", Connection = "EventHubConnection")] string[] messages,
FunctionContext context,
CancellationToken cancellationToken)
{
_logger.LogInformation("C# EventHub {functionName} trigger function processing a request.", nameof(HandleCancellationCleanup));
foreach (var message in messages)
{
if (cancellationToken.IsCancellationRequested)
{
_logger.LogInformation("A cancellation token was received, taking precautionary actions.");
// Take precautions like noting how far along you are with processing the batch
_logger.LogInformation("Precautionary activities complete.");
break;
}
await Task.Delay(6000); // task delay to simulate message processing
_logger.LogInformation("Message '{msg}' was processed.", message);
}
}
バインド
バインドは、メソッド、パラメーター、および戻り値の型の属性を使用して定義します。 バインドでは、文字列、配列、および単純な従来のクラス オブジェクト (POCO) のようなシリアル化可能型としてデータを提供できます。 一部のバインド拡張機能では、サービス SDK で定義されているサービス固有の型にバインドすることもできます。
HTTP トリガーについては、HTTP トリガーのセクションを参照してください。
トリガーおよびバインドを分離ワーカー プロセス関数と共に使用するリファレンス サンプルの全セットについては、バインド拡張機能のリファレンス サンプルを参照してください。
入力バインディング
関数には、関数にデータを渡すことができる入力バインディングを 0 個以上含めることができます。 トリガーと同様、入力バインディングは、入力パラメーターにバインディング属性を適用することによって定義します。 関数を実行すると、ランタイムはバインディングで指定されたデータを取得しようとします。 要求されるデータは、多くの場合、バインディング パラメーターを使用してトリガーから提供される情報に依存します。
出力バインディング
出力バインドに書き込むには、出力バインド属性を関数メソッドに適用する必要があります。これによって、バインドされたサービスへの書き込みの方法が定義されます。 メソッドによって返される値は、出力バインディングに書き込まれます。 たとえば、次の例では、出力バインディングを使用して、output-queue
という名前のメッセージ キューに文字列値を書き込みます。
[Function(nameof(QueueFunction))]
[QueueOutput("output-queue")]
public string[] Run([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)
{
// Use a string array to return more than one message.
string[] messages = {
$"Album name = {myQueueItem.Name}",
$"Album songs = {myQueueItem.Songs}"};
_logger.LogInformation("{msg1},{msg2}", messages[0], messages[1]);
// Queue Output messages
return messages;
}
複数の出力バインディング
出力バインディングに書き込まれるデータは、常に関数の戻り値です。 複数の出力バインディングに書き込む必要がある場合は、カスタムの戻り値の型を作成する必要があります。 この戻り値の型では、出力バインディング属性はクラスの 1 つ以上のプロパティに適用されていなければなりません。 次の例は、"ASP.NET Core 統合" を使用して HTTP によってトリガーされる関数です。この関数では、HTTP 応答とキュー出力バインドの両方への書き込みが行われます。
public class MultipleOutputBindings
{
private readonly ILogger<MultipleOutputBindings> _logger;
public MultipleOutputBindings(ILogger<MultipleOutputBindings> logger)
{
_logger = logger;
}
[Function("MultipleOutputBindings")]
public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
var myObject = new MyOutputType
{
Result = new OkObjectResult("C# HTTP trigger function processed a request."),
MessageText = "some output"
};
return myObject;
}
public class MyOutputType
{
[HttpResult]
public IActionResult Result { get; set; }
[QueueOutput("myQueue")]
public string MessageText { get; set; }
}
}
ASP.NET Core 統合で複数の出力バインドにカスタム戻り値の型を使用する場合は、結果を提供するプロパティに [HttpResult]
属性を追加する必要があります。 HttpResult
属性は、SDK 1.17.3-preview2 以降と、HTTP 拡張機能のバージョン 3.2.0 以降、および ASP.NET Core 拡張機能のバージョン 1.3.0 以降を使う場合に使用できます。
SDK タイプ
一部のサービス固有のバインディングの型では、サービス SDK とフレームワークの型を使用してバインディング データを提供できます。 これらは、シリアル化された文字列や単純な従来の CLR オブジェクト (POCO) では不可能な機能を提供します。 新しいタイプを使用するには、コア依存関係の新しいバージョンを使用するようにプロジェクトを更新する必要があります。
依存関係 | バージョン要件 |
---|---|
Microsoft.Azure.Functions.Worker | 1.18.0 以降 |
Microsoft.Azure.Functions.Worker.Sdk | 1.13.0 以上 |
SDK 型をマシン上でローカルにテストする場合は、Azure Functions Core Tools バージョン 4.0.5000 以降を使用することも必要です。 現在のバージョンを確認するには func version
コマンドを使用します。
各トリガーとバインド拡張機能にも独自の最小バージョン要件があり、これは拡張機能のリファレンス記事で説明されています。 次のサービス固有のバインドでは SDK 型が提供されます。
サービス | トリガー | 入力バインド | 出力バインド |
---|---|---|---|
Azure BLOB | 一般提供 | 一般提供 | SDK の型は推奨されません。1 |
Azure キュー | 一般提供 | 入力バインドは存在しません | SDK の型は推奨されません。1 |
Azure Service Bus | 一般提供 | 入力バインドは存在しません | SDK の型は推奨されません。1 |
Azure Event Hubs | 一般提供 | 入力バインドは存在しません | SDK の型は推奨されません。1 |
Azure Cosmos DB | SDK 型は使用されません2 | 一般提供 | SDK の型は推奨されません。1 |
Azure テーブル | トリガーは存在しません | 一般提供 | SDK の型は推奨されません。1 |
Azure Event Grid | 一般提供 | 入力バインドは存在しません | SDK の型は推奨されません。1 |
1 SDK の型を使用する出力シナリオでは、出力バインドを使用する代わりに、SDK クライアントを直接作成して操作する必要があります。 依存関係の挿入の例については、「Azure クライアントの登録」を参照してください。
2 Cosmos DB トリガーでは、Azure Cosmos DB の変更フィードが使用され、変更フィードの項目が JSON シリアル化可能な型として公開されます。 このシナリオの設計により、SDK 型は存在しません。
Note
トリガー データに依存するバインド式を使用するとき、トリガー自体の SDK の型は使用できません。
HTTP トリガー
HTTP トリガーを使用すると、HTTP 要求によって関数を呼び出せます。 使用できる方法は 2 つあります。
- ASP.NET Core 開発者が慣れている概念を使用する ASP.NET Core 統合モデル
- 組み込みモデル。追加の依存関係は不要であり、カスタム型が HTTP 要求と応答に使用されます。 このアプローチは、以前の .NET 分離ワーカー アプリとの後方互換対応を目的として維持されています。
ASP.NET Core の統合
このセクションでは、HttpRequest、HttpResponse、IActionResult などの ASP.NET Core の型を使用して、基になる HTTP 要求オブジェクトと応答オブジェクトを操作する方法について説明します。 このモデルは .NET Framework をターゲットとするアプリには使用できません。このようなアプリでは、代わりに組み込みモデルを使用する必要があります。
Note
ASP.NET Core の全機能がこのモデルによって公開されるわけではありません。 具体的には、ASP.NET Core ミドルウェア パイプラインとルーティング機能は使用できません。 ASP.NET Core 統合を使用するには、更新されたパッケージを使用する必要があります。
ASP.NET Core 統合を HTTP に対して有効にする手順は次のとおりです。
プロジェクトに Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore パッケージ バージョン 1.0.0 以降への参照を追加します。
次に示すパッケージ バージョンを使用するようにプロジェクトを更新します。
- Microsoft.Azure.Functions.Worker.Sdk バージョン 1.11.0。 "以降"
- Microsoft.Azure.Functions.Worker バージョン 1.16.0 以降。
Program.cs
ファイルの中で、ConfigureFunctionsWebApplication()
を呼び出すようにホスト ビルダーの構成を更新します。ConfigureFunctionsWorkerDefaults()
を使用していた場合は、このメソッドがこれで置き換えられます。 次の例は、他のカスタマイズを行わない最小限のセットアップを示しています。using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.Hosting; var host = new HostBuilder() .ConfigureFunctionsWebApplication() .Build(); host.Run();
HTTP によってトリガーされる既存の関数がある場合は、ASP.NET Core の型を使用するように更新します。 この例では、標準の
HttpRequest
とIActionResult
が単純な "hello, world" 関数に使用されています。[Function("HttpFunction")] public IActionResult Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req) { return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!"); }
ASP.NET Core 統合での JSON のシリアル化
ASP.NET Core には独自のシリアル化レイヤーがあり、一般的なシリアル化構成のカスタマイズによる影響を受けません。 HTTP トリガーに使われるシリアル化の動作をカスタマイズするには、サービス登録の一部として .AddMvc()
の呼び出しを含める必要があります。 返された IMvcBuilder
を使って、ASP.NET Core の JSON シリアル化の設定を変更できます。
HttpRequestData
と HttpResponsedata
は、ASP.NET 統合の使用中でも引き続き使うことができますが、ほとんどのアプリで、代わりに HttpRequest
と IActionResult
を使用することをお勧めします。 HttpRequestData
/HttpResponseData
を使用すると、ASP.NET Core シリアル化レイヤーは呼び出されず、代わりに、アプリの一般的な worker シリアル化構成が使用されます。 ただし、ASP.NET Core 統合が有効になっている場合でも、構成の追加が必要になる場合があります。 ASP.NET Core の既定の動作は同期 IO を禁止することです。 NewtonsoftJsonObjectSerializer
などの非同期 IO をサポートしていないカスタム シリアライザーを使用するには、KestrelServerOptions
を構成して、アプリケーションの同期 IO を有効にする必要があります。
次の例では、このアプローチを使用して、シリアル化用に JSON.NET (Newtonsoft.Json
) と Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet パッケージを構成する方法を示します。
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
services.AddMvc().AddNewtonsoftJson();
// Only needed if using HttpRequestData/HttpResponseData and a serializer that doesn't support asynchronous IO
// services.Configure<KestrelServerOptions>(options => options.AllowSynchronousIO = true);
})
.Build();
host.Run();
組み込みの HTTP モデル
組み込みの HTTP モデルでは、システムは受信した HTTP 要求メッセージを、関数に渡される HttpRequestData オブジェクトに変換します。 このオブジェクトは、Headers
、Cookies
、Identities
、URL
、メッセージ Body
(オプション) を含む、要求からのデータを提供します。 このオブジェクトは HTTP 要求の表現ですが、基になる HTTP リスナーまたは受信されたメッセージに直接接続されてはいません。
同様に、関数が返す HttpResponseData オブジェクトも、メッセージ StatusCode
、Headers
、およびメッセージ Body
(オプション) を含む、HTTP 応答を作成するために使用するデータを提供します。
次の例は、HttpRequestData
と HttpResponseData
の使い方を示しています。
[Function(nameof(HttpFunction))]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData req,
FunctionContext executionContext)
{
var logger = executionContext.GetLogger(nameof(HttpFunction));
logger.LogInformation("message logged");
var response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
response.WriteString("Welcome to .NET isolated worker !!");
return response;
}
ログ記録
ログに書き込むには、ILogger<T>
または ILogger
インスタンスを使用します。 ロガーは、ILogger<T>
または ILoggerFactory の依存関係の挿入を通じて取得できます。
public class MyFunction {
private readonly ILogger<MyFunction> _logger;
public MyFunction(ILogger<MyFunction> logger) {
_logger = logger;
}
[Function(nameof(MyFunction))]
public void Run([BlobTrigger("samples-workitems/{name}", Connection = "")] string myBlob, string name)
{
_logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {myBlob}");
}
}
ロガーは、関数に渡される FunctionContext オブジェクトから取得することもできます。 GetLogger<T> または GetLogger メソッドを呼び出し、ログが書き込まれるカテゴリの名前を表す文字列値を渡します。 カテゴリは通常、ログの書き込み元となる特定の関数の名前です。 カテゴリについて詳しくは、監視に関する記事をご覧ください。
ILogger<T>
と ILogger
のメソッドを使用して、LogWarning
や LogError
などのさまざまなログ レベルを記述します。 ログ レベルについて詳しくは、監視に関する記事をご覧ください。 フィルターを登録することで、コードに追加されたコンポーネントのログ レベルをカスタマイズできます。
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(services =>
{
// Registers IHttpClientFactory.
// By default this sends a lot of Information-level logs.
services.AddHttpClient();
})
.ConfigureLogging(logging =>
{
// Disable IHttpClientFactory Informational logs.
// Note -- you can also remove the handler that does the logging: https://github.com/aspnet/HttpClientFactory/issues/196#issuecomment-432755765
logging.AddFilter("System.Net.Http.HttpClient", LogLevel.Warning);
})
.Build();
Program.cs
でアプリを構成する一環として、ログにエラーを表示する方法の動作を定義することもできます。 既定の動作は、使用するビルダーの種類によって異なります。
HostBuilder
を使用するときは、既定では、コードによってスローされる例外が最終的に RpcException
でラップされることがあります。 この追加レイヤーを削除するには、ビルダーの構成の一環として、 EnableUserCodeException
プロパティを "true" に設定します。
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(builder => {}, options =>
{
options.EnableUserCodeException = true;
})
.Build();
host.Run();
Application Insights
開発者は、分離プロセス アプリケーションがログを直接 Application Insights に出力するように構成できます。 この動作により、ホストを介したログのリレーの既定の動作が置き換えられます。 .NET Aspire を使用している場合を除き、これらのログの出力方法を制御できるため、Application Insights の直接統合を構成することをお勧めします。
Application Insights 統合は、すべてのセットアップ エクスペリエンスで既定で有効になっているわけではありません。 一部のテンプレートでは、必要なパッケージとスタートアップ コードがコメントアウトされた Functions プロジェクトが作成されます。Application Insights 統合を使用する必要がある場合は、Program.cs
とプロジェクトの .csproj
ファイルでこれらの行のコメントを解除できます。 このセクションの残りの部分の手順で、統合を有効にする方法についても説明します。
プロジェクトが .NET Aspire オーケストレーションの一部である場合は、代わりに監視に OpenTelemetry を使用します。 .NET Aspire プロジェクト内で Application Insights の直接統合を有効にしないでください。 代わりに、Azure Monitor OpenTelemetry エクスポーターをサービスの既定のプロジェクトの一部として構成します。 Functions プロジェクトにおいて、.NET Aspire コンテキストで Application Insights 統合を使用すると、アプリケーションが起動時にエラーになります。
パッケージをインストールする
コードから Application Insights に直接ログを書き込むには、次のパッケージへの参照をプロジェクトに追加してください。
- Microsoft.Azure.Functions.Worker.ApplicationInsights バージョン 1.0.0 以降。
- Microsoft.ApplicationInsights.WorkerService。
次のコマンドを実行すると、これらの参照をプロジェクトに追加できます。
dotnet add package Microsoft.ApplicationInsights.WorkerService
dotnet add package Microsoft.Azure.Functions.Worker.ApplicationInsights
起動を構成する
パッケージがインストールされている状態で、次の例に示すように AddApplicationInsightsTelemetryWorkerService()
と ConfigureFunctionsApplicationInsights()
を Program.cs
ファイル内でのサービス構成時に呼び出す必要があります。
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(services => {
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
})
.Build();
host.Run();
ConfigureFunctionsApplicationInsights()
への呼び出しによって ITelemetryModule
が追加されますが、これは Functions で定義された ActivitySource
をリッスンします。 これで、分散トレースのサポートに必要な依存関係テレメトリが作成されます。 AddApplicationInsightsTelemetryWorkerService()
の詳細とその使用方法については、「Application Insights for Worker Service アプリケーション」を参照してください。
ログ レベルの管理
重要
Functions ホストと分離プロセス ワーカーには、ログ レベルなどの個別の構成があります。host.json の Application Insights 構成はワーカーからのログには影響しません。同様に、ワーカー コードで行われた構成は、ホストからのログ記録には影響しません。 シナリオによって両方のレイヤーでカスタマイズが必要な場合は、両方の場所で変更の適用が必要になる可能性があります。
アプリケーションの残りの部分は引き続き ILogger
と ILogger<T>
で動作します。 ただし、既定では、Application Insights SDK は、警告とそれより深刻なログのみをキャプチャするようにロガーに指示するログ フィルターを追加します。 この動作を無効にする場合は、サービス構成の一部としてフィルター規則を削除します。
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(services => {
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
})
.ConfigureLogging(logging =>
{
logging.Services.Configure<LoggerFilterOptions>(options =>
{
LoggerFilterRule defaultRule = options.Rules.FirstOrDefault(rule => rule.ProviderName
== "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
if (defaultRule is not null)
{
options.Rules.Remove(defaultRule);
}
});
})
.Build();
host.Run();
パフォーマンスの最適化
このセクションでは、コールド スタートに関するパフォーマンスを向上させるために有効にできるオプションの概要について説明します。
通常アプリでは、最新バージョンのコア依存関係を使用する必要があります。 少なくとも、プロジェクトを次のように更新する必要があります。
- Microsoft.Azure.Functions.Worker をバージョン 1.19.0 以降にアップグレードします。
- Microsoft.Azure.Functions.Worker.Sdk をバージョン 1.16.4 以降にアップグレードします。
- アプリで .NET Framework をターゲットにする場合を除き、
Microsoft.AspNetCore.App
にフレームワーク参照を追加します。
次のスニペットは、プロジェクト ファイルのコンテキストでのこの構成を示しています。
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.4" />
</ItemGroup>
プレースホルダー
プレースホルダーは、.NET 6 以降をターゲットにするアプリのコールド スタートを改善するプラットフォーム機能です。 この最適化を使用するには、次の手順を使用してプレースホルダーを明示的に有効にする必要があります。
前のセクションでの詳細説明のとおりに、最新の依存関係バージョンを使用するようにプロジェクト構成を更新します。
WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED
アプリケーション設定を1
に設定します。これを行うには、次に示す az functionapp config appsettings set コマンドを使用します。az functionapp config appsettings set -g <groupName> -n <appName> --settings 'WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED=1'
この例の中の
<groupName>
をリソース グループの名前で置き換え、<appName>
を関数アプリの名前で置き換えてください。関数アプリの
netFrameworkVersion
プロパティがプロジェクトのターゲット フレームワーク (.NET 6 以降である必要があります) と一致していることを確認します。 これを行うには、次に示す az functionapp config set コマンドを使用します。az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
この例の中の
<framework>
も、ターゲットの .NET バージョンに応じて適切なバージョン文字列 (v8.0
など) で置き換えてください。関数アプリが 64 ビット プロセスを使用するように構成されていることを確認します。これを行うには、次に示す az functionapp config set コマンドを使用します。
az functionapp config set -g <groupName> -n <appName> --use-32bit-worker-process false
重要
WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED
を 1
に設定するときは、他のすべての関数アプリ構成がすべて正しく設定されている必要があります。 このとおりでない場合は、関数アプリの起動に失敗する可能性があります。
最適化された Executor
関数 Executor は、呼び出しを実行するプラットフォームのコンポーネントです。 このコンポーネントの最適化されたバージョンは、SDK のバージョン 1.16.2 以降で既定で有効になっています。 それ以上の構成は必要ありません。
ReadyToRun
関数アプリは ReadyToRun バイナリとしてコンパイルできます。 ReadyToRun は、事前コンパイル形式であり、起動時のパフォーマンスを向上させることができます。これは、従量課金プランで実行される場合にコールド スタートの影響を軽減するのに役立ちます。 ReadyToRun は .NET 6 以降のバージョンで使用可能であり、Azure Functions ランタイムのバージョン 4.0 以降が必要です。
ReadyToRun では、ホスティング アプリのランタイム アーキテクチャに対してプロジェクトをビルドする必要があります。 これらが配置されていない場合は、起動時にアプリでエラーが発生します。 ランタイム識別子を次の表から選択してください。
オペレーティング システム | アプリは 32 ビットです1 | ランタイム識別子 |
---|---|---|
Windows | 正しい | win-x86 |
Windows | いいえ | win-x64 |
Linux | 正しい | 該当なし (サポートされていません) |
Linux | いいえ | linux-x64 |
1 他のパフォーマンス最適化の対象となるのは、64 ビット アプリのみです。
Windows アプリが 32 ビットか 64 ビットかをチェックするには、次の CLI コマンドを実行して、<group_name>
をリソース グループの名前に、<app_name>
をアプリケーションの名前に置き換えます。 "true" の出力は、アプリが 32 ビットであることを示し、"false" は 64 ビットであることを示します。
az functionapp config show -g <group_name> -n <app_name> --query "use32BitWorkerProcess"
同じ置換を使用して、次のコマンドでアプリケーションを 64 ビットに変更できます。
az functionapp config set -g <group_name> -n <app_name> --use-32bit-worker-process false`
プロジェクトを ReadyToRun としてコンパイルするには、<PublishReadyToRun>
および <RuntimeIdentifier>
要素を追加して、プロジェクト ファイルを更新します。 次の例は、Windows 64 ビットの関数アプリに公開するための構成を示しています。
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
<RuntimeIdentifier>
をプロジェクト ファイルの一部として設定しない場合は、これを発行ジェスチャ自体の一部として構成することもできます。 たとえば、Windows 64 ビットの関数アプリでは、.NET CLI コマンドは次のようになります。
dotnet publish --runtime win-x64
Visual Studio では、発行プロファイルの [ターゲット ランタイム] オプションが正しいランタイム識別子に設定されている必要があります。 既定値である [移植可能] に設定されているときは、ReadyToRun は使用されません。
Azure Functions へのデプロイ
関数コード プロジェクトを Azure にデプロイする場合、それは関数アプリ内または Linux コンテナー内で実行する必要があります。 コードをデプロイする前に、関数アプリとその他の必要な Azure リソースが存在している必要があります。
関数アプリを Linux コンテナー内でデプロイすることもできます。 詳細については、コンテナーと Azure Functions の使用に関するページを参照してください。
Azure リソースを作成する
関数アプリとその他の必要なリソースを Azure 内で作成するには、次のいずれかの方法を使用します。
- Visual Studio: Visual Studio でのコード発行プロセス中にリソースを自動的に作成できます。
- Visual Studio Code: Visual Studio Codeがサブスクリプションに接続し、アプリに必要なリソースを作成してから、コードを発行することができます。
- Azure CLI: Azure CLI を使用して、必要なリソースを Azure 内で作成できます。
- Azure PowerShell: Azure PowerShell を使用して、必要なリソースを Azure 内で作成できます。
- デプロイ テンプレート: 必要なリソースを Azure にデプロイする作業を、ARM テンプレートと Bicep ファイルを使用して自動化できます。 必要な設定がテンプレートに含まれていることを確認してください。
- Azure portal: 必要なリソースを Azure portal で作成できます。
アプリケーションの発行
関数アプリとその他の必要なリソースを Azure 内で作成したら、次のいずれかの方法を使用してコード プロジェクトを Azure にデプロイします。
- Visual Studio: 単純な手動デプロイを開発中に行います。
- Visual Studio Code: 単純な手動デプロイを開発中に行います。
- Azure Functions Core Tools: プロジェクト ファイルをコマンド ラインからデプロイします。
- 継続的デプロイ: 継続的メンテナンスのためにステージング スロットに頻繁にデプロイする場合に便利です。
- デプロイ テンプレート: ARM テンプレートまたは Bicep ファイルを使用して、パッケージのデプロイを自動化できます。
詳細については、「Azure Functions のデプロイ テクノロジ」を参照してください。
デプロイ ペイロード
多くのデプロイ方法で zip アーカイブが使用されます。 zip アーカイブを自分で作成する場合は、このセクションで示している構造に従う必要があります。 このとおりでない場合は、開発したアプリの起動時にエラーが発生することがあります。
デプロイ ペイロードは、外側の親フォルダーを除いて、dotnet publish
コマンドの出力と一致する必要があります。 zip アーカイブは、次のファイルから作成する必要があります。
.azurefunctions/
extensions.json
functions.metadata
host.json
worker.config.json
- プロジェクトの実行可能ファイル (コンソール アプリ)
- その実行可能ファイルと対になる他のサポート ファイルとディレクトリ
これらのファイルはビルド プロセスによって生成されるものであり、直接編集することを意図したものではありません。
zip アーカイブをデプロイ用に準備する場合は、出力ディレクトリの内容のみを圧縮し、外側のディレクトリ自体は圧縮しないでください。 アーカイブが現在の作業ディレクトリに抽出されたとき、上記のファイルがすぐに表示される必要があります。
デプロイ要件
Azure で .NET 関数を分離ワーカー モデルで実行するには、オペレーティング システムに応じて次のような要件があります。
- FUNCTIONS_WORKER_RUNTIME の値が
dotnet-isolated
に設定されている必要があります。 - netFrameworkVersion が目的のバージョンに設定されている必要があります。
関数アプリを Azure 内で作成するときに、前のセクションで示した方法を使用すると、これらの必要な設定が自動的に追加されます。 これらのリソースを、自動化のために ARM テンプレートまたは Bicep ファイルを使用して作成するときは、テンプレート内で設定されていることを確認する必要があります。
.NET Aspire (プレビュー)
.NET Aspire は、クラウドでの分散アプリケーションの開発を簡略化する独断的なスタックです。 プレビュー サポートを使用して、Aspire 9.0 オーケストレーションに .NET 8 および .NET 9 分離ワーカー モデル プロジェクトを登録することができます。 このセクションでは、登録の主要な要件について説明します。
この統合には、特定のセットアップが必要です。
- Aspire 9.0 以降と .NET 9 SDK を使用します。 Aspire 9.0 では、.NET 8 および .NET 9 フレームワークがサポートされています。
- Visual Studio を使用する場合は、バージョン 17.12 以降に更新してください。 Visual Studio 用 Functions ツールの最新バージョンも必要です。 更新プログラムを確認するには、[ツール]>[オプション] に移動し、[プロジェクトおよびソリューション] で [Azure Functions] を選択します。 [更新プログラムの確認] を選択し、指示に従って更新プログラムをインストールします。
- Aspire アプリ ホスト プロジェクトの場合:
- Aspire.Hosting.Azure.Functions を参照する必要があります。
- Functions プロジェクトへのプロジェクト参照が必要です。
- また、アプリ ホストの
Program.cs
において、IDistributedApplicationBuilder
でAddAzureFunctionsProject<TProject>()
を呼び出してプロジェクトを含める必要があります。 このメソッドは、他のプロジェクトの種類に使用するAddProject<TProject>()
の代わりに使用されます。AddProject<TProject>()
を使用するだけでは、Functions プロジェクトは正しく起動しません。
- Functions プロジェクトの場合:
- Microsoft.Azure.Functions.Worker と Microsoft.Azure.Functions.Worker.Sdk の 2.x バージョンを参照する必要があります。 また、
Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore
への参照もすべて 2.x バージョンに更新する必要があります。 Program.cs
で、ホスト インスタンスの起動のIHostApplicationBuilder
バージョン使用する必要があります。- Aspire サービスの既定値を使用する場合は、サービスの既定のプロジェクトへのプロジェクト参照を含める必要があります。
Program.cs
でIHostApplicationBuilder
をビルドする前に、builder.AddServiceDefaults()
の呼び出しも含める必要があります。 - "dotnet-isolated" のままにする必要がある
FUNCTIONS_WORKER_RUNTIME
設定を除き、local.settings.json
に構成を保持しないでください。 その他の構成は、アプリ ホスト プロジェクトを通じて設定する必要があります。 - Application Insights の直接統合はすべて削除する必要があります。 代わりに、Aspire での監視は、OpenTelemetry のサポートを通じて処理されます。
- Microsoft.Azure.Functions.Worker と Microsoft.Azure.Functions.Worker.Sdk の 2.x バージョンを参照する必要があります。 また、
次の例は、アプリ ホスト プロジェクトの最小の Program.cs
を示しています。
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject");
builder.Build().Run();
次の例は、Aspire で使用される Functions プロジェクトの最小の Program.cs
を示しています。
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = FunctionsApplication.CreateBuilder(args);
builder.AddServiceDefaults();
builder.ConfigureFunctionsWebApplication();
builder.Build().Run();
これには、この記事の他の Program.cs
例の多くで見られる既定の Application Insights 構成は含まれません。 代わりに、Aspire の OpenTelemetry 統合は、builder.AddServiceDefaults()
呼び出しによって構成されます。
.NET Aspire 統合に関する考慮事項とベスト プラクティス
Azure Functions で .NET Aspire を評価する場合は、次の点を考慮してください。
- .NET Aspire での Azure Functions のサポートは現在プレビュー段階です。 プレビュー期間中に、Aspire ソリューションを Azure に発行すると、Functions プロジェクトはイベントドリブン スケーリングなしで Azure Container Apps リソースとしてデプロイされます。 このモードでデプロイされたアプリでは、Azure Functions のサポートを利用できません。
- 現在、Aspire を使用したトリガーとバインドの構成は、特定の統合に制限されています。 詳細については、「Aspire を使用した接続構成」を参照してください。
Program.cs
で、ホスト インスタンスの起動のIHostApplicationBuilder
バージョン使用する必要があります。 これにより、builder.AddServiceDefaults()
を呼び出して、.NET Aspire サービスの既定を Functions プロジェクトに追加できます。- Aspire では、監視に OpenTelemetry が使用されます。 サービスの既定のプロジェクトを使用して Azure Monitor にテレメトリをエクスポートするように、Aspire を構成できます。 他の多くの Azure Functions コンテキストで、テレメトリ ワーカー サービスを登録することで、Application Insights との直接統合を含めることができます。 これは、Aspire では推奨されず、バージョン 2.22.0 の
Microsoft.ApplicationInsights.WorkerService
でランタイム エラーが発生する可能性があります。 Aspire を使用する場合は、Functions プロジェクトから Application Insights の直接統合をすべて削除する必要があります。 - Aspire オーケストレーションに登録されている Functions プロジェクトの場合、ほとんどのアプリケーション構成は、Aspire アプリ ホスト プロジェクトから取得する必要があります。 通常は、
FUNCTIONS_WORKER_RUNTIME
設定以外は、local.settings.json
で設定を行わないでください。 同じ環境変数がlocal.settings.json
と Aspire によって設定されている場合、Aspire バージョンがシステムによって使用されます。 local.settings.json
内の接続用にストレージ エミュレーターを構成しないでください。 多くの Functions スターター テンプレートには、AzureWebJobsStorage
の既定値としてエミュレーターが含まれています。 ただし、エミュレーターの構成で、一部の IDE に対して、Aspire により使用されるバージョンと競合する可能性のあるバージョンのエミュレーターを起動するように求められる場合があります。
Aspire を使用した接続構成
Azure Functions では、いくつかのコア動作にホスト ストレージ接続 (AzureWebJobsStorage
) が必要です。 アプリ ホスト プロジェクトで AddAzureFunctionsProject<TProject>()
を呼び出すと、既定の AzureWebJobsStorage
接続が作成され、Functions プロジェクトに提供されます。 この既定の接続では、ローカル開発の実行にストレージ エミュレーターが使用され、デプロイ時にストレージ アカウントが自動的にプロビジョニングされます。 追加の制御を行うには、Functions プロジェクト リソースで .WithHostStorage()
を呼び出して、この接続を置き換えることができます。
次の例は、ホスト ストレージを置き換えるアプリ ホスト プロジェクトの最小の Program.cs
を示しています。
var builder = DistributedApplication.CreateBuilder(args);
var myHostStorage = builder.AddAzureStorage("myHostStorage");
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
.WithHostStorage(myHostStorage);
builder.Build().Run();
Note
Aspire で発行モードのホスト ストレージがプロビジョニングされる場合、既定では、ストレージ アカウント共同作成者、ストレージ BLOB データ共同作成者、ストレージ キュー データ共同作成者、ストレージ テーブル データ共同作成者のロールに対してロールの割り当てが作成されます。
トリガーとバインドは、名前で接続を参照します。 一部の Aspire 統合では、プロジェクト リソースの WithReference()
を呼び出すことでこれらを提供できます。
Aspire 統合 | メモ |
---|---|
Azure BLOB | Aspire でリソースがプロビジョニングされる場合、既定では、ストレージ BLOB データ共同作成者、ストレージ キュー データ共同作成者、ストレージ テーブル データ共同作成者のロールに対してロールの割り当てが作成されます。 |
Azure キュー | Aspire でリソースがプロビジョニングされる場合、既定では、ストレージ BLOB データ共同作成者、ストレージ キュー データ共同作成者、ストレージ テーブル データ共同作成者のロールに対してロールの割り当てが作成されます。 |
Azure Event Hubs | Aspire でリソースがプロビジョニングされる場合、既定では、Azure Event Hubs データ所有者ロールを使用してロールの割り当てが作成されます。 |
Azure Service Bus | Aspire でリソースがプロビジョニングされる場合、既定では、Azure Service Bus データ所有者ロールを使用してロールの割り当てが作成されます。 |
次の例は、キュー トリガーを構成するアプリ ホスト プロジェクトの最小の Program.cs
を示しています。 この例では、対応するキュー トリガーの Connection
プロパティが "MyQueueTriggerConnection" に設定されています。
var builder = DistributedApplication.CreateBuilder(args);
var myAppStorage = builder.AddAzureStorage("myAppStorage").RunAsEmulator();
var queues = myAppStorage.AddQueues("queues");
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
.WithReference(queues, "MyQueueTriggerConnection");
builder.Build().Run();
その他の統合の場合は、WithReference
呼び出しによって別の方法で構成が設定され、Aspire クライアント統合で使用できるようになりますが、トリガーとバインドでは使用できません。 これらの統合では、WithEnvironment()
を呼び出して、解決するトリガーまたはバインドの接続情報を渡す必要があります。 次の例は、接続文字列式を公開するリソースの環境変数 "MyBindingConnection" を設定する方法を示しています。
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
.WithEnvironment("MyBindingConnection", otherIntegration.Resource.ConnectionStringExpression);
Aspire クライアント統合とトリガーおよびバインド システムの両方で接続を使用する必要がある場合は、WithReference()
と WithEnvironment()
の両方を構成できます。
一部のリソースでは、接続の構造が、ローカルで実行する場合と Azure に発行する場合とで異なる可能性があります。 前の例では、otherIntegration
はエミュレーターとして実行されるリソースである可能性があるため、ConnectionStringExpression
からエミュレーター接続文字列が返されます。 ただし、リソースが発行されると、Aspire により、ID ベースの接続が設定され、ConnectionStringExpression
からサービスの URI が返される可能性があります。 この場合、Azure Functions の ID ベースの接続を設定するには、別の環境変数名の指定が必要になる可能性があります。 次の例では、必要なサフィックスを条件付きで追加するため builder.ExecutionContext.IsPublishMode
が使用されています。
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
.WithEnvironment("MyBindingConnection" + (builder.ExecutionContext.IsPublishMode ? "__serviceUri" : ""), otherIntegration.Resource.ConnectionStringExpression);
シナリオによっては、ID ベースの接続に割り当てられるアクセス許可の調整が必要になる場合もあります。 ConfigureConstruct<T>()
メソッドを使用して、プロジェクトの発行時に、Aspire でインフラストラクチャが構成される方法をカスタマイズできます。
サポートされている接続形式と、これらの形式で必要なアクセス許可の詳細については、各バインドの参照ページを参照してください。
デバッグ
ローカルで Visual Studio または Visual Studio Code を使用して実行するときは .NET 分離ワーカー プロジェクトのデバッグを通常どおりに行うことができます。 ただし、期待どおりにならないデバッグ シナリオが 2 つあります。
Visual Studio を使用したリモート デバッグ
分離ワーカー プロセス アプリは Functions ランタイムの外部で実行されるため、リモート デバッガーを別のプロセスにアタッチする必要があります。 Visual Studio を使用したデバッグの詳細は、「リモート デバッグ」をご覧ください。
.NET Framework をターゲットにするときのデバッグ
分離されたプロジェクトが .NET Framework 4.8 をターゲットにしている場合は、デバッグを有効にするために手動の手順を実行する必要があります。 別のターゲット フレームワークを使用する場合、これらの手順は必要ありません。
アプリは、最初の操作として FunctionsDebugger.Enable();
への呼び出しで開始する必要があります。 これは、HostBuilder を初期化する前に Main()
メソッドで発生します。 Program.cs
ファイルは次のようになります。
using System;
using System.Diagnostics;
using Microsoft.Extensions.Hosting;
using Microsoft.Azure.Functions.Worker;
using NetFxWorker;
namespace MyDotnetFrameworkProject
{
internal class Program
{
static void Main(string[] args)
{
FunctionsDebugger.Enable();
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.Build();
host.Run();
}
}
}
次に、.NET Framework デバッガーを使用してプロセスに手動でアタッチする必要があります。 Visual Studio は、分離ワーカー プロセスの .NET Framework アプリに対してはまだ自動的にこれを行いません。"デバッグの開始" 操作は避ける必要があります。
プロジェクト ディレクトリ (またはそのビルド出力ディレクトリ) で、次を実行します。
func host start --dotnet-isolated-debug
これでワーカーが開始され、プロセスは次のメッセージを表示して停止します。
Azure Functions .NET Worker (PID: <process id>) initialized in debug mode. Waiting for debugger to attach...
ここで、<process id>
はワーカー プロセスの ID です。 これで、Visual Studio を使用して、プロセスに手動でアタッチできるようになりました。 この操作の手順については、実行中のプロセスにアタッチする方法に関する記事を参照してください。
デバッガーがアタッチされると、プロセスの実行が再開され、デバッグできるようになります。
プレビュー .NET バージョン
一般公開リリースの前に .NET のバージョンが "プレビュー" または "Go-live" 状態でリリースされることがあります。 これらの状態の詳細については、 .NET 公式サポート ポリシー を参照してください。
ローカルの Functions プロジェクトから特定のリリースをターゲットにすることもできますが、Azure でホストされている関数アプリでは、そのリリースが利用できない可能性があります。 Azure Functions は、このセクションで説明する "プレビュー" または "Go-live "リリースでのみ使用できます。
Azure Functions は現在、"プレビュー" または"Go-live" の .NET リリースでは動作しません。 使用できる一般公開リリースの一覧については、サポートされているバージョン を参照してください。
プレビュー .NET SDK の使用
.NET のプレビュー バージョンで Azure Functions を使うには、次の方法でプロジェクトを更新する必要があります。
- 関連する .NET SDK バージョンを開発環境にインストールする
.csproj
ファイルのTargetFramework
設定を変更する
Azure の関数アプリにデプロイする場合は、そのアプリでフレームワークが使用できるようにする必要があります。 プレビュー期間中、ツールとエクスペリエンスによっては、新しいプレビュー バージョンがオプションとして表示されない場合があります。 プレビュー バージョンが、たとえば Azure portal に表示されない場合は、REST API、Bicep テンプレート、または Azure CLI を使用して、そのバージョンを手動で構成することができます。
Windows でホストされているアプリの場合は、次の Azure CLI コマンドを使用します。 <groupName>
をリソース グループの名前に置き換え、<appName>
を関数アプリの名前に置き換えます。 <framework>
を適切なバージョン文字列 (たとえば v8.0
) に置き換えます。
az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
.NET のプレビュー バージョンを使用する場合の考慮事項
.NET のプレビュー バージョンで Functions を使う場合、次の考慮事項に注意してください。
関数を Visual Studio で作成するときは、Visual Studio Preview を使う必要があります。この製品では .NET プレビュー SDK を使用する Azure Functions プロジェクトの構築がサポートされます。
Functions のツールとテンプレートが最新であることを確認します。 ツールを更新する手順は次のとおりです。
- [ツール]>[オプション] に移動し、[プロジェクトおよびソリューション] で [Azure Functions] を選択します。
- [更新プログラムの確認] を選択し、指示に従って更新プログラムをインストールします。
プレビュー期間中は、開発者の環境の .NET プレビューのバージョンが、ホストされているサービスよりも新しいバージョンであることもあります。 これが原因で、関数アプリがデプロイ時に失敗する可能性があります。 これに対処するには、使用する SDK のバージョンを
global.json
で指定します。dotnet --list-sdks
コマンドを実行して、ローカル開発で現在使用しているプレビュー バージョンを確認します。dotnet new globaljson --sdk-version <SDK_VERSION> --force
コマンドを実行します。<SDK_VERSION>
はローカルで使用しているバージョンです。 たとえば、dotnet new globaljson --sdk-version dotnet-sdk-8.0.100-preview.7.23376.3 --force
を実行するとプロジェクトのビルド時に .NET 8 Preview 7 SDK がシステムによって使用されます。
Note
プレビュー フレームワークの Just-In-Time 読み込みが理由で、Windows 上で実行される関数アプリのコールド スタート時間が以前の GA バージョンに比べて長くなる可能性があることに注意してください。