このガイドでは、Durable Functions アプリケーションをインプロセス モデルから分離ワーカー モデルに移行する方法について説明します。
Warnung
インプロセス モデルのサポートは 、2026 年 11 月 10 日に終了します。 継続的なサポートと新機能へのアクセスのために、分離されたワーカー モデルに移行します。
移行する理由
インプロセス モデルのサポート終了
Microsoft は、.NET Azure Functionsのインプロセス モデルが 2026 年 11 月 10 日にサポート終了になると発表しました。 この日付より後:
- セキュリティ更新プログラムは提供されません
- バグ修正はリリースされません
- 新しい機能は、分離されたワーカー モデルでのみ使用できます
分離ワーカー モデルの利点
分離ワーカー モデルへの移行には、次の利点があります。
| メリット | 説明 |
|---|---|
| アセンブリの競合なし | コードは別のプロセスで実行され、バージョンの競合を排除します |
| 完全なプロセス制御 | を使用してスタートアップ、構成、ミドルウェアを制御する Program.cs |
| 標準 DI パターン | 使い慣れた.NET依存関係の挿入を使用する |
| .NETバージョンの柔軟性 | LTS、STS、および .NET Framework のサポート |
| ミドルウェアのサポート | 完全な ASP.NET Core ミドルウェア パイプライン |
| パフォーマンスの向上 | ASP.NET Core の HTTP トリガー統合 |
| プラットフォームのサポート | Flex 従量課金プランと.NET Aspireへのアクセス |
[前提条件]
移行を開始する前に、次の前提条件があることを確認してください。
- Azure Functions Core Tools v4.x 以降
- .NET 8.0 SDK (またはターゲット .NET バージョン)
- Visual Studio 2022 または VS Code with Azure Functions extension
- Durable Functionsの概念に関する知識
移行の概要
移行プロセスには、次の主な手順が含まれます。
- 移行するアプリを特定する
- プロジェクト ファイルを更新する
- Program.csの追加
- パッケージ参照を更新する
- 関数コードを更新する
- local.settings.jsonの更新
- ローカルでテストする
Azure
移行するアプリを特定する
このAzure PowerShell スクリプトを使用して、インプロセス モデルを使用するサブスクリプション内の関数アプリを検索します。
$FunctionApps = Get-AzFunctionApp
$AppInfo = @{}
foreach ($App in $FunctionApps)
{
if ($App.Runtime -eq 'dotnet')
{
$AppInfo.Add($App.Name, $App.Runtime)
}
}
$AppInfo
ランタイムとして dotnet を表示するアプリは、インプロセス モデルを使用します。
dotnet-isolatedを使用するアプリでは、分離された worker モデルが既に使用されています。
プロジェクト ファイルを更新する
ビフォー (処理中)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.1" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DurableTask" Version="2.13.0" />
</ItemGroup>
</Project>
後で(隔離された作業者)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<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.17.2" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.1" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.14.1" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext"/>
</ItemGroup>
</Project>
主な変更点
-
<OutputType>Exe</OutputType>の追加 - 分離されたワーカーは実行可能ファイルです -
<FrameworkReference Include="Microsoft.AspNetCore.App" />の追加 - ASP.NET Core統合用 -
Microsoft.NET.Sdk.FunctionsをMicrosoft.Azure.Functions.Worker.*パッケージに置き換える -
Microsoft.Azure.WebJobs.Extensions.DurableTaskをMicrosoft.Azure.Functions.Worker.Extensions.DurableTaskに置き換えます
Program.csの追加
プロジェクト ルートに新しい Program.cs ファイルを作成します。
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services => {
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
})
.Build();
host.Run();
カスタム サービスを使用する
FunctionsStartup クラスがある場合は、その構成をProgram.csに移動します。
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services => {
// Application Insights
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
// Your custom services (previously in FunctionsStartup)
services.AddSingleton<IMyService, MyService>();
services.AddHttpClient<IApiClient, ApiClient>();
})
.Build();
host.Run();
FunctionsStartup の削除
Startup.csで[assembly: FunctionsStartup(...)]がある場合は、構成を Program.cs に移動した後で削除します。
パッケージ参照を更新する
Durable Functions パッケージの変更
| インプロセス パッケージ | 分離ワーカー パッケージ |
|---|---|
Microsoft.Azure.WebJobs.Extensions.DurableTask |
Microsoft.Azure.Functions.Worker.Extensions.DurableTask |
Microsoft.DurableTask.SqlServer.AzureFunctions |
Microsoft.Azure.Functions.Worker.Extensions.DurableTask.SqlServer |
Microsoft.Azure.DurableTask.Netherite.AzureFunctions |
Microsoft.Azure.Functions.Worker.Extensions.DurableTask.Netherite |
拡張機能パッケージの一般的な変更
| 進行中 | アイソレートワーカー |
|---|---|
Microsoft.Azure.WebJobs.Extensions.Storage |
Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs、.Queues、.Tables |
Microsoft.Azure.WebJobs.Extensions.CosmosDB |
Microsoft.Azure.Functions.Worker.Extensions.CosmosDB |
Microsoft.Azure.WebJobs.Extensions.ServiceBus |
Microsoft.Azure.Functions.Worker.Extensions.ServiceBus |
Microsoft.Azure.WebJobs.Extensions.EventHubs |
Microsoft.Azure.Functions.Worker.Extensions.EventHubs |
Microsoft.Azure.WebJobs.Extensions.EventGrid |
Microsoft.Azure.Functions.Worker.Extensions.EventGrid |
Important
Microsoft.Azure.WebJobs.* 名前空間と Microsoft.Azure.Functions.Extensions への参照をプロジェクトから削除します。
関数コードを更新する
名前空間の変更
// Before (In-Process)
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
// After (Isolated Worker)
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.DurableTask;
using Microsoft.DurableTask.Client;
using Microsoft.DurableTask.Entities;
関数属性の変更
// Before (In-Process)
[FunctionName("MyOrchestrator")]
// After (Isolated Worker)
[Function(nameof(MyOrchestrator))]
オーケストレーター関数の変更
Before (In-Process):
[FunctionName("OrderOrchestrator")]
public static async Task<OrderResult> RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context,
ILogger log)
{
var order = context.GetInput<Order>();
await context.CallActivityAsync("ValidateOrder", order);
await context.CallActivityAsync("ProcessPayment", order.Payment);
await context.CallActivityAsync("ShipOrder", order);
return new OrderResult { Success = true };
}
アフター(アイソレーテッドワーカー):
[Function(nameof(OrderOrchestrator))]
public static async Task<OrderResult> OrderOrchestrator(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
ILogger logger = context.CreateReplaySafeLogger(nameof(OrderOrchestrator));
var order = context.GetInput<Order>();
await context.CallActivityAsync("ValidateOrder", order);
await context.CallActivityAsync("ProcessPayment", order.Payment);
await context.CallActivityAsync("ShipOrder", order);
return new OrderResult { Success = true };
}
主な違い
| 特徴 | 処理中 | 孤立作業者 |
|---|---|---|
| コンテキストの種類 | IDurableOrchestrationContext |
TaskOrchestrationContext |
| Logger |
ILogger パラメーター |
context.CreateReplaySafeLogger() |
| 特性 | [FunctionName] |
[Function] |
アクティビティ関数の変更
進行中の内容:
[FunctionName("ValidateOrder")]
public static bool ValidateOrder(
[ActivityTrigger] Order order,
ILogger log)
{
log.LogInformation("Validating order {OrderId}", order.Id);
return order.Items.Any() && order.TotalAmount > 0;
}
後 (孤立した作業者):
[Function(nameof(ValidateOrder))]
public static bool ValidateOrder(
[ActivityTrigger] Order order,
FunctionContext executionContext)
{
ILogger logger = executionContext.GetLogger(nameof(ValidateOrder));
logger.LogInformation("Validating order {OrderId}", order.Id);
return order.Items.Any() && order.TotalAmount > 0;
}
クライアント関数の変更
以前(進行中):
[FunctionName("StartOrder")]
public static async Task<IActionResult> StartOrder(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req,
[DurableClient] IDurableOrchestrationClient client,
ILogger log)
{
var order = await req.ReadFromJsonAsync<Order>();
string instanceId = await client.StartNewAsync("OrderOrchestrator", order);
return client.CreateCheckStatusResponse(req, instanceId);
}
アフター (Isolated Worker):
[Function("StartOrder")]
public static async Task<HttpResponseData> StartOrder(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req,
[DurableClient] DurableTaskClient client,
FunctionContext executionContext)
{
ILogger logger = executionContext.GetLogger("StartOrder");
var order = await req.ReadFromJsonAsync<Order>();
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
nameof(OrderOrchestrator),
order
);
return await client.CreateCheckStatusResponseAsync(req, instanceId);
}
クライアントの種類の変更
| 進行中 | アイソレートワーカー |
|---|---|
IDurableOrchestrationClient |
DurableTaskClient |
StartNewAsync() |
ScheduleNewOrchestrationInstanceAsync() |
CreateCheckStatusResponse() |
CreateCheckStatusResponseAsync() |
HttpRequest / IActionResult |
HttpRequestData / HttpResponseData |
ポリシーの変更を再試行する
インプロセスはRetryOptionsとCallActivityWithRetryAsyncを使用します。 分離ワーカーは、TaskOptionsと標準のCallActivityAsyncを使用します。
Before (In-Process):
var retryOptions = new RetryOptions(
firstRetryInterval: TimeSpan.FromSeconds(5),
maxNumberOfAttempts: 3);
string result = await context.CallActivityWithRetryAsync<string>(
"MyActivity", retryOptions, input);
アフター (Isolated Worker):
var retryOptions = new TaskOptions(
new TaskRetryOptions(new RetryPolicy(
maxNumberOfAttempts: 3,
firstRetryInterval: TimeSpan.FromSeconds(5))));
string result = await context.CallActivityAsync<string>(
"MyActivity", input, retryOptions);
エンティティ関数の変更
Before (In-Process):
[FunctionName(nameof(Counter))]
public static void Counter([EntityTrigger] IDurableEntityContext ctx)
{
switch (ctx.OperationName.ToLowerInvariant())
{
case "add":
ctx.SetState(ctx.GetState<int>() + ctx.GetInput<int>());
break;
case "get":
ctx.Return(ctx.GetState<int>());
break;
}
}
アフター (Isolated Worker):
[Function(nameof(Counter))]
public static Task Counter([EntityTrigger] TaskEntityDispatcher dispatcher)
{
return dispatcher.DispatchAsync<CounterEntity>();
}
public class CounterEntity
{
public int Value { get; set; }
public void Add(int amount) => Value += amount;
public int Get() => Value;
}
完全な API リファレンス
次の表は、インプロセス 2.x SDK と分離されたワーカー SDK API の間の包括的なマッピングを示しています。
クライアント API
| インプロセス中 (2.x) | アイソレートワーカー |
|---|---|
IDurableOrchestrationClient |
DurableTaskClient |
IDurableOrchestrationClient.StartNewAsync |
DurableTaskClient.ScheduleNewOrchestrationInstanceAsync |
IDurableOrchestrationClient.GetStatusAsync |
DurableTaskClient.GetInstanceAsync |
IDurableOrchestrationClient.ListInstancesAsync |
DurableTaskClient.GetAllInstancesAsync |
IDurableOrchestrationClient.TerminateAsync |
DurableTaskClient.TerminateInstanceAsync |
IDurableOrchestrationClient.SuspendAsync |
DurableTaskClient.SuspendInstanceAsync |
IDurableOrchestrationClient.ResumeAsync |
DurableTaskClient.ResumeInstanceAsync |
IDurableOrchestrationClient.RaiseEventAsync |
DurableTaskClient.RaiseEventAsync |
IDurableOrchestrationClient.RewindAsync |
DurableTaskClient.RewindInstanceAsync |
IDurableOrchestrationClient.RestartAsync |
DurableTaskClient.RestartAsync |
IDurableOrchestrationClient.PurgeInstanceHistoryAsync |
DurableTaskClient.PurgeInstanceAsync または PurgeAllInstancesAsync |
IDurableOrchestrationClient.CreateCheckStatusResponse |
DurableTaskClient.CreateCheckStatusResponseAsync (拡張メソッド、 HttpRequestDataを受け取ります) |
IDurableOrchestrationClient.WaitForCompletionOrCreateCheckStatusResponseAsync |
DurableTaskClient.WaitForCompletionOrCreateCheckStatusResponseAsync(拡張メソッド、timeoutCancellationTokenに置き換えられます) |
IDurableOrchestrationClient.CreateHttpManagementPayload |
DurableTaskClient.CreateHttpManagementPayload (拡張メソッド) |
IDurableOrchestrationClient.MakeCurrentAppPrimaryAsync |
Removed |
IDurableOrchestrationClient.GetStatusAsync(IEnumerable<string>) |
削除。 ループ内で GetInstanceAsync を使用するか、クエリ フィルターを使用して GetAllInstancesAsync します。 |
IDurableOrchestrationClient.PurgeInstanceHistoryAsync(IEnumerable<string>) |
削除。 ループ内で PurgeInstanceAsync を使用するか、フィルターを使用して PurgeAllInstancesAsync します。 |
IDurableOrchestrationClient.RaiseEventAsync ( taskHubName に関連したクロスタスクハブのオーバーロード) |
削除。 同じタスクハブのイベント発生のみがサポートされています。 |
IDurableEntityClient.SignalEntityAsync |
DurableTaskClient.Entities.SignalEntityAsync |
IDurableEntityClient.SignalEntityAsync ( taskHubName、connectionName によるクロスタスクハブオーバーロード) |
削除。 同じタスク ハブ エンティティ操作のみがサポートされます。 |
IDurableEntityClient.ReadEntityStateAsync |
DurableTaskClient.Entities.GetEntityAsync |
IDurableEntityClient.ReadEntityStateAsync ( taskHubName、 connectionName を使用したタスク ハブ間のオーバーロード) |
削除。 同じタスク ハブ エンティティ操作のみがサポートされます。 |
IDurableEntityClient.ListEntitiesAsync |
DurableTaskClient.Entities.GetAllEntitiesAsync |
IDurableEntityClient.CleanEntityStorageAsync |
DurableTaskClient.Entities.CleanEntityStorageAsync (bool パラメーターの代わりにオブジェクト CleanEntityStorageRequest 受け取ります) |
DurableOrchestrationStatus |
OrchestrationMetadata |
DurableOrchestrationStatus.History |
状態オブジェクトから削除されました。
DurableTaskClient.GetOrchestrationHistoryAsync を代わりに使用します。 |
PurgeHistoryResult |
PurgeResult |
OrchestrationStatusQueryCondition |
OrchestrationQuery |
OrchestrationStatusQueryResult |
AsyncPageable<OrchestrationMetadata> |
オーケストレーション コンテキスト API
| インプロセス中 (2.x) | アイソレートワーカー |
|---|---|
IDurableOrchestrationContext |
TaskOrchestrationContext |
IDurableOrchestrationContext.GetInput<T>() |
TaskOrchestrationContext.GetInput<T>() またはパラメーターとして入力を挿入します。 MyOrchestration([OrchestrationTrigger] TaskOrchestrationContext context, T input) |
IDurableOrchestrationContext.SetOutput |
削除。 オーケストレーター関数の戻り値を使用します。 |
IDurableOrchestrationContext.CallActivityWithRetryAsync |
TaskOrchestrationContext.CallActivityAsync 再試行の詳細については、 TaskOptions パラメーターを指定します。 |
IDurableOrchestrationContext.CallSubOrchestratorWithRetryAsync |
TaskOrchestrationContext.CallSubOrchestratorAsync 再試行の詳細については、 TaskOptions パラメーターを指定します。 |
IDurableOrchestrationContext.CallHttpAsync |
TaskOrchestrationContext.CallHttpAsync |
IDurableOrchestrationContext.CreateTimer<T>(DateTime, T, CancellationToken) |
TaskOrchestrationContext.CreateTimer(DateTime, CancellationToken)。 State パラメーターが削除されました。 |
IDurableOrchestrationContext.WaitForExternalEvent(string) (非ジェネリック) |
削除。
WaitForExternalEvent<T>(string, CancellationToken) を使用してください。 |
IDurableOrchestrationContext.WaitForExternalEvent<T>(string, TimeSpan, T) ( defaultValueあり) |
削除。
TaskCanceledExceptionをタイムアウト時にスローするWaitForExternalEvent<T>(string, TimeSpan, CancellationToken)を使用します。 |
IDurableOrchestrationContext.ParentInstanceId |
TaskOrchestrationContext.Parent.InstanceId |
IDurableOrchestrationContext.CreateReplaySafeLogger(ILogger) |
TaskOrchestrationContext.CreateReplaySafeLogger<T>() または TaskOrchestrationContext.CreateReplaySafeLogger(string) |
IDurableOrchestrationContext.CreateEntityProxy<T> |
削除。
Entities.CallEntityAsyncまたはEntities.SignalEntityAsyncを直接使用します。 |
IDurableOrchestrationContext.CallEntityAsync |
TaskOrchestrationContext.Entities.CallEntityAsync |
IDurableOrchestrationContext.SignalEntity |
TaskOrchestrationContext.Entities.SignalEntityAsync |
IDurableOrchestrationContext.LockAsync |
TaskOrchestrationContext.Entities.LockEntitiesAsync |
IDurableOrchestrationContext.IsLocked |
TaskOrchestrationContext.Entities.InCriticalSection() |
RetryOptions |
TaskOptions と TaskRetryOptions |
DurableActivityContext |
同等の値はありません |
DurableActivityContext.GetInput<T>() |
パラメーターとして入力を挿入します。 MyActivity([ActivityTrigger] T input) |
DurableHttpRequest (WebJobs 名前空間) |
DurableHttpRequest (Microsoft.Azure.Functions.Worker.Extensions.DurableTask.Http 名前空間) |
DurableHttpResponse (WebJobs 名前空間) |
DurableHttpResponse (Microsoft.Azure.Functions.Worker.Extensions.DurableTask.Http 名前空間) |
エンティティAPI群
| インプロセス中 (2.x) | アイソレートワーカー |
|---|---|
IDurableEntityContext |
TaskEntityContext |
IDurableEntityContext.EntityName |
TaskEntityContext.Id.Name |
IDurableEntityContext.EntityKey |
TaskEntityContext.Id.Key |
IDurableEntityContext.OperationName |
TaskEntityOperation.Name |
IDurableEntityContext.FunctionBindingContext |
削除。 入力パラメーターとして FunctionContext を追加します。 |
IDurableEntityContext.HasState |
TaskEntityOperation.State.HasState |
IDurableEntityContext.GetState |
TaskEntityOperation.State.GetState |
IDurableEntityContext.SetState |
TaskEntityOperation.State.SetState |
IDurableEntityContext.DeleteState |
TaskEntityOperation.State.SetState(null) |
IDurableEntityContext.GetInput |
TaskEntityOperation.GetInput |
IDurableEntityContext.Return |
削除。 代わりにメソッドの戻り値を使用してください。 |
IDurableEntityContext.SignalEntity |
TaskEntityContext.SignalEntity。 スケジュールされたシグナルでは、SignalEntityOptions.SignalTime パラメーターオーバーロードの代わりにDateTimeが使用されます。 |
IDurableEntityContext.StartNewOrchestration |
TaskEntityContext.ScheduleNewOrchestration。 インスタンス ID は、文字列パラメーターではなく StartOrchestrationOptions.InstanceId を使用して設定されます。 |
IDurableEntityContext.DispatchAsync |
TaskEntityDispatcher.DispatchAsync。 コンストラクターのパラメーターが削除されました。代わりに標準 DI を使用してください。 |
IDurableEntityContext.BatchSize |
Removed |
IDurableEntityContext.BatchPosition |
Removed |
動作の変更
-
シリアル化: 既定のシリアライザーが
Newtonsoft.JsonからSystem.Text.Jsonに変更されました。 詳細については、「Durable Functions を参照してください。
Warnung
ContinueAsNew の既定の変更: preserveUnprocessedEvents パラメーターの既定値が false (2.x) から true (分離) に変更されました。 オーケストレーションで ContinueAsNew を使用し、破棄される未処理のイベントに依存している場合は、 preserveUnprocessedEvents: falseを明示的に渡します。
注
RestartAsync の既定の変更: restartWithNewInstanceId パラメーターの既定値が true (2.x) から false (分離) に変更されました。 コードが RestartAsync を呼び出し、生成される新しいインスタンス ID に依存している場合は、 restartWithNewInstanceId: trueを明示的に渡します。
-
エンティティ プロキシの削除: 分離されたワーカーでは、
CreateEntityProxy<T>および型指定されたSignalEntityAsync<TEntityInterface>(Action<T>)デリゲート オーバーロードは使用できません。 型指定されたプロキシ インターフェイスを使用する代わりに、文字列ベースの操作名を使用してEntities.CallEntityAsyncまたはEntities.SignalEntityAsyncを直接呼び出します。 -
WaitForCompletionOrCreateCheckStatusResponseAsync:
timeoutパラメーターが削除されました。 代わりに、取り消しタイムアウトのCancellationTokenを使用してください。 -
タスクハブ間の操作が削除されました:
taskHubName、connectionName、RaiseEventAsync上でSignalEntityAsyncパラメーターとReadEntityStateAsyncパラメーターを受け入れていたインプロセスオーバーロードは、分離されたワーカーで利用できません。 同じタスク ハブ操作のみがサポートされます。 -
ID によるバッチ操作が削除されました。インプロセス
GetStatusAsync(IEnumerable<string>)およびPurgeInstanceHistoryAsync(IEnumerable<string>)オーバーロードは、分離されたワーカーでは使用できません。GetAllInstancesAsyncフィルターを使用するか、GetInstanceAsync/PurgeInstanceAsyncを個別に呼び出します。 -
移動されたオーケストレーション履歴:
DurableOrchestrationStatus.History(埋め込みJArray) は、状態オブジェクトの一部ではなくなりました。 オーケストレーション履歴を取得するには、個別のDurableTaskClient.GetOrchestrationHistoryAsyncAPI を使用します。 -
Entity DispatchAsync コンストラクターのパラメーターが削除されました:
DispatchAsync<T>(params object[])コンストラクター パラメーターのオーバーロードは使用できません。 エンティティ クラスは、標準の依存関係の挿入によってアクティブ化されます。 エンティティの依存関係をProgram.csに登録します。 -
エンティティ クエリ フィルターの変更:
EntityQuery.EntityNameはEntityQuery.InstanceIdStartsWithに置き換えられ、EntityQuery.IncludeDeletedはEntityQuery.IncludeTransientに置き換えられます。 -
CleanEntityStorageAsync シグネチャの変更: 分離バージョンでは、
(bool removeEmptyEntities, bool releaseOrphanedLocks, CancellationToken)の代わりに、CleanEntityStorageRequestプロパティとRemoveEmptyEntitiesプロパティを持つReleaseOrphanedLocksオブジェクトを受け取ります。 -
分離されたワーカーの新しい API:
DurableTaskClient.GetOrchestrationHistoryAsyncとTaskOrchestrationContext.GetFunctionContext()拡張メソッドは、分離されたワーカーで使用できますが、インプロセスに相当するものはありません。
local.settings.jsonの更新
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;Authentication=None"
}
}
キーの変更は、FUNCTIONS_WORKER_RUNTIMEからdotnetにdotnet-isolatedされます。
ローカルでテストする
エミュレーターを起動する
docker run -d -p 8080:8080 -p 8082:8082 mcr.microsoft.com/dts/dts-emulator:latest
関数アプリを実行する
func start
機能を検証する
すべてのオーケストレーション、アクティビティ、エンティティをテストして、正しく動作することを確認します。
- HTTP トリガーを使用してオーケストレーションを開始する
- オーケストレーションの状態を監視する
- アクティビティの実行順序を確認する
- エンティティ操作 (該当する場合) をテストする
- Application Insights テレメトリを確認する
Azureにデプロイする
推奨: デプロイ スロットを使用する
デプロイ スロットを使用してダウンタイムを最小限に抑えます。
- 関数アプリのステージング スロットを作成します。
-
ステージング スロットの構成を更新します。
-
FUNCTIONS_WORKER_RUNTIMEをdotnet-isolatedに設定します。 - 必要に応じて.NETスタック バージョンを更新します。
-
- 移行されたコード をステージング スロットにデプロイします。
- ステージング スロットで十分にテストします。
- スロット スワップを実行 し、変更を本番環境に反映します。
アプリケーション設定を更新する
Azure ポータルまたは CLI を使用して、次の手順を実行します。
az functionapp config appsettings set \
--name <FUNCTION_APP_NAME> \
--resource-group <RESOURCE_GROUP> \
--settings FUNCTIONS_WORKER_RUNTIME=dotnet-isolated
スタックの構成を更新
別の.NET バージョンを対象とする場合:
az functionapp config set \
--name <FUNCTION_APP_NAME> \
--resource-group <RESOURCE_GROUP> \
--net-framework-version v8.0
移行に関する一般的な問題
問題: アセンブリの読み込みエラー
現象:Could not load file or assembly エラー。
Solution: すべてのMicrosoft.Azure.WebJobs.* パッケージ参照を削除し、それらを分離型ワーカーに置き換えてください。
問題: バインド属性が見つかりません
症状:The type or namespace 'QueueTrigger' could not be found
ソリューション: 適切な拡張パッケージを追加し、ステートメントを使用して更新します。
// Add using statement
using Microsoft.Azure.Functions.Worker;
// Install package
// dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues
問題: IDurableOrchestrationContext が見つかりません
症状:The type or namespace 'IDurableOrchestrationContext' could not be found
ソリューション:TaskOrchestrationContextに置き換えます。
using Microsoft.DurableTask;
[Function(nameof(MyOrchestrator))]
public static async Task MyOrchestrator([OrchestrationTrigger] TaskOrchestrationContext context)
{
// ...
}
問題: JSON シリアル化の違い
症状: シリアル化エラーまたは予期しないデータ形式
ソリューション: 分離モデルでは、既定で System.Text.Json が使用されます。
Program.csでシリアル化を構成します。
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services => {
services.Configure<JsonSerializerOptions>(options => {
options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});
})
.Build();
代わりに Newtonsoft.Json を使用するには:
services.Configure<WorkerOptions>(options => {
options.Serializer = new NewtonsoftJsonObjectSerializer();
});
問題: カスタム シリアル化設定の移行
症状: インプロセス モデルの IMessageSerializerSettingsFactory を使用して、オーケストレーションの入力、出力、またはエンティティ状態の JSON シリアル化をカスタマイズし、分離されたワーカーで同等のものが必要です。
ソリューション:IMessageSerializerSettingsFactory インターフェイスは、分離ワーカーでは使用できません。 代わりに、 Program.csでワーカー レベルのシリアライザーを構成します。
処理中 (進行中) 前:
// Startup.cs
[assembly: FunctionsStartup(typeof(MyStartup))]
public class MyStartup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<IMessageSerializerSettingsFactory, CustomSerializerSettingsFactory>();
}
}
アフター (Isolated Worker):
// Program.cs
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.Configure<WorkerOptions>(options =>
{
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.None,
DateFormatHandling = DateFormatHandling.IsoDateFormat,
};
options.Serializer = new NewtonsoftJsonObjectSerializer(settings);
});
})
.Build();
注
この方法では、Newtonsoft.Json および Azure.Core.Serialization NuGet パッケージが必要です。
WorkerOptions.Serializer設定は、Durable Functions拡張機能によってシリアル化されるすべての設定にグローバルに適用されます。 詳細については、「 Durable Functions におけるシリアル化と永続化」を参照してください。
Checklist
完全な移行を確認するには、次のチェックリストを使用します。
- プロジェクト ファイルを
<OutputType>Exe</OutputType>で更新しました -
Microsoft.NET.Sdk.Functionsをワーカー パッケージに置き換えた -
Microsoft.Azure.WebJobs.Extensions.DurableTaskを分離パッケージに置き換えました - ホスト構成を使用して
Program.csを作成しました - クラス
FunctionsStartup削除 (存在する場合) - すべての
[FunctionName]を[Function]に更新しました -
IDurableOrchestrationContextに置き換えられましたTaskOrchestrationContext -
IDurableOrchestrationClientに置き換えられましたDurableTaskClient - ログの更新を行い、DI または
FunctionContextを使用する -
local.settings.jsonランタイムを使用してdotnet-isolatedを更新しました - すべての
Microsoft.Azure.WebJobs.*using ステートメントを削除しました - using ステートメントを追加しました
Microsoft.Azure.Functions.Worker -
CreateEntityProxy<T>を直接CallEntityAsync/SignalEntityAsync呼び出しに置き換えた - 使用中の場合はタスクハブ間での操作オーバーロードを置き換えました
- バッチ
GetStatusAsync/PurgeInstanceHistoryAsyncby-ID呼び出しをフィルターベースまたは個別の呼び出しに置き換えた -
DurableOrchestrationStatus.HistoryアクセスがGetOrchestrationHistoryAsyncへの移行 - DI を使用するようにエンティティ
DispatchAsyncコンストラクターパラメーターを更新しました - すべての関数をローカルでテストしました
- ステージング スロットにデプロイされ、検証済み
- 本番環境に切り替えられました