管理 Azure Functions 中的連線

函數應用程式共用資源中的函數。 這些共用資源為連線:HTTP 連線、資料庫連線,以及 Azure 儲存體等服務連線。 當許多函數同時在使用量方案中執行時,就可能用盡可用的連線。 本文說明如何避免使用其所需的更多連線來撰寫函數的程式碼。

注意

本文所述的連線限制僅適用於在使用量方案中執行時。 不過,在此所述的技術可能會在任何方案中執行時有所幫助。

連線上限

使用量方案中可用的連線數目有限,部分原因為此方案中的函數應用程式會在沙箱環境中執行。 沙箱對程式碼施加的其中一項限制是輸出連線數目的限制,也就是目前每個執行個體 600 個 (共 1,200 個) 連線。 當您到達此限制時,函數執行階段會將下列訊息寫入記錄:Host thresholds exceeded: Connections。 如需詳細資訊,請參閱函數服務限制

此限制是按執行個體。 當調整控制器新增函數應用程式執行個體來處理更多要求時,每個執行個體都有獨立的連線限制。 這表示沒有全域連線限制,而且在所有作用中執行個體上可以有超過 600 個作用中的連線。

進行疑難排解時,請確定您已為函數應用程式啟用 Application Insights。 Application Insights 可讓您檢視函數應用程式的計量,例如執行。 如需詳細資訊,請參閱檢視 Application Insights 中的遙測

靜態用戶端

若要避免保有超過所需的連線,請重複使用用戶端執行個體,而不是在每次函式引動過程建立新的執行個體。 建議您針對任何可能用來撰寫函數的語言重複使用用戶端連線。 如果您使用單一靜態用戶端,則 .NET 用戶端 (HttpClientDocumentClient 和 Azure 儲存體用戶端) 可以管理連線。

以下是在 Azure Functions 應用程式中使用特定服務用戶端時所要遵循的一些指導方針:

  • 請勿在每次函數叫用過程建立新的用戶端。
  • 建立單一靜態用戶端,以供每次函數叫用使用。
  • 如果不同函數使用相同的服務,請考慮在共用協助程式類別中建立單一靜態用戶端。

用戶端程式碼範例

本節示範如何從您的函式程式碼建立和使用用戶端的最佳做法。

HTTP 要求

以下 C# 函式程式碼範例會建立靜態 HttpClient 執行個體:

// 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 的常見問題是「我是否應該處置用戶端?」一般而言,您會處置當您完成使用這些物件時所實作 IDisposable 的物件。 但您不會處置靜態用戶端,因為在函數結束時,您還未使用完畢。 您希望靜態用戶端在您應用程式的使用期間存留。

Azure Cosmos DB 用戶端

CosmosClient 會連線到 Azure Cosmos DB 執行個體。 Azure Cosmos DB 文件建議您在應用程式存留期內使用單一 Azure Cosmos DB 用戶端。 下列範例顯示在函式中執行該作業的一種模式:

#r "Microsoft.Azure.Cosmos"
using Microsoft.Azure.Cosmos;

private static Lazy<CosmosClient> lazyClient = new Lazy<CosmosClient>(InitializeCosmosClient);
private static CosmosClient cosmosClient => lazyClient.Value;

private static CosmosClient InitializeCosmosClient()
{
    // Perform any initialization here
    var uri = "https://youraccount.documents.azure.com:443";
    var authKey = "authKey";
   
    return new CosmosClient(uri, authKey);
}

public static async Task Run(string input)
{
    Container container = cosmosClient.GetContainer("database", "collection");
    MyItem item = new MyItem{ id = "myId", partitionKey = "myPartitionKey", data = "example" };
    await container.UpsertItemAsync(document);
   
    // Rest of function
}

此外,請為觸發程序建立名為「function.proj」的檔案,並新增下列內容:


<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.Azure.Cosmos" Version="3.23.0" />
    </ItemGroup>
</Project>

SqlClient 連線

函數程式碼可能會使用 .NET Framework Data Provider for SQL Server (SqlClient) 來連線到 SQL 關聯式資料庫。 這也是依賴 ADO.NET 之資料架構的基礎提供者,例如 Entity Framework。 不同於 HttpClient \(英文\) 和 DocumentClient \(英文\) 連線,ADO.NET 預設會實作連線共用。 不過,由於您仍然可將連線用完,因此,您應該將與資料庫的連線最佳化。 如需詳細資訊,請參閱 SQL Server 連線共用 (ADO.NET) \(機器翻譯\)。

秘訣

部分資料架構 (例如 Entity Framework) 通常會從設定檔的 ConnectionStrings 區段取得連接字串。 在此情況下,您必須明確地將 SQL 資料庫連接字串新增至函數應用程式設定的連接字串集合,以及您本機專案的 local.settings.json 檔案中。 如果您要在函數程式碼中建立 SqlConnection 執行個體,您應該將連接字串值以及其他連線一起儲存於應用程式設定中。

後續步驟

如需有關為何建議使用靜態用戶端的詳細資訊,請參閱不適當的具現化反模式

如需更多 Azure Functions 效能祕訣,請參閱將 Azure Functions 效能和可靠性最佳化