Azure Functions で接続を管理する方法How to manage connections in Azure Functions

関数アプリ内の Functions はリソースを共有します。それらの共有リソースの中には、HTTP 接続、データベース接続、ストレージなどの Azure サービスへの接続があります。Functions in a function app share resources, and among those shared resources are connections — HTTP connections, database connections, and connections to Azure services such as Storage. 多くの関数が同時に実行されている場合、利用可能な接続がなくなる可能性があります。When many functions are running concurrently, it's possible to run out of available connections. この記事では、実際に必要な接続よりも多くの接続を使用しないように関数をコーディングする方法について説明します。This article explains how to code your functions to avoid using more connections than they actually need.

接続の制限Connections limit

利用できる接続の数が制限される理由の一部は、関数アプリが Azure App Service サンドボックス内で実行されるためです。The number of available connections is limited partly because a function app runs in the Azure App Service sandbox. サンドボックスがコードに課す制限の 1 つは、接続数の上限 (現在は 300) です。One of the restrictions that the sandbox imposes on your code is a cap on the number of connections, currently 300. この制限に達すると、関数ランタイムは Host thresholds exceeded: Connections というメッセージでログを作成します。When you reach this limit, the functions runtime creates a log with the following message: Host thresholds exceeded: Connections.

より多くの要求を処理するためにスケール コントローラーが関数アプリのインスタンスを追加すると、制限を超える可能性が高くなります。The likelihood of exceeding the limit goes up when the scale controller adds function app instances to handle more requests. 各関数アプリ インスタンスは一度に多くの関数を実行でき、そのすべてが 300 の制限に加算される接続を使用します。Each function app instance can be running many functions at once, all of which are using connections that count toward the 300 limit.

静的クライアントを使用するUse static clients

必要以上に多くの接続を保持しないようにするには、関数の呼び出しごとに新しいインスタンスを作成するのではなく、クライアント インスタンスを再利用します。To avoid holding more connections than necessary, reuse client instances rather than creating new ones with each function invocation. HttpClientDocumentClient、Azure Storage クライアントのような .NET クライアントは、単一の静的クライアントを使用する場合に接続を管理できます。.NET clients like the HttpClient, DocumentClient, and Azure Storage clients can manage connections if you use a single, static client.

Azure Functions アプリケーションでサービス固有のクライアントを使用する場合のガイドラインを次に示します。Here are some guidelines to follow when using a service-specific client in an Azure Functions application:

  • 関数の呼び出しごとに新しいクライアントを作成しないDO NOT create a new client with every function invocation.
  • 関数の呼び出しごとに使用できる単一の静的クライアントを作成するDO create a single, static client that can be used by every function invocation.
  • 異なる関数が同じサービスを使用している場合、共有ヘルパー クラスで単一の静的クライアントを作成することを検討するCONSIDER creating a single, static client in a shared helper class if different functions use the same service.

HttpClient コードの例HttpClient code example

静的 HttpClient を作成する関数コードの例を次に示します。Here's an example of function code that creates a static HttpClient:

// Create a single, static HttpClient
private static HttpClient httpClient = new HttpClient();

public static async Task Run(string input)
{
    var response = await httpClient.GetAsync("http://example.com");
    // Rest of function
}

.NET の HttpClient については、"クライアントを破棄する方がよいですか" という質問がよく寄せられます。A common question about the .NET HttpClient is "Should I be disposing my client?" 一般的に、IDisposable を実装したオブジェクトは、使用の終了後に破棄します。In general, you dispose objects that implement IDisposable when you're done using them. ただし、関数の終了時に静的クライアントの使用は終了しないため、静的クライアントは破棄しません。But you don't dispose a static client because you aren't done using it when the function ends. アプリケーションの起動中は、静的クライアントを存続することができます。You want the static client to live for the duration of your application.

DocumentClient のコード例DocumentClient code example

DocumentClient は、Azure Cosmos DB のインスタンスに接続します。DocumentClient connects to an Azure Cosmos DB instance. Azure Cosmos DB のドキュメントでは、アプリケーションの有効期間中はシングルトン Azure Cosmos DB クライアントを使用することが推奨されています。The Azure Cosmos DB documentation recommends that you use a singleton Azure Cosmos DB client for the lifetime of your application. 次の例では、関数内でそれを行うパターンの 1 つを示します。The following example shows one pattern for doing that in a function:

#r "Microsoft.Azure.Documents.Client"
using Microsoft.Azure.Documents.Client;

private static Lazy<DocumentClient> lazyClient = new Lazy<DocumentClient>(InitializeDocumentClient);
private static DocumentClient documentClient => lazyClient.Value;

private static DocumentClient InitializeDocumentClient()
{
    // Perform any initialization here
    var uri = new Uri("example");
    var authKey = "authKey";

    return new DocumentClient(uri, authKey);
}

public static async Task Run(string input)
{
    Uri collectionUri = UriFactory.CreateDocumentCollectionUri("database", "collection");
    object document = new { Data = "example" };
    await documentClient.UpsertDocumentAsync(collectionUri, document);

    // Rest of function
}

SqlClient の接続SqlClient connections

関数のコードでは、SQL リレーショナル データベースに接続するために、SQL Server に対する .NET Framework データ プロバイダー (SqlClient) を使うことがあります。Your function code may use the .NET Framework Data Provider for SQL Server (SqlClient) to make connections to a SQL relational database. これは、Entity Framework のような ADO.NET に依存するデータ フレームワークの基になるプロバイダーでもあります。This is also the underlying provider for data frameworks that rely on ADO.NET, such as Entity Framework. HttpClientDocumentClient の接続とは異なり、ADO.NET は接続プールを既定で実装します。Unlike HttpClient and DocumentClient connections, ADO.NET implements connection pooling by default. ただし、それでも接続を使い果たす可能性があるため、データベースへの接続を最適化する必要があります。However, because you can still run out of connections, you should optimize connections to the database. 詳細については、「SQL Server Connection Pooling (ADO.NET)」(SQL Server の接続プーリング (ADO.NET)) をご覧ください。For more information, see SQL Server Connection Pooling (ADO.NET).

ヒント

Entity Framework などの一部のデータ フレームワークは、通常、構成ファイルの ConnectionStrings セクションから接続文字列を取得します。Some data frameworks, such as Entity Framework, typically get connection strings from the ConnectionStrings section of a configuration file. その場合は、関数アプリの設定およびローカル プロジェクトの local.settings.json ファイル接続文字列コレクションに、SQL データベースの接続文字列を明示的に追加する必要があります。In this case, you must explicitly add SQL database connection strings to the Connection strings collection of your function app settings and in the local.settings.json file in your local project. 関数のコードで SqlConnection を作成する場合は、接続文字列の値を他の接続と共にアプリケーションの設定に格納する必要があります。If you are creating a SqlConnection in your function code, you should store the connection string value in Application settings with your other connections.

次の手順Next steps

静的クライアントが推奨される理由の詳細については、「不適切なインスタンス化のアンチパターン」を参照してください。For more information about why static clients are recommended, see Improper instantiation antipattern.

Azure Functions のパフォーマンスに関するその他のヒントについては、「Azure Functions のパフォーマンスと信頼性を最適化する」を参照してください。For more Azure Functions performance tips, see Optimize the performance and reliability of Azure Functions.