Gerenciar conexões no Azure Functions

As funções em um aplicativo de funções compartilham recursos. Funções em um aplicativo de funções compartilham recursos e, entre os recursos compartilhados estão conexões HTTP, conexões de banco de dados e conexões com os serviços do Azure como Armazenamento. Quando muitas funções estão em execução simultaneamente em um plano de consumo, é possível ficar sem conexões disponíveis. Este artigo explica como codificar as funções para evitar o uso de mais conexões do que realmente precisam.

Observação

Os limites de conexão descritos neste artigo se aplicam somente quando executado em um plano de consumo. No entanto, as técnicas descritas aqui podem ser benéficas quando executadas em um plano.

Limite de conexão

O número de conexões disponíveis em um plano de consumo é limitado em parte porque um aplicativo de funções nesse plano é executado em um ambiente de área restrita. Uma das restrições que a área de proteção impõe em seu código é um limite no número de conexões de saída, que são atualmente 600 conexões ativas (total de 1.200) por instância. Ao alcançar esse limite, o runtime das funções criará um log com a seguinte mensagem: Host thresholds exceeded: Connections. Para saber mais, confira Limites do serviço do Functions.

Esse limite é por instância. Quando o controlador de escala adiciona instâncias do aplicativo de funções para lidar com mais solicitações, cada instância tem um limite de conexão independente. Isso significa que não há nenhum limite de conexão global e você pode ter muito mais do que 600 conexões ativas em todas as instâncias ativas.

Ao solucionar problemas, certifique-se de ter habilitado Application Insights para seu aplicativo de funções. Application Insights permite exibir métricas para seus aplicativos de funções, como execuções. Para obter mais informações, consulte Exibir telemetria no Application Insights.

Clientes estáticos

Para evitar manter mais conexões que o necessário, reutilize as instâncias do cliente em vez de criar novas com cada invocação de função. É recomendável reutilizar conexões de cliente para qualquer idioma em que você possa escrever sua função. Clientes .NET como o HttpClient, o DocumentClient e os clientes de Armazenamento do Microsoft Azure poderão gerenciar conexões, se você usar um único cliente estático.

Aqui estão algumas diretrizes a serem seguidas quando você estiver usando um cliente específico do serviço em um aplicativo Azure Functions:

  • Não crie um novo cliente com cada invocação de função.
  • Crie um cliente único e estático que possa ser usado por todas as invocações de funções.
  • Considere criar um cliente único e estático em uma classe do auxiliar compartilhada, se diferentes funções usarem o mesmo serviço.

Exemplos de código do cliente

Esta seção demonstra as melhores práticas para criar e usar clientes de seu código de função.

Solicitações HTTP

Aqui está um exemplo de C# função de código que cria um estático 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
}

Uma pergunta comum sobre o HttpClient no .NET é "Devo descartar meu cliente?" Em geral, você descarta objetos que implementam IDisposable quando você termina de usá-los. Mas você não descartar um cliente estático porque não está pronto usando-o quando a função termina. Você quer que o cliente estático permaneça durante a duração do aplicativo.

Clientes do Azure Cosmos DB

O DocumentClient conecta uma instância do Azure Cosmos DB. A documentação do Azure Cosmos DB recomenda que você use um cliente singleton do Azure Cosmos DB pelo tempo de vida do aplicativo. O exemplo a seguir mostra um padrão para fazer isso em uma função:

#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
}

Além disso, crie um arquivo chamado "function. proj" para seu gatilho e adicione o conteúdo abaixo:


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

Conexões SqlClient

O código de função pode usar o Provedor de Dados .NET Framework para SQL Server (SqlClient) para fazer conexões com um Banco de Dados SQL relacional. Esse também é o provedor subjacente de estruturas de dados que dependem do ADO.NET, como o Entity Framework. Ao contrário das conexões HttpClient e DocumentClient, o ADO.NET implementa o pool de conexões por padrão. No entanto, como você ainda pode ficar sem conexões, é necessário otimizar as conexões com o banco de dados. Para obter mais informações, consulte Pool de Conexões do SQL Server (ADO.NET).

Dica

Algumas estruturas de dados, como Entity Framework, normalmente obtêm cadeias de conexão da seção ConnectionStrings de um arquivo de configuração. Nesse caso, é necessário adicionar explicitamente as cadeias de conexão de banco de dados SQL à coleção Cadeias de conexão das configurações de aplicativo de funções e no local.settings.json file no projeto local. Se estiver criando um SqlConnection no código de função, você deverá armazenar o valor da cadeia de conexão em Configurações de aplicativos com as outras conexões.

Próximas etapas

Para obter mais informações sobre o motivo pelo qual os clientes estáticos são recomendados, consulte Antipadrão de instanciação inadequada.

Para obter mais dicas de desempenho do Azure Functions, consulte Melhore o desempenho e a confiabilidade do Azure Functions.