Azure Functions での接続の管理Manage connections in Azure Functions

関数アプリ内の関数はリソースを共有します。Functions in a function app share resources. それらの共有リソースの中には、HTTP 接続、データベース接続、Azure Storage などのサービスへの接続があります。Among those shared resources are connections: HTTP connections, database connections, and connections to services such as Azure 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 need.

接続の制限Connection limit

使用できる接続の数が制限される理由の 1 つは、関数アプリがサンドボックス環境で実行されるためです。The number of available connections is limited partly because a function app runs in a sandbox environment. サンドボックスがコードに課す制限の 1 つに、送信接続数の制限があります。現在は、インスタンスあたり 600 アクティブ (合計 1,200) 接続です。One of the restrictions that the sandbox imposes on your code is a limit on the number of outbound connections, which is currently 600 active (1,200 total) connections per instance. この制限に達すると、関数ランタイムによって Host thresholds exceeded: Connections というメッセージがログに出力されます。When you reach this limit, the functions runtime writes the following message to the logs: Host thresholds exceeded: Connections. 詳細については、Functions のサービスの制限に関する記事を参照してください。For more information, see the Functions service limits.

この制限はインスタンスごとに適用されます。This limit is per instance. より多くの要求を処理するために、スケール コントローラーによって関数アプリ インスタンスが追加されると、インスタンスごとに接続の制限が適用されます。When the scale controller adds function app instances to handle more requests, each instance has an independent connection limit. つまり、接続のグローバルな制限はないので、すべてのアクティブ インスタンスでアクティブな接続の数が 600 をはるかに超える可能性があります。That means there's no global connection limit, and you can have much more than 600 active connections across all active instances.

トラブルシューティングを行う際には、関数アプリに対して Application Insights を有効にしたことを確認します。When troubleshooting, make sure that you have enabled Application Insights for your function app. Application Insights では、実行など、関数アプリのメトリックを表示できます。Application Insights lets you view metrics for your function apps like executions. 詳細については、「Application Insights でテレメトリを表示する」を参照してください。For more information, see View telemetry in Application Insights.

静的クライアントStatic clients

必要以上に多くの接続を保持しないようにするには、関数の呼び出しごとに新しいインスタンスを作成するのではなく、クライアント インスタンスを再利用します。To avoid holding more connections than necessary, reuse client instances rather than creating new ones with each function invocation. 関数の記述に使用するどの言語でも、クライアント接続を再利用することをお勧めします。We recommend reusing client connections for any language that you might write your function in. たとえば、単一の静的クライアントを使用すると、HttpClientDocumentClient、Azure Storage クライアントなどの .NET クライアントで接続を管理できます。For example, .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 you're 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 every function invocation can use.
  • さまざまな関数が同じサービスを使用している場合は、共有ヘルパー クラスで単一の静的クライアントを作成することを検討するConsider creating a single, static client in a shared helper class if different functions use the same service.

クライアント コードの例Client code examples

このセクションでは、関数のコードからクライアントを作成および使用するためのベスト プラクティスを示します。This section demonstrates best practices for creating and using clients from your function code.

HttpClient の例 (C#)HttpClient example (C#)

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

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

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

.NET の HttpClient について、"クライアントを破棄する方がよいですか" という質問がよく寄せられます。A common question about HttpClient in .NET is "Should I dispose of my client?" 一般に、IDisposable を実装したオブジェクトは、使用の終了後に破棄します。In general, you dispose of objects that implement IDisposable when you're done using them. ただし、関数の終了時に静的クライアントの使用は終了しないため、静的クライアントは破棄しません。But you don't dispose of 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.

HTTP エージェントの例 (JavaScript)HTTP agent examples (JavaScript)

優れた接続管理オプションが提供されることから、node-fetch モジュールなどの非ネイティブ メソッドではなくネイティブの http.agent クラスを使用する必要があります。Because it provides better connection management options, you should use the native http.agent class instead of non-native methods, such as the node-fetch module. 接続パラメーターは、http.agent クラスのオプションを使用して構成されます。Connection parameters are configured through options on the http.agent class. HTTP エージェントで利用できるオプションの詳細については、new Agent([options]) を参照してください。For detailed options available with the HTTP agent, see new Agent([options]).

http.request() で使用されるグローバル http.globalAgent クラスでは、これらのすべての値がそれぞれの既定値に設定されます。The global http.globalAgent class used by http.request() has all of these values set to their respective defaults. 関数の接続制限を構成するための推奨される方法は、グローバルに最大数を設定することです。The recommended way to configure connection limits in Functions is to set a maximum number globally. 次の例は、関数アプリのソケットの最大数を設定します。The following example sets the maximum number of sockets for the function app:

http.globalAgent.maxSockets = 200;

次の例では、その要求専用のカスタム HTTP エージェントを使用する新しい HTTP 要求を作成します。The following example creates a new HTTP request with a custom HTTP agent only for that request:

var http = require('http');
var httpAgent = new http.Agent();
httpAgent.maxSockets = 200;
options.agent = httpAgent;
http.request(options, onResponseCallback);

DocumentClient のコード例 (C#)DocumentClient code example (C#)

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
}

CosmosClient のコード例 (JavaScript)CosmosClient code example (JavaScript)

CosmosClient は、Azure Cosmos DB のインスタンスに接続します。CosmosClient 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:

const cosmos = require('@azure/cosmos');
const endpoint = process.env.COSMOS_API_URL;
const masterKey = process.env.COSMOS_API_KEY;
const { CosmosClient } = cosmos;

const client = new CosmosClient({ endpoint, auth: { masterKey } });
// All function invocations also reference the same database and container.
const container = client.database("MyDatabaseName").container("MyContainerName");

module.exports = async function (context) {
    const { result: itemArray } = await container.items.readAll().toArray();
    context.log(itemArray);
}

SqlClient の接続SqlClient connections

関数コードでは、SQL リレーショナル データベースに接続するために、.NET Framework Data Provider for SQL Server (SqlClient) を使用できます。Your function code can use the .NET Framework Data Provider for SQL Server (SqlClient) to make connections to a SQL relational database. これは、ADO.NET に依存するデータ フレームワーク (Entity Framework など) の基になるプロバイダーでもあります。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. ただし、それでも接続を使い果たす可能性があるため、データベースへの接続を最適化する必要があります。But 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're creating an instance of 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 we recommend static clients, see Improper instantiation antipattern.

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