A concorrência de instâncias define o número máximo de requisições simultâneas que cada instância de função pode processar por vez. Use o recurso de concorrência de instâncias do Function Compute para gerencie o uso de recursos de forma eficiente durante picos de tráfego e mitigar o impacto de cold starts. Isso ajuda a melhorar o desempenho e reduzir custos.
Informações básicas
O faturamento do uso de recursos do Function Compute tem como base a duração da execução e as especificações das instâncias de função. Portanto, quanto maior a duração da execução de uma instância de função, maiores serão as taxas de uso de recursos.
Por exemplo, considere que três requisições precisem ser processadas ao mesmo tempo e que o processamento de cada uma dure 10 segundos. Os itens a seguir descrevem a duração da execução para diferentes configurações de concorrência:
Se a concorrência de instâncias estiver definida como 1, cada instância poderá processar apenas uma requisição por vez. O Function Compute crie três instâncias para processar as três requisições. A duração total da execução é de 30 segundos.
Caso a concorrência de instâncias esteja definida como 10 e esse valor não exceda o limite de consultas por segundo (QPS) da instância, cada instância poderá processar 10 requisições simultaneamente. Nesse cenário, o Function Compute crie apenas uma instância para atender às três requisições. A duração total da execução é de 10 segundos.
Quando a concorrência de uma instância de função é defina como 1, cada instância processa somente uma requisição por vez. Ao defina a concorrência de instâncias com um valor superior a 1, o Function Compute crie uma nova instância apenas quando o número de requisições processadas simultaneamente pelas instâncias existentes ultrapassa o valor especifique.
Geralmente, a concorrência de instâncias é configure em conjunto com as especificações da instância. Essa prática facilita a otimização do desempenho da função e a redução de custos.
A figura a seguir ilustra a diferença na execução de requisições quando a concorrência de instâncias assume valores distintos.
Benefícios
-
Redução da duração da execução e dos custos.
Em funções que envolvem muitas operações de I/O, por exemplo, é possível usar uma única instância para processar várias requisições simultaneamente. Isso diminui a quantidade de instâncias necessárias para o processamento e reduz a duração total da execução das requisições.
-
Compartilhamento de status entre requisições.
Várias requisições podem compartilhar o pool de conexões de um banco de dados em uma única instância, minimizando assim o número de conexões entre as requisições e o banco de dados.
-
Diminuição da frequência de cold starts.
Como uma instância consegue processar múltiplas requisições, a criação de novas instâncias ocorre com menos frequência, o que reduz também a ocorrência de cold starts.
-
Economia de endereços IP em uma Virtual Private Cloud (VPC).
Para um volume fixo de requisições, a capacidade de processar múltiplas requisições por instância reduz o número total de instâncias necessárias. Consequentemente, há menor consumo de endereços IP na VPC.
ImportanteCertifique-se de que o vSwitch associado à sua VPC possua pelo menos dois endereços IP disponíveis. Caso contrário, os services podem ficar indisponíveis, causando falhas nas requisições.
Cenários
Recomenda-se usar uma única instância para processar múltiplas requisições simultaneamente quando a função demora muito para obter respostas de services downstream. Na maioria dos casos, a espera por respostas não consome recursos computacionais. O processamento simultâneo de várias requisições em uma mesma instância gera economia de custos e melhora tanto a responsividade quanto o throughput das aplicações.
Limites
Item | Limite |
Ambiente de runtime compatível com a camada. |
|
Valor válido para concorrência de instâncias | 1 a 200 |
Logs de execução de função fornecidos no header de resposta X-Fc-Log-Result | Não compatível se a concorrência de instâncias for defina com um valor maior que 1 |
Procedimento
Especifique a concorrência de instâncias no momento da criação da função.
Para alterar a concorrência de instâncias de uma função existente, acesse a página de detalhes da função e clique em na aba Configurations. Em seguida, na seção Instance Configuration, clique em Modify. No painel exibido, modifique a concorrência de instâncias conforme necessário.
Impactos
Esta seção detalha as diferenças entre o cenário em que uma instância processa apenas uma requisição por vez (Concorrência de Instâncias = 1) e o cenário em que uma instância processa múltiplas requisições simultaneamente (Concorrência de Instâncias > 1).
Billing
A duração da execução e o custo de uma instância de função variam conforme a concorrência de instâncias. Para mais informações, consulte Billing overview.
-
Concorrência de Instâncias = 1
A instância processa apenas uma requisição por vez. O período de faturamento inicia quando a primeira requisição começa a ser processada e termina quando a última requisição é concluída.
-
Concorrência de Instâncias > 1
A instância processa múltiplas requisições simultaneamente. A duração real de execução da instância serve como base para medir o tempo de execução da função. O período de faturamento começa no início do processamento da primeira requisição e encerra após a conclusão da última requisição.
Concurrency throttling
Por padrão, o Function Compute suporta até 100 instâncias sob demanda em uma região. O cálculo do número máximo de requisições que podem ser processadas simultaneamente em uma região segue a fórmula: 100 × Concorrência de Instâncias. Por exemplo, ao defina a concorrência de instâncias como 10, a região poderá processar no máximo 1.000 requisições simultâneas. Se o volume de requisições concorrentes exceder a capacidade máxima de processamento do Function Compute, o sistema retornará o erro de limitação ResourceExhausted.
Para aumentar o número máximo de instâncias em uma região, contact us.
Logging
Com a concorrência de instâncias defina como 1, o Function Compute retorna os logs da função no header de resposta
X-Fc-Log-Resultcaso você especifiqueX-Fc-Log-Type: Tailno header da requisição HTTP ao invocar a função. Quando a concorrência de instâncias é maior que 1, o header de resposta não inclui os logs da função, pois não é possível isolar os logs de uma requisição específica dentre as requisições concorrentes.-
No runtime Node.js, a função
console.info()era utilizada para retornar logs contendo os IDs das requisições. Entretanto, se a Concorrência de Instâncias for maior que 1, aconsole.info()não exibirá os IDs das requisições corretamente. Todos os IDs aparecerão comoreq 2. O exemplo abaixo mostra um log nesse formato:2019-11-06T14:23:37.587Z req1 [info] logger begin 2019-11-06T14:23:37.587Z req1 [info] ctxlogger begin 2019-11-06T14:23:37.587Z req2 [info] logger begin 2019-11-06T14:23:37.587Z req2 [info] ctxlogger begin 2019-11-06T14:23:40.587Z req1 [info] ctxlogger end 2019-11-06T14:23:40.587Z req2 [info] ctxlogger end 2019-11-06T14:23:37.587Z req2 [info] logger end 2019-11-06T14:23:37.587Z req2 [info] logger endNessa situação, recomenda-se o uso de
context.logger.info()para imprimir os logs. Esse método garante a exibição correta dos IDs das requisições. Veja o código de exemplo a seguir:exports.handler = (event, context, callback) => { console.info('logger begin'); context.logger.info('ctxlogger begin'); setTimeout(function() { context.logger.info('ctxlogger end'); console.info('logger end'); callback(null, 'hello world'); }, 3000); };
Error handling
Quando uma instância processa múltiplas requisições simultaneamente, o encerramento inesperado do processo causado por uma falha em uma requisição pode afetar as demais requisições concorrentes. Por isso, é essencial implementar lógica de captura de exceções no nível da requisição dentro do código da função, evitando impactos negativos nas outras requisições. O exemplo a seguir apresenta um código em Node.js:
exports.handler = (event, context, callback) => {
try {
JSON.parse(event);
} catch (ex) {
callback(ex);
}
callback(null, 'hello world');
};
Shared variables
Erros podem ocorrer se múltiplas requisições tentarem modifique a mesma variável simultaneamente enquanto uma instância processa requisições concorrentes. Utilize mecanismos de exclusão mútua no código para impedir modificações de variáveis que não sejam seguras para threads. O exemplo abaixo demonstra um código em Java:
public class App implements StreamRequestHandler
{
private static int counter = 0;
@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
synchronized (this) {
counter = counter + 1;
}
outputStream.write(new String("hello world").getBytes());
}
}