Gerir ligações nas Funções do Azure
As funções em um aplicativo de função compartilham recursos. Entre esses recursos compartilhados estão conexões: conexões HTTP, conexões de banco de dados e conexões com serviços como o Armazenamento do Azure. Quando muitas funções estão sendo executadas simultaneamente em um plano de consumo, é possível ficar sem conexões disponíveis. Este artigo explica como codificar suas funções para evitar o uso de mais conexões do que as necessárias.
Nota
Os limites de conexão descritos neste artigo aplicam-se somente quando executados em um plano de consumo. No entanto, as técnicas descritas aqui podem ser benéficas quando executadas em qualquer plano.
Limite de ligações
O número de conexões disponíveis em um plano de Consumo é limitado, em parte porque um aplicativo de função nesse plano é executado em um ambiente de área restrita. Uma das restrições que a sandbox impõe ao seu código é um limite no número de conexões de saída, que atualmente é de 600 conexões ativas (1.200 no total) por instância. Quando você atinge esse limite, o tempo de execução das funções grava a seguinte mensagem nos logs: Host thresholds exceeded: Connections
. Para obter mais informações, consulte os limites do serviço Funções.
Este limite é por exemplo. Quando o controlador de escala adiciona instâncias de aplicativo de função para lidar com mais solicitações, cada instância tem um limite de conexão independente. Isso significa que não há limite de conexão global e você pode ter muito mais de 600 conexões ativas em todas as instâncias ativas.
Ao solucionar problemas, verifique se você habilitou o Application Insights para seu aplicativo de função. O Application Insights permite visualizar métricas para seus aplicativos de função, como execuções. Para obter mais informações, consulte Exibir telemetria no Application Insights.
Clientes estáticos
Para evitar manter mais conexões do que o necessário, reutilize instâncias de cliente em vez de criar novas com cada chamada de função. Recomendamos reutilizar conexões de cliente para qualquer idioma em que você possa escrever sua função. Por exemplo, clientes .NET como os clientes HttpClient, DocumentClient e Armazenamento do Azure podem 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 de serviço em um aplicativo do Azure Functions:
- Não crie um novo cliente com cada chamada de função.
- Crie um único cliente estático que cada invocação de função possa usar.
- Considere a criação de um único cliente estático em uma classe auxiliar compartilhada se diferentes funções usarem o mesmo serviço.
Exemplos de código de cliente
Esta seção demonstra as práticas recomendadas para criar e usar clientes a partir do seu código de função.
Pedidos HTTP
Aqui está um exemplo de código de função C# que cria uma instância estática de 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 HttpClient no .NET é "Devo descartar meu cliente?" Em geral, você descarta objetos que são implementados IDisposable
quando termina de usá-los. Mas você não descarta um cliente estático porque não termina de usá-lo quando a função termina. Você deseja que o cliente estático viva durante a duração do seu aplicativo.
Clientes do Azure Cosmos DB
O CosmosClient se conecta a 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 durante o tempo de vida do seu 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 o 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
Seu código de função pode usar o Provedor de Dados do .NET Framework para SQL Server (SqlClient) para fazer conexões com um banco de dados relacional SQL. Esse também é o provedor subjacente para estruturas de dados que dependem de ADO.NET, como o Entity Framework. Ao contrário das conexões HttpClient e DocumentClient , ADO.NET implementa o pool de conexões por padrão. Mas como você ainda pode ficar sem conexões, você deve otimizar as conexões com o banco de dados. Para obter mais informações, consulte Pool de conexões do SQL Server (ADO.NET).
Gorjeta
Algumas estruturas de dados, como o Entity Framework, normalmente obtêm cadeias de conexão da seção ConnectionStrings de um arquivo de configuração. Nesse caso, você deve adicionar explicitamente cadeias de conexão do banco de dados SQL à coleção Cadeias de conexão das configurações do seu aplicativo de função e no arquivo local.settings.json em seu projeto local. Se você estiver criando uma instância de SqlConnection em seu código de função, deverá armazenar o valor da cadeia de conexão nas configurações do aplicativo com suas outras conexões.
Próximos passos
Para obter mais informações sobre por que recomendamos clientes estáticos, consulte Antipadrão de instanciação impróprio.
Para obter mais dicas de desempenho do Azure Functions, consulte Otimizar o desempenho e a confiabilidade do Azure Functions.