Implementação sem tempo de inatividade para Durable Functions
O modelo de execução fiável do Durable Functions requer que as orquestrações sejam deterministas, o que cria um desafio adicional a considerar ao implementar atualizações. Quando uma implementação contém alterações às assinaturas da função de atividade ou à lógica do orquestrador, as instâncias de orquestração em fluxo falham. Esta situação é especialmente um problema para instâncias de orquestrações de longa duração, que podem representar horas ou dias de trabalho.
Para impedir que estas falhas aconteçam, tem duas opções:
- Atrase a implementação até que todas as instâncias de orquestração em execução estejam concluídas.
- Certifique-se de que todas as instâncias de orquestração em execução utilizam as versões existentes das suas funções.
O gráfico seguinte compara as três estratégias principais para alcançar uma implementação de tempo de inatividade zero para Durable Functions:
Estratégia | Quando utilizar | Vantagens | Desvantagens |
---|---|---|---|
Controlo de versões | Aplicações que não experimentam alterações interruptivas frequentes. | Simples de implementar. | Aumento do tamanho da aplicação de funções na memória e no número de funções. Duplicação de código. |
Verificação de estado com bloco | Um sistema que não tem orquestrações de longa duração que durem mais de 24 horas ou orquestrações frequentemente sobrepostas. | Base de código simples. Não requer gestão adicional da aplicação de funções. |
Requer gestão adicional da conta de armazenamento ou do hub de tarefas. Requer períodos de tempo em que não existem orquestrações em execução. |
Encaminhamento de aplicações | Um sistema que não tem períodos de tempo em que as orquestrações não estão em execução, como os períodos de tempo com orquestrações que duram mais de 24 horas ou com orquestrações frequentemente sobrepostas. | Processa novas versões de sistemas com orquestrações em execução contínuas que têm alterações interruptivas. | Requer um router de aplicação inteligente. Pode exceder o número máximo de aplicações de funções permitidas pela sua subscrição. A predefinição é 100. |
O resto deste documento descreve estas estratégias mais detalhadamente.
Nota
As descrições destas estratégias de implementação de tempo de inatividade zero partem do princípio de que está a utilizar o fornecedor de Armazenamento do Azure predefinido para Durable Functions. A documentação de orientação poderá não ser adequada se estiver a utilizar um fornecedor de armazenamento diferente do fornecedor de Armazenamento do Azure predefinido. Para obter mais informações sobre as várias opções do fornecedor de armazenamento e como se comparam, veja a documentação Durable Functions fornecedores de armazenamento.
Controlo de versões
Defina novas versões das suas funções e deixe as versões antigas na sua aplicação de funções. Como pode ver no diagrama, a versão de uma função torna-se parte do respetivo nome. Uma vez que as versões anteriores das funções são preservadas, as instâncias de orquestração em voo podem continuar a referenciá-las. Entretanto, os pedidos de novas instâncias de orquestração exigem a versão mais recente, que a função de cliente orchestration pode referenciar a partir de uma definição de aplicação.
Nesta estratégia, todas as funções têm de ser copiadas e as respetivas referências a outras funções têm de ser atualizadas. Pode torná-lo mais fácil ao escrever um script. Eis um projeto de exemplo com um script de migração.
Nota
Esta estratégia utiliza blocos de implementação para evitar períodos de indisponibilidade durante a implementação. Para obter informações mais detalhadas sobre como criar e utilizar novos blocos de implementação, veja Funções do Azure blocos de implementação.
Verificação de estado com bloco
Enquanto a versão atual da aplicação de funções estiver em execução no bloco de produção, implemente a nova versão da sua aplicação de funções no bloco de teste. Antes de trocar os blocos de produção e de teste, verifique se existem instâncias de orquestração em execução. Depois de todas as instâncias de orquestração estarem concluídas, pode fazer a troca. Esta estratégia funciona quando tem períodos previsíveis quando não existem instâncias de orquestração em movimento. Esta é a melhor abordagem quando as orquestrações não são de longa duração e quando as execuções de orquestração não se sobrepõem frequentemente.
Configuração da aplicação de funções
Utilize o procedimento seguinte para configurar este cenário.
Adicione blocos de implementação à sua aplicação de funções para teste e produção.
Para cada bloco, defina a definição da aplicação AzureWebJobsStorage para a cadeia de ligação de uma conta de armazenamento partilhada. Esta cadeia de ligação da conta de armazenamento é utilizada pelo Funções do Azure runtime para armazenar as chaves de acesso das funções de forma segura.
Para cada bloco, crie uma nova definição de aplicação, por exemplo,
DurableManagementStorage
. Defina o respetivo valor para a cadeia de ligação de diferentes contas de armazenamento. Estas contas de armazenamento são utilizadas pela extensão Durable Functions para uma execução fiável. Utilize uma conta de armazenamento separada para cada bloco. Não marque esta definição como uma definição de bloco de implementação.Na secção durableTask do ficheiro host.json da sua aplicação de funções, especifique
connectionStringName
(Durable 2.x) ouazureStorageConnectionStringName
(Durable 1.x) como o nome da definição da aplicação que criou no passo 3.
O diagrama seguinte mostra a configuração descrita de blocos de implementação e contas de armazenamento. Neste cenário potencial de pré-implementação, a versão 2 de uma aplicação de funções está em execução no bloco de produção, enquanto a versão 1 permanece no bloco de teste.
exemplos host.json
Os seguintes fragmentos JSON são exemplos da definição da cadeia de ligação no ficheiro host.json .
Funções 2.0
{
"version": 2.0,
"extensions": {
"durableTask": {
"hubName": "MyTaskHub",
"storageProvider": {
"connectionStringName": "DurableManagementStorage"
}
}
}
}
Funções 1.x
{
"durableTask": {
"azureStorageConnectionStringName": "DurableManagementStorage"
}
}
Configuração do pipeline CI/CD
Configure o pipeline CI/CD para implementar apenas quando a aplicação de funções não tiver instâncias de orquestração pendentes ou em execução. Quando estiver a utilizar o Azure Pipelines, pode criar uma função que verifica estas condições, tal como no exemplo seguinte:
[FunctionName("StatusCheck")]
public static async Task<IActionResult> StatusCheck(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestMessage req,
[DurableClient] IDurableOrchestrationClient client,
ILogger log)
{
var runtimeStatus = new List<OrchestrationRuntimeStatus>();
runtimeStatus.Add(OrchestrationRuntimeStatus.Pending);
runtimeStatus.Add(OrchestrationRuntimeStatus.Running);
var result = await client.ListInstancesAsync(new OrchestrationStatusQueryCondition() { RuntimeStatus = runtimeStatus }, CancellationToken.None);
return (ActionResult)new OkObjectResult(new { HasRunning = result.DurableOrchestrationState.Any() });
}
Em seguida, configure a porta de teste para aguardar até que nenhuma orquestração esteja em execução. Para obter mais informações, veja Controlo de implementação de versões com portas
O Azure Pipelines verifica a execução de instâncias de orquestração na sua aplicação de funções antes do início da implementação.
Agora, a nova versão da sua aplicação de funções deve ser implementada no bloco de teste.
Por fim, troque os blocos.
As definições da aplicação que não estão marcadas como definições do bloco de implementação também são trocadas, pelo que a aplicação da versão 2 mantém a respetiva referência à conta de armazenamento A. Uma vez que o estado de orquestração é controlado na conta de armazenamento, todas as orquestrações em execução na aplicação versão 2 continuam a ser executadas no novo bloco sem interrupções.
Para utilizar a mesma conta de armazenamento para ambos os blocos, pode alterar os nomes dos seus hubs de tarefas. Neste caso, tem de gerir o estado dos blocos e as definições do HubName da sua aplicação. Para saber mais, veja Hubs de tarefas no Durable Functions.
Encaminhamento de aplicações
Esta estratégia é a mais complexa. No entanto, pode ser utilizado para aplicações de funções que não têm tempo entre orquestrações em execução.
Para esta estratégia, tem de criar um router de aplicação à frente da sua Durable Functions. Este router pode ser implementado com Durable Functions. O router tem a responsabilidade de:
- Implementar a aplicação de funções.
- Gerir a versão do Durable Functions.
- Encaminhar pedidos de orquestração para aplicações de funções.
Quando um pedido de orquestração é recebido pela primeira vez, o router faz as seguintes tarefas:
- Cria uma nova aplicação de funções no Azure.
- Implementa o código da aplicação de funções na nova aplicação de funções no Azure.
- Reencaminha o pedido de orquestração para a nova aplicação.
O router gere o estado da versão do código da aplicação que é implementada na aplicação de funções no Azure.
O router direciona os pedidos de implementação e orquestração para a aplicação de funções adequada com base na versão enviada com o pedido. Ignora a versão do patch.
Quando implementa uma nova versão da sua aplicação sem uma alteração interruptiva, pode incrementar a versão do patch. O router é implementado na sua aplicação de funções existente e envia pedidos para as versões antigas e novas do código, que são encaminhados para a mesma aplicação de funções.
Quando implementa uma nova versão da sua aplicação com uma alteração interruptiva, pode incrementar a versão principal ou secundária. Em seguida, o router de aplicação cria uma nova aplicação de funções no Azure, implementa na mesma e encaminha os pedidos para a nova versão da sua aplicação para a mesma. No diagrama seguinte, a execução de orquestrações na versão 1.0.1 da aplicação continua em execução, mas os pedidos para a versão 1.1.0 são encaminhados para a nova aplicação de funções.
O router monitoriza o estado das orquestrações na versão 1.0.1 e remove as aplicações após todas as orquestrações serem concluídas.
Controlar as definições da loja
Cada aplicação de funções deve utilizar filas de agendamento separadas, possivelmente em contas de armazenamento separadas. Se quiser consultar todas as instâncias de orquestração em todas as versões da sua aplicação, pode partilhar tabelas de instâncias e histórico nas suas aplicações de funções. Pode partilhar tabelas ao configurar as trackingStoreConnectionStringName
definições e trackingStoreNamePrefix
no ficheiro de definições host.json para que todas utilizem os mesmos valores.
Para obter mais informações, veja Gerir instâncias no Durable Functions no Azure.