Agent Skills by ALSEL
Anthropic ClaudeLLM・AI開発⭐ リポ 0品質スコア 50/100

azure-functions

Azure Functionsの開発に関する専門的なパターンを提供します。isolated workerモデル、Durable Functionsのオーケストレーション、コールドスタートの最適化、および本番環境向けのパターンをカバーし、.NET・Python・Node.jsのプログラミングモデルに対応しています。

description の原文を見る

Expert patterns for Azure Functions development including isolated worker model, Durable Functions orchestration, cold start optimization, and production patterns. Covers .NET, Python, and Node.js programming models.

SKILL.md 本文

Azure Functions

Azure Functions開発の専門的パターン。Isolated Workerモデル、Durable Functions オーケストレーション、コールドスタート最適化、本番運用パターンを網羅。.NET、Python、Node.jsプログラミングモデルに対応。

パターン

Isolated Worker Model (.NET)

プロセス分離を備えた最新の.NET実行モデル

使用場面: 新しい.NET Azure Functionsアプリを構築する場合

テンプレート

// Program.cs - Isolated Worker Model
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services =>
    {
        // Application Insightsの追加
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();

        // HttpClientFactoryの追加(ソケット枯渇を防止)
        services.AddHttpClient();

        // カスタムサービスの追加
        services.AddSingleton<IMyService, MyService>();
    })
    .Build();

host.Run();

// HttpTriggerFunction.cs
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;

public class HttpTriggerFunction
{
    private readonly ILogger<HttpTriggerFunction> _logger;
    private readonly IMyService _service;

    public HttpTriggerFunction(
        ILogger<HttpTriggerFunction> logger,
        IMyService service)
    {
        _logger = logger;
        _service = service;
    }

    [Function("HttpTrigger")]
    public async Task<HttpResponseData> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
    {
        _logger.LogInformation("リクエストを処理しています");

        try
        {
            var result = await _service.ProcessAsync(req);

            var response = req.CreateResponse(HttpStatusCode.OK);
            await response.WriteAsJsonAsync(result);
            return response;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "リクエスト処理中にエラーが発生しました");
            var response = req.CreateResponse(HttpStatusCode.InternalServerError);
            await response.WriteAsJsonAsync(new { error = "内部サーバーエラー" });
            return response;
        }
    }
}

注釈

  • In-processモデルは2026年11月に廃止予定
  • Isolated Workerは.NET 8、9、10、および.NET Frameworkをサポート
  • 完全な依存性注入サポート
  • カスタムミドルウェアサポート

Node.js v4 プログラミングモデル

TypeScript/JavaScriptのための最新のコード中心アプローチ

使用場面: Node.js Azure Functionsを構築する場合

テンプレート

// src/functions/httpTrigger.ts
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";

export async function httpTrigger(
  request: HttpRequest,
  context: InvocationContext
): Promise<HttpResponseInit> {
  context.log(`HTTP関数がURL「${request.url}」のリクエストを処理しました`);

  try {
    const name = request.query.get("name") || (await request.text()) || "world";

    return {
      status: 200,
      jsonBody: { message: `Hello, ${name}!` }
    };
  } catch (error) {
    context.error("リクエスト処理中にエラーが発生しました:", error);
    return {
      status: 500,
      jsonBody: { error: "内部サーバーエラー" }
    };
  }
}

// appオブジェクトで関数を登録
app.http("httpTrigger", {
  methods: ["GET", "POST"],
  authLevel: "function",
  handler: httpTrigger
});

// タイマートリガーの例
app.timer("timerTrigger", {
  schedule: "0 */5 * * * *",  // 5分ごと
  handler: async (myTimer, context) => {
    context.log("タイマー関数実行時刻:", new Date().toISOString());
  }
});

// Blobトリガーの例
app.storageBlob("blobTrigger", {
  path: "samples-workitems/{name}",
  connection: "AzureWebJobsStorage",
  handler: async (blob, context) => {
    context.log(`Blobトリガー処理中: ${context.triggerMetadata.name}`);
    context.log(`Blobサイズ: ${blob.length} bytes`);
  }
});

注釈

  • v4モデルはコード中心で、function.jsonファイルがない
  • Express.jsに似たappオブジェクトを使用
  • TypeScriptが第一級サポート
  • すべてのトリガーがコード内に登録される

Python v2 プログラミングモデル

Pythonファンクション用のデコレータベースアプローチ

使用場面: Python Azure Functionsを構築する場合

テンプレート

# function_app.py
import azure.functions as func
import logging
import json

app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)

@app.route(route="hello", methods=["GET", "POST"])
async def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
    logging.info("Python HTTPトリガー関数がリクエストを処理しました。")

    try:
        name = req.params.get("name")
        if not name:
            try:
                req_body = req.get_json()
                name = req_body.get("name")
            except ValueError:
                pass

        if name:
            return func.HttpResponse(
                json.dumps({"message": f"Hello, {name}!"}),
                mimetype="application/json"
            )
        else:
            return func.HttpResponse(
                json.dumps({"message": "Hello, World!"}),
                mimetype="application/json"
            )
    except Exception as e:
        logging.error(f"リクエスト処理中にエラーが発生しました: {str(e)}")
        return func.HttpResponse(
            json.dumps({"error": "内部サーバーエラー"}),
            status_code=500,
            mimetype="application/json"
        )

@app.timer_trigger(schedule="0 */5 * * * *", arg_name="myTimer")
def timer_trigger(myTimer: func.TimerRequest) -> None:
    logging.info("タイマートリガーが実行されました")

@app.blob_trigger(arg_name="myblob", path="samples-workitems/{name}",
                  connection="AzureWebJobsStorage")
def blob_trigger(myblob: func.InputStream):
    logging.info(f"Blobトリガー: {myblob.name}、サイズ: {myblob.length} bytes")

@app.queue_trigger(arg_name="msg", queue_name="myqueue",
                   connection="AzureWebJobsStorage")
def queue_trigger(msg: func.QueueMessage) -> None:
    logging.info(f"キューメッセージ: {msg.get_body().decode('utf-8')}")

注釈

  • v2モデルはデコレータを使用し、function.jsonファイルがない
  • Pythonはアウトオブプロセスで実行(常にIsolated)
  • Linux ベースのホスティングが必要
  • 非同期関数がサポートされている

Durable Functions - Function Chaining

状態永続化による順序実行

使用場面: 自動リトライ機能を備えた順序ワークフローが必要な場合

テンプレート

// C# Isolated Worker - Function Chaining
using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;
using Microsoft.DurableTask.Client;

public class OrderWorkflow
{
    [Function("OrderOrchestrator")]
    public static async Task<OrderResult> RunOrchestrator(
        [OrchestrationTrigger] TaskOrchestrationContext context)
    {
        var order = context.GetInput<Order>();

        // 関数は順序に実行され、各段階間で状態が永続化される
        var validated = await context.CallActivityAsync<ValidatedOrder>(
            "ValidateOrder", order);

        var payment = await context.CallActivityAsync<PaymentResult>(
            "ProcessPayment", validated);

        var shipped = await context.CallActivityAsync<ShippingResult>(
            "ShipOrder", new ShipRequest { Order = validated, Payment = payment });

        var notification = await context.CallActivityAsync<bool>(
            "SendNotification", shipped);

        return new OrderResult
        {
            OrderId = order.Id,
            Status = "完了",
            TrackingNumber = shipped.TrackingNumber
        };
    }

    [Function("ValidateOrder")]
    public static async Task<ValidatedOrder> ValidateOrder(
        [ActivityTrigger] Order order, FunctionContext context)
    {
        var logger = context.GetLogger<OrderWorkflow>();
        logger.LogInformation("注文を検証しています {OrderId}", order.Id);

        // 検証ロジック...
        return new ValidatedOrder { /* ... */ };
    }

    [Function("ProcessPayment")]
    public static async Task<PaymentResult> ProcessPayment(
        [ActivityTrigger] ValidatedOrder order, FunctionContext context)
    {
        // 組み込みリトライ機能付きの支払い処理...
        return new PaymentResult { /* ... */ };
    }

    [Function("OrderWorkflow_HttpStart")]
    public static async Task<HttpResponseData> HttpStart(
        [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req,
        [DurableClient] DurableTaskClient client,
        FunctionContext context)
    {
        var order = await req.ReadFromJsonAsync<Order>();
        string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
            "OrderOrchestrator", order);

        return client.CreateCheckStatusResponse(req, instanceId);
    }
}

注釈

  • アクティビティ間で状態が自動的に永続化される
  • 一時的な障害時に自動リトライ
  • プロセス再開後も機能継続
  • 監視用の組み込みステータスエンドポイント

Durable Functions - Fan-Out/Fan-In

結果集約を伴う並列実行

使用場面: 複数アイテムを並列に処理する場合

テンプレート

// C# Isolated Worker - Fan-Out/Fan-In
using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;

public class ParallelProcessing
{
    [Function("ProcessImagesOrchestrator")]
    public static async Task<ProcessingResult> RunOrchestrator(
        [OrchestrationTrigger] TaskOrchestrationContext context)
    {
        var images = context.GetInput<List<string>>();

        // Fan-out: すべてのタスクを並列に開始
        var tasks = images.Select(image =>
            context.CallActivityAsync<ImageResult>("ProcessImage", image));

        // Fan-in: すべてのタスク完了まで待機
        var results = await Task.WhenAll(tasks);

        // 結果を集約
        var successful = results.Count(r => r.Success);
        var failed = results.Count(r => !r.Success);

        return new ProcessingResult
        {
            TotalProcessed = results.Length,
            Successful = successful,
            Failed = failed,
            Results = results.ToList()
        };
    }

    [Function("ProcessImage")]
    public static async Task<ImageResult> ProcessImage(
        [ActivityTrigger] string imageUrl, FunctionContext context)
    {
        var logger = context.GetLogger<ParallelProcessing>();
        logger.LogInformation("画像を処理しています: {Url}", imageUrl);

        try
        {
            // 画像処理ロジック...
            await Task.Delay(1000); // シミュレートされた処理

            return new ImageResult
            {
                Url = imageUrl,
                Success = true,
                ProcessedUrl = $"processed-{imageUrl}"
            };
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "失敗: {Url}", imageUrl);
            return new ImageResult { Url = imageUrl, Success = false };
        }
    }

    // Python相当
    // @app.orchestration_trigger(context_name="context")
    // def process_images_orchestrator(context: df.DurableOrchestrationContext):
    //     images = context.get_input()
    //
    //     # Fan-out: 並列タスク作成
    //     tasks = [context.call_activity("ProcessImage", img) for img in images]
    //
    //     # Fan-in: すべて待機
    //     results = yield context.task_all(tasks)
    //
    //     return {"processed": len(results), "results": results}
}

注釈

  • 独立したタスクの並列実行
  • すべてが完了したときに結果を集約
  • メモリ効率的 - タスク IDのみを保存
  • 数千の並列アクティビティまで可能

コールドスタート最適化

本番環境でのコールドスタート遅延を最小化

使用場面: 本番環境での高速応答時間が必要な場合

テンプレート

// 1. Premium プランを使用してインスタンスを事前ウォーミング
// host.json
{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "hubName": "MyTaskHub"
    }
  },
  "functionTimeout": "00:30:00"
}

// 2. ウォームアップトリガーを追加(Premium プラン)
[Function("Warmup")]
public static void Warmup(
    [WarmupTrigger] object warmupContext,
    FunctionContext context)
{
    var logger = context.GetLogger("Warmup");
    logger.LogInformation("ウォームアップトリガーが実行されました - 依存性を初期化しています");

    // コストの高いリソースを事前初期化
    // データベース接続、HttpClient等
}

// 3. DI でスタティック/シングルトンクライアントを使用
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // HttpClientFactoryはソケット枯渇を防止
        services.AddHttpClient<IMyApiClient, MyApiClient>(client =>
        {
            client.BaseAddress = new Uri("https://api.example.com");
            client.Timeout = TimeSpan.FromSeconds(30);
        });

        // 初期化コストが高いものはシングルトン
        services.AddSingleton<IExpensiveService>(sp =>
        {
            // 一度初期化され、呼び出し間で再利用
            return new ExpensiveService();
        });
    }
}

// 4. パッケージサイズを削減
// .csproj - 不要な依存性を除外
<PropertyGroup>
  <PublishTrimmed>true</PublishTrimmed>
  <TrimMode>partial</TrimMode>
</PropertyGroup>

// 5. パッケージデプロイメントから実行
// Azure CLI
// az functionapp deployment source config-zip \
//   --resource-group myResourceGroup \
//   --name myFunctionApp \
//   --src myapp.zip \
//   --build-remote true

注釈

  • コールドスタート全リージョン/言語で約53%改善
  • Premium プランが事前ウォーミングされたインスタンスを提供
  • ウォームアップトリガーがトラフィック前に初期化
  • パッケージデプロイメントでコールドスタート削減可能

Queue Trigger とエラーハンドリング

poison queueを使用した信頼性のあるメッセージ処理

使用場面: Azure Storage Queue からメッセージを処理する場合

テンプレート

// C# Isolated Worker - Queue Trigger
using Microsoft.Azure.Functions.Worker;

public class QueueProcessor
{
    private readonly ILogger<QueueProcessor> _logger;
    private readonly IMyService _service;

    public QueueProcessor(ILogger<QueueProcessor> logger, IMyService service)
    {
        _logger = logger;
        _service = service;
    }

    [Function("ProcessQueueMessage")]
    public async Task Run(
        [QueueTrigger("myqueue-items", Connection = "AzureWebJobsStorage")]
        QueueMessage message)
    {
        _logger.LogInformation("メッセージを処理しています: {Id}", message.MessageId);

        try
        {
            var payload = JsonSerializer.Deserialize<MyPayload>(message.Body);
            await _service.ProcessAsync(payload);

            _logger.LogInformation("メッセージが正常に処理されました: {Id}", message.MessageId);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "メッセージ処理中にエラーが発生しました: {Id}", message.MessageId);

            // メッセージはmaxDequeueCount(デフォルト5)までリトライされる
            // その後、poison queueに移動: myqueue-items-poison
            throw;
        }
    }

    // オプション: Poison queueを監視
    [Function("ProcessPoisonQueue")]
    public async Task ProcessPoison(
        [QueueTrigger("myqueue-items-poison", Connection = "AzureWebJobsStorage")]
        QueueMessage message)
    {
        _logger.LogWarning("Poison メッセージを処理しています: {Id}", message.MessageId);

        // ログ、アラート、または手動レビュー用に保存
        await _service.HandlePoisonMessageAsync(message);
    }
}

// host.json - Queue設定
// {
//   "version": "2.0",
//   "extensions": {
//     "queues": {
//       "maxPollingInterval": "00:00:02",
//       "visibilityTimeout": "00:00:30",
//       "batchSize": 16,
//       "maxDequeueCount": 5,
//       "newBatchThreshold": 8
//     }
//   }
// }

注釈

  • メッセージはmaxDequeueCountまでリトライ
  • 失敗メッセージがpoison queueに移動
  • visibilityTimeoutを処理時間に合わせて設定
  • batchSizeが並列処理を制御

HTTP Trigger と長時間実行パターン

230秒のHTTP制限を超える処理の処理

使用場面: HTTP要求トリガーが長時間実行される処理

テンプレート

// 非同期HTTPパターン - すぐに返し、ステータスをポーリング
[Function("StartLongRunning")]
public static async Task<HttpResponseData> StartLongRunning(
    [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req,
    [DurableClient] DurableTaskClient client,
    FunctionContext context)
{
    var input = await req.ReadFromJsonAsync<WorkRequest>();

    // オーケストレーション開始(すぐに返される)
    string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
        "LongRunningOrchestrator", input);

    // ポーリング用のステータスURLを返す
    return client.CreateCheckStatusResponse(req, instanceId);
}

// レスポンスに含まれるもの:
// {
//   "id": "abc123",
//   "statusQueryGetUri": "https://.../instances/abc123",
//   "sendEventPostUri": "https://.../instances/abc123/raiseEvent/{eventName}",
//   "terminatePostUri": "https://.../instances/abc123/terminate"
// }

// 代替: Durable Functionsなしのキューベースパターン
[Function("StartWork")]
[QueueOutput("work-queue")]
public static async Task<WorkItem> StartWork(
    [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req,
    FunctionContext context)
{
    var input = await req.ReadFromJsonAsync<WorkRequest>();
    var workId = Guid.NewGuid().ToString();

    // 処理をキュー登録し、すぐに返す
    var workItem = new WorkItem
    {
        Id = workId,
        Request = input
    };

    // ステータスチェック用のwork IDを返す
    var response = req.CreateResponse(HttpStatusCode.Accepted);
    await response.WriteAsJsonAsync(new
    {
        workId = workId,
        statusUrl = $"/api/status/{workId}"
    });

    return workItem;
}

[Function("ProcessWork")]
public static async Task ProcessWork(
    [QueueTrigger("work-queue")] WorkItem work,
    FunctionContext context)
{
    // 長時間の処理
    // ポーリング用にストレージでステータスを更新
}

注釈

  • HTTPタイムアウトはプランに関係なく230秒
  • 非同期パターンにはDurable Functionsを使用
  • すぐに返し、ステータスエンドポイントを提供
  • クライアントが完了までポーリング

鋭い問題点

HTTP タイムアウトがプランに関係なく230秒

重大度: 高

状況: 長時間処理を伴うHTTPトリガー関数

症状:

  • 約4分後に504 Gateway Timeout
  • タイムアウト前にリクエストが終了
  • 関数が続行していてもクライアントがタイムアウト
  • host.jsonのタイムアウト設定は効果がない

なぜこれが発生するのか: Azure Load Balancerには、HTTPリクエストに対して230秒のハードコードされたアイドルタイムアウトがあります。これはご使用のFunction Appタイムアウト設定に関わらず適用されます。

host.jsonでfunctionTimeoutを30分に設定したとしても、HTTPトリガーはクライアントの観点から230秒後にタイムアウトします。

関数はタイムアウト後も実行継続しますが、クライアントはレスポンスを受け取りません。

推奨される対応:

Durable Functionsで非同期パターンを使用

[Function("StartLongProcess")]
public static async Task<HttpResponseData> Start(
    [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req,
    [DurableClient] DurableTaskClient client)
{
    var input = await req.ReadFromJsonAsync<WorkRequest>();

    // オーケストレーション開始、すぐに返される
    string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
        "LongRunningOrchestrator", input);

    // ポーリング用のステータスURLを返す
    return client.CreateCheckStatusResponse(req, instanceId);
}

// クライアントはstatusQueryGetUriが完了まできまでポーリング

キューベースの非同期パターンを使用

[Function("StartWork")]
public static async Task<HttpResponseData> StartWork(
    [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req,
    [QueueOutput("work-queue")] out WorkItem workItem)
{
    var workId = Guid.NewGuid().ToString();

    workItem = new WorkItem { Id = workId, /* ... */ };

    var response = req.CreateResponse(HttpStatusCode.Accepted);
    await response.WriteAsJsonAsync(new {
        id = workId,
        statusUrl = $"/api/status/{workId}"
    });
    return response;
}

Webhookコールバックパターンを使用

// クライアントがコールバックURLを提供
// Function が処理をキュー登録、202 Acceptedを返す
// 完了時、結果をコールバックURLに POST

HttpClient インスタンス化によるソケット枯渇

重大度: 高

状況: 関数コード内で HttpClient インスタンスを作成

症状:

  • SocketException: 「リモートサーバーへの接続ができません」
  • 「ソケットにアクセスしようとした方法が許可されていません」
  • 高負荷時の散発的な接続失敗
  • ローカルではうまくいくが本番では失敗

なぜこれが発生するのか: 各要求に対して新しい HttpClient を作成すると、新しいソケット接続が生成されます。

閉じた後、ソケットは240秒間TIME_WAIT状態のままです。

サーバーレス環境での高スループット時、利用可能なソケットがすぐに枯渇します。これはHttpClientに限りませんが、すべてのネットワーククライアントに影響します。

Azure Functionsは複数カスタマー間でネットワークリソースを共有しており、これはさらに重要です。

推奨される対応:

IHttpClientFactory を使用(推奨)

// Program.cs
var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services =>
    {
        services.AddHttpClient<IMyApiClient, MyApiClient>(client =>
        {
            client.BaseAddress = new Uri("https://api.example.com");
            client.Timeout = TimeSpan.FromSeconds(30);
        });
    })
    .Build();

// MyApiClient.cs
public class MyApiClient : IMyApiClient
{
    private readonly HttpClient _client;

    public MyApiClient(HttpClient client)
    {
        _client = client;  // ファクトリで注入、管理される
    }

    public async Task<string> GetDataAsync()
    {
        return await _client.GetStringAsync("/data");
    }
}

スタティッククライアントを使用(代替)

public static class MyFunction
{
    // スタティック HttpClient、呼び出し間で再利用
    private static readonly HttpClient _httpClient = new HttpClient
    {
        Timeout = TimeSpan.FromSeconds(30)
    };

    [Function("MyFunction")]
    public static async Task Run(...)
    {
        var result = await _httpClient.GetAsync("...");
    }
}

Azure SDK クライアントにも同じパターンを適用

// 以下にも適用:
// - BlobServiceClient
// - CosmosClient
// - ServiceBusClient
// DI またはスタティックインスタンスを使用

非同期呼び出しをブロックするとスレッド枯渇を引き起こす

重大度: 高

状況: .Result、.Wait()、またはThread.Sleepを非同期コード内で使用

症状:

  • 高負荷時のデッドロック
  • リクエストが無期限にハング
  • 「A task was canceled」例外
  • 低い同時実行性ではうまくいくが、高い場合は失敗

なぜこれが発生するのか: Azure Functionsスレッドプールは限定されています。ブロック呼び出し(.Result、.Wait())はスレッドを人質に取ります。待機中は他の処理を実行できません。

Thread.Sleepはスレッドをブロックし、他のリクエストを処理できるスレッドが失われます。

複数同時実行により、すぐにスレッドが枯渇し、デッドロックとタイムアウトが発生します。

推奨される対応:

常に async/await を使用

// 悪い例 - スレッドをブロック
var result = httpClient.GetAsync(url).Result;
someTask.Wait();
Thread.Sleep(5000);

// 良い例 - スレッドを譲歩
var result = await httpClient.GetAsync(url);
await someTask;
await Task.Delay(5000);

同期メソッド呼び出しを修正

// 悪い例 - 同期で非同期をラップ
public void ProcessData()
{
    var data = GetDataAsync().Result;  // ブロック!
}

// 良い例 - 非同期で統一
public async Task ProcessDataAsync()
{
    var data = await GetDataAsync();
}

コンソール/スタートアップ時点では非同期を設定

// エントリーポイントでのみ GetAwaiter().GetResult() を使用が必要
public static void Main(string[] args)
{
    MainAsync(args).GetAwaiter().GetResult();
}

private static async Task MainAsync(string[] args)
{
    // 非同期コードはここで
}

Consumption Plan の10分タイムアウト制限

重大度: 中

状況: Consumption プランで長時間実行処理

症状:

  • 10分後に関数が終了
  • ログに「Function timed out」
  • エラーをキャッチせず処理が不完全
  • 開発環境(長いタイムアウト)ではうまくいくが本番では失敗

なぜこれが発生するのか: Consumption プランには10分のハード実行時間制限があります。 設定しない場合は5分です。

Consumption プランではこの10分を超えることはできません。 長時間実行処理にはPremium プランまたは別のアーキテクチャが必要です。

推奨される対応:

最大タイムアウトを設定(Consumption)

// host.json
{
  "version": "2.0",
  "functionTimeout": "00:10:00"  // Consumption の最大値
}

Premium プランにアップグレードしてより長いタイムアウト

// Premium プラン - デフォルト30分、無制限利用可能
{
  "version": "2.0",
  "functionTimeout": "00:30:00"  // または無制限のため削除
}

長時間ワークフローにはDurable Functionsを使用

[Function("LongWorkflowOrchestrator")]
public static async Task<string> RunOrchestrator(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    // 各アクティビティは独自のタイムアウト
    // ワークフローは数日実行可能
    await context.CallActivityAsync("Step1", input);
    await context.CallActivityAsync("Step2", input);
    await context.CallActivityAsync("Step3", input);
    return "完了";
}

処理をより小さなチャンクに分割

// キューベースのチャンキング
[Function("ProcessChunk")]
[QueueOutput("work-queue")]
public static IEnumerable<WorkChunk> ProcessChunk(
    [QueueTrigger("work-queue")] WorkChunk chunk)
{
    var results = Process(chunk);

    // さらに処理がある場合は次のチャンクをキュー
    if (chunk.HasMore)
    {
        yield return chunk.Next();
    }
}

.NET In-Process Model が2026年11月に廃止予定

重大度: 高

状況: 新しい.NET関数を作成、または既存を保守

症状:

  • 新しいプロジェクトでin-processモデルを使用
  • ホストランタイムとの依存性のバージョン競合
  • 最新の.NETバージョンを使用できない
  • 将来の移行負担

なぜこれが発生するのか: In-processモデルはコードをAzure Functionsホストと同じプロセスで実行します。これにより以下が発生:

  • アセンブリバージョン競合
  • LTS .NET バージョンに制限
  • 最新.NET機能へのアクセスなし
  • ホストランタイムとの密結合

サポートは2026年11月10日で終了します。その後、in-processアプリは動作が停止し、セキュリティ更新を受け取らなくなる可能性があります。

推奨される対応:

新しいプロジェクトでisolated workerを使用

# 新しいisolated workerプロジェクトを作成
func init MyFunctionApp --worker-runtime dotnet-isolated

# または.NET 8で
dotnet new func --name MyFunctionApp --framework net8.0

既存のin-processをisolatedに移行

// 旧 - In-process (FunctionNameアトリビュート)
public class InProcessFunction
{
    [FunctionName("MyFunction")]
    public async Task<IActionResult> Run(
        [HttpTrigger] HttpRequest req,
        ILogger log)
    {
        log.LogInformation("処理しています");
        return new OkResult();
    }
}

// 新 - Isolated worker (Functionアトリビュート)
public class IsolatedFunction
{
    private readonly ILogger<IsolatedFunction> _logger;

    public IsolatedFunction(ILogger<IsolatedFunction> logger)
    {
        _logger = logger;
    }

    [Function("MyFunction")]
    public async Task<HttpResponseData> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get")]
        HttpRequestData req)
    {
        _logger.LogInformation("処理しています");
        return req.CreateResponse(HttpStatusCode.OK);
    }
}

主な移行変更

  • FunctionName → Function アトリビュート
  • HttpRequest → HttpRequestData
  • IActionResult → HttpResponseData
  • ILogger注入 → コンストラクタ注入
  • Program.csを追加

ILogger がコンソールまたはAppInsightsに出力しない

重大度: 中

状況: Isolated workerで依存性注入されたILoggerを使用

症状:

  • ローカルコンソールにログが表示されない
  • Application Insightsにログが表示されない
  • context.GetLogger()で機能するがILoggerの場合は不可
  • すべてのメソッド呼び出しでロガーを渡す必要がある

なぜこれが発生するのか: Isolated worker モデルでは、依存性注入されたILoggerがAzure Functionsログパイプラインに適切に接続されないことがあります。

ローカル開発では特に影響 - ログがどこにも表示されないことがあります。 Application Insightsには明示的な設定が必要です。

FunctionContextから得たILoggerは異なるように機能します。

推奨される対応:

Application Insightsを適切に設定

// Program.cs
var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services =>
    {
        // App Insightsテレメトリを追加
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .Build();

ログレベルを設定

// host.json
{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    },
    "logLevel": {
      "default": "Information",
      "Host.Results": "Error",
      "Function": "Information",
      "Host.Aggregator": "Trace"
    }
  }
}

確実性のためにcontext.GetLoggerを使用

[Function("MyFunction")]
public async Task Run(
    [HttpTrigger] HttpRequestData req,
    FunctionContext context)
{
    // このロガーは常に機能
    var logger = context.GetLogger<MyFunction>();
    logger.LogInformation("リクエストを処理しています");
}

ローカル開発 - local.settings.jsonを確認

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "APPLICATIONINSIGHTS_CONNECTION_STRING": "InstrumentationKey=..."
  }
}

拡張パッケージの不足でサイレント障害が発生

重大度: 中

状況: 拡張パッケージをインストールしていないままトリガー/バインディングを使用

症状:

  • イベントでFunction がトリガーされない
  • ログに「No job functions found」警告
  • 設定が正しくてもバインディングが機能しない
  • 拡張パッケージ追加後に機能するようになる

なぜこれが発生するのか: Azure Functions v2+は、トリガーとバインディング用に拡張バンドルを使用します。 拡張が適切に設定されていない、またはパッケージがインストールされていない場合、Function ホストがバインディングを認識できません。

Isolated workerでは明示的なNuGetパッケージが必要です。 In-processでは Microsoft.Azure.WebJobs.Extensions.* が必要です。

推奨される対応:

拡張バンドルを確認(最も一般的)

// host.json - 拡張バンドルはほとんどのケースを処理
{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  }
}

Isolated worker用の明示的パッケージをインストール

<!-- .csproj - Isolated worker パッケージ -->
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.20.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.0" />

<!-- ストレージトリガー/バインディング -->
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage" Version="6.2.0" />

<!-- Service Bus -->
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.ServiceBus" Version="5.14.0" />

<!-- Cosmos DB -->
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.CosmosDB" Version="4.6.0" />

<!-- Durable Functions -->
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.1.0" />

Function登録を確認

# 登録されたFunctionを確認
func host start --verbose

# 以下を探す:
# "Found the following functions:"
# 空の場合、拡張とアトリビュートをチェック

Premium Plan でもあたらしいインスタンス上でのコールドスタートは発生

重大度: 中

状況: Premium プランを使用していてもコールドスタートが予想される

症状:

  • Premium プランにもかかわらずコールドスタート発生
  • 新しいインスタンスへの最初のリクエストが遅い
  • スケールアウトイベント中にレイテンシースパイク
  • 事前ウォーミングされたインスタンスが使用されない

なぜこれが発生するのか: Premium プランは事前ウォーミングされたインスタンスを提供しますが:

  • デフォルトでは事前ウォーミングインスタンスは1つだけ
  • 急速なスケールアウト時は新しいコールドインスタンスが作成される
  • 事前ウォーミングはランタイムの準備、アプリケーションではない
  • ウォームアップトリガーが実行されてもコード初期化が遅い場合がある

事前ウォーミングはランタイムが準備完了という意味であり、アプリケーションではありません。

推奨される対応:

ウォームアップトリガーを追加してアプリケーションコードを初期化

[Function("Warmup")]
public void Warmup(
    [WarmupTrigger] object warmupContext,
    FunctionContext context)
{
    var logger = context.GetLogger("Warmup");
    logger.LogInformation("ウォームアップトリガーが実行されました");

    // コストの高いリソースを初期化
    _cosmosClient.GetContainer("db", "container");
    _httpClient.GetAsync("https://api.example.com/health").Wait();
}

事前ウォーミングインスタンス数を設定

# 事前ウォーミングインスタンス数を増加(コスト増)
az functionapp config set \
  --name <app-name> \
  --resource-group <rg> \
  --prewarmed-instance-count 3

アプリケーション初期化を最適化

// コストの高いリソースを遅延初期化
private static readonly Lazy<ExpensiveClient> _client =
    new Lazy<ExpensiveClient>(() => new ExpensiveClient());

// コネクションプーリング
services.AddDbContext<MyDbContext>(options =>
    options.UseSqlServer(connectionString, sql =>
        sql.MinPoolSize(5)));

Always-ready インスタンスを使用(最もコスト高)

# インスタンスが常に実行、コールドスタートなし
az functionapp config set \
  --name <app-name> \
  --resource-group <rg> \
  --minimum-elastic-instance-count 2

検証チェック

ハードコーディングされた接続文字列

重大度: エラー

接続文字列はハードコーディングしてはいけません

メッセージ: ハードコーディングされた接続文字列。Key Vaultまたはアプリ設定を使用してください。

ハードコーディングされたAPIキー

重大度: エラー

APIキーはKey Vaultまたはアプリ設定を使用してください

メッセージ: ハードコーディングされたAPIキー。Key Vaultまたは環境変数を使用してください。

本番環境での Anonymous 認可レベル

重大度: 警告

匿名エンドポイントは他の方法で保護されるべき

メッセージ: 匿名認可。API Management やその他の認証で保護されていることを確認してください。

ブロック .Result 呼び出し

重大度: エラー

.Resultを使用するとスレッドがブロックされデッドロックの原因

メッセージ: ブロック .Result 呼び出し。代わりに await を使用してください。

ブロック .Wait() 呼び出し

重大度: エラー

.Wait()を使用するとスレッドがブロック

メッセージ: ブロック .Wait() 呼び出し。代わりに await を使用してください。

Thread.Sleep 使用

重大度: エラー

Thread.Sleepはスレッドをブロック

メッセージ: Thread.Sleep はスレッドをブロック。代わりに await Task.Delay() を使用してください。

リクエストごとの新しい HttpClient インスタンス

重大度: 警告

リクエストごとに HttpClient を作成するとソケット枯渇を引き起こす

メッセージ: リクエストごとの新しい HttpClient。IHttpClientFactory またはスタティッククライアントを使用してください。

Using ステートメント内の HttpClient

重大度: 警告

HttpClient を Dispose するとソケット枯渇を引き起こす

メッセージ: Using ステートメント内の HttpClient。適切なライフサイクルのための IHttpClientFactory を使用してください。

In-Process FunctionName アトリビュート

重大度: 情報

In-process モデルは2026年11月に廃止予定

メッセージ: In-process FunctionName アトリビュート。Isolated workerへの移行を検討してください。

関数アトリビュートなし

重大度: 警告

Isolated workerには [Function] アトリビュートが必要

メッセージ: [Function] アトリビュートなしの HttpTrigger (Isolated workerが必要)。

コラボレーション

デリゲーショントリガー

  • ユーザーが AWS サーバーレスを必要とする -> aws-serverless (Lambda、API Gateway、SAM)
  • ユーザーが GCP サーバーレスを必要とする -> gcp-cloud-run (Cloud Run、Cloud Functions)
  • ユーザーがコンテナベースデプロイを必要とする -> gcp-cloud-run (Azure Container Apps または Cloud Run)
  • ユーザーがデータベース設計を必要とする -> postgres-wizard (Azure SQL、Cosmos DB データモデリング)
  • ユーザーが認証を必要とする -> auth-specialist (Azure AD、Easy Auth、管理サービスID)
  • ユーザーが複雑なオーケストレーションを必要とする -> workflow-automation (Logic Apps、Power Automate)

使用場面

  • ユーザーが言及または示唆: Azure Function
  • ユーザーが言及または示唆: Azure Functions
  • ユーザーが言及または示唆: Durable Functions
  • ユーザーが言及または示唆: Azure サーバーレス
  • ユーザーが言及または示唆: Function App

制限事項

  • このスキルは上記で説明されるスコープに明確に一致するタスクの場合のみ使用してください。
  • 出力を環境固有の検証、テスト、またはエキスパートレビューの代替と見なさないでください。
  • 必要な入力、許可、セーフティ境界、または成功基準が不明な場合は一度停止して説明を要求してください。

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
sickn33
リポジトリ
sickn33/antigravity-awesome-skills
ライセンス
MIT
最終更新
不明

Source: https://github.com/sickn33/antigravity-awesome-skills / ライセンス: MIT

関連スキル

OpenAILLM・AI開発⭐ リポ 6,054

agent-browser

AI エージェント向けのブラウザ自動化 CLI です。ウェブサイトとの対話が必要な場合に使用します。ページ遷移、フォーム入力、ボタンクリック、スクリーンショット取得、データ抽出、ウェブアプリのテスト、ブラウザ操作の自動化など、あらゆるブラウザタスクに対応できます。「ウェブサイトを開く」「フォームに記入する」「ボタンをクリックする」「スクリーンショットを取得する」「ページからデータを抽出する」「このウェブアプリをテストする」「サイトにログインする」「ブラウザ操作を自動化する」といった要求や、プログラマティックなウェブ操作が必要なタスクで起動します。

by JimmyLv
汎用LLM・AI開発⭐ リポ 1,982

anyskill

AnySkill — あなたのプライベート・スキルクラウド。GitHubを基盤としたリポジトリからエージェントスキルを管理、同期、動的にロードできます。自然言語でクラウドスキルを検索し、オンデマンドでプロンプトを自動ロード、カスタムスキルのアップロードと共有、スキルバンドルの一括インストールが可能です。OpenClaw、Antigravity、Claude Code、Cursorに対応しています。

by LeoYeAI
汎用LLM・AI開発⭐ リポ 1,982

engram

AIエージェント向けの永続的なメモリシステムです。バグ修正、意思決定、発見、設定変更の後はmem_saveを使用してください。ユーザーが「覚えている」「記憶している」と言及した場合、または以前のセッションと重複する作業を開始する際はmem_searchを使用します。セッション終了前にmem_session_summaryを使用して、コンテキストを保持してください。

by LeoYeAI
汎用LLM・AI開発⭐ リポ 21,584

skyvern

AI駆動のブラウザ自動化により、任意のウェブサイトを自動化できます。フォーム入力、データ抽出、ファイルダウンロード、ログイン、複数ステップのワークフロー実行など、ユーザーがウェブサイトと連携する必要があるときに使用します。Skyvernは、LLMとコンピュータビジョンを活用して、未知のサイトも自動操作可能です。Python SDK、TypeScript SDK、REST API、MCPサーバー、またはCLIを通じて統合できます。

by Skyvern-AI
汎用LLM・AI開発⭐ リポ 1,149

pinchbench

PinchBenchベンチマークを実行して、OpenClawエージェントの実世界タスクにおけるパフォーマンスを評価できます。モデルの機能テスト、モデル間の比較、ベンチマーク結果のリーダーボード提出、またはOpenClawのセットアップがカレンダー、メール、リサーチ、コーディング、複数ステップのワークフローにどの程度対応しているかを確認する際に使用します。

by pinchbench
汎用LLM・AI開発⭐ リポ 4,693

openui

OpenUIとOpenUI Langを使用してジェネレーティブUIアプリを構築できます。これらはLLM生成インターフェースのためのトークン効率的なオープン標準です。OpenUI、@openuidev、ジェネレーティブUI、LLMからのストリーミングUI、AI向けコンポーネントライブラリ、またはjson-render/A2UIの置き換えについて述べる際に使用します。スキャフォルディング、defineComponent、システムプロンプト、Renderer、およびOpenUI Lang出力のデバッグに対応しています。

by thesysdev
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: sickn33 · sickn33/antigravity-awesome-skills · ライセンス: MIT