Editar

Padrão coreográfico

Azure Event Grid
Azure Service Bus

Faça com que cada componente do sistema participe do processo de tomada de decisão sobre o fluxo de trabalho de uma transação comercial, em vez de depender de um ponto central de controle.

Contexto e problema

Na arquitetura de microsserviços, geralmente é o caso de um aplicativo baseado em nuvem ser dividido em vários pequenos serviços que trabalham juntos para processar uma transação comercial de ponta a ponta. Para reduzir o acoplamento entre serviços, cada serviço é responsável por uma única operação comercial. Alguns benefícios incluem desenvolvimento mais rápido, base de código menor e escalabilidade. No entanto, projetar um fluxo de trabalho eficiente e escalável é um desafio e muitas vezes requer uma comunicação interserviços complexa.

Os serviços se comunicam entre si usando APIs bem definidas. Mesmo uma única operação comercial pode resultar em várias chamadas ponto-a-ponto entre todos os serviços. Um padrão comum de comunicação é usar um serviço centralizado que atua como o orquestrador. Reconhece todos os pedidos recebidos e delega as operações aos respetivos serviços. Ao fazer isso, ele também gerencia o fluxo de trabalho de toda a transação comercial. Cada serviço apenas conclui uma operação e não está ciente do fluxo de trabalho geral.

O padrão orchestrator reduz a comunicação ponto-a-ponto entre serviços, mas tem algumas desvantagens devido ao acoplamento estreito entre o orchestrator e outros serviços que participam do processamento da transação comercial. Para executar tarefas em uma sequência, o orquestrador precisa ter algum conhecimento de domínio sobre as responsabilidades desses serviços. Se você quiser adicionar ou remover serviços, a lógica existente será interrompida e você precisará reconectar partes do caminho de comunicação. Embora você possa configurar o fluxo de trabalho, adicionar ou remover serviços facilmente com um orquestrador bem projetado, essa implementação é complexa e difícil de manter.

Processando uma solicitação usando um orquestrador central

Solução

Permita que cada serviço decida quando e como uma operação de negócio será processada em vez de depender de um orquestrador central.

Uma maneira de implementar coreografia é usar o padrão de mensagens assíncronas para coordenar as operações de negócios.

Processando uma solicitação usando um coreógrafo

Uma solicitação de cliente publica mensagens em uma fila de mensagens. À medida que as mensagens chegam, elas são enviadas para assinantes, ou serviços, interessados nessa mensagem. Cada serviço inscrito faz sua operação conforme indicado pela mensagem e responde à fila de mensagens com sucesso ou falha da operação. Em caso de sucesso, o serviço pode enviar uma mensagem de volta para a mesma fila ou uma fila de mensagens diferente para que outro serviço possa continuar o fluxo de trabalho, se necessário. Se uma operação falhar, o barramento de mensagens poderá repetir essa operação.

Desta forma, os serviços coreografam o fluxo de trabalho entre si sem depender de um orquestrador ou ter comunicação direta entre eles.

Como não há comunicação ponto-a-ponto, esse padrão ajuda a reduzir o acoplamento entre serviços. Além disso, ele pode remover o gargalo de desempenho causado pelo orquestrador quando ele tem que lidar com todas as transações.

Quando utilizar este padrão

Use o padrão de coreografia se você espera atualizar ou substituir serviços com freqüência e adicionar ou remover alguns serviços eventualmente. Todo o aplicativo pode ser modificado com menos esforço e interrupção mínima nos serviços existentes.

Considere esse padrão se você tiver gargalos de desempenho no orquestrador central.

Esse padrão é um modelo natural para a arquitetura sem servidor, onde todos os serviços podem ser de curta duração ou orientados a eventos. Os serviços podem girar por causa de um evento, fazer sua tarefa e são removidos quando a tarefa é concluída.

Problemas e considerações

Descentralizar o orquestrador pode causar problemas ao gerenciar o fluxo de trabalho.

Se um serviço não conseguir concluir uma operação de negócios, pode ser difícil recuperar dessa falha. Uma maneira é fazer com que o serviço indique falha disparando um evento. Outro serviço assina esses eventos com falha, toma as ações necessárias, como aplicar transações de compensação para desfazer operações bem-sucedidas em uma solicitação. O serviço com falha também pode falhar ao disparar um evento para a falha. Nesse caso, considere usar um mecanismo de repetição e/ou tempo limite para reconhecer essa operação como uma falha. Para obter um exemplo, consulte a seção Exemplo .

É simples implementar um fluxo de trabalho quando você deseja processar operações de negócios independentes em paralelo. Você pode usar um único barramento de mensagem. No entanto, o fluxo de trabalho pode se tornar complicado quando a coreografia precisa ocorrer em uma sequência. Por exemplo, o Serviço C só pode iniciar a sua operação depois de o Serviço A e o Serviço B terem concluído as suas operações com êxito. Uma abordagem é ter vários barramentos de mensagens ou filas que recebem mensagens na ordem necessária. Para obter mais informações, consulte a seção Exemplo .

O padrão coreográfico torna-se um desafio se o número de serviços crescer rapidamente. Dado o elevado número de peças móveis independentes, o fluxo de trabalho entre serviços tende a tornar-se complexo. Além disso, o rastreamento distribuído torna-se difícil.

O orquestrador gerencia centralmente a resiliência do fluxo de trabalho e ele pode se tornar um único ponto de falha. Por outro lado, para a coreografia, o papel distribui-se por todos os serviços e a resiliência torna-se menos robusta.

Cada serviço não é apenas responsável pela resiliência da sua operação, mas também pelo fluxo de trabalho. Esta responsabilidade pode ser onerosa para o serviço e difícil de implementar. Cada serviço deve repetir falhas transitórias, não transitórias e de tempo limite, para que a solicitação termine normalmente, se necessário. Além disso, o serviço deve ser diligente na comunicação do sucesso ou fracasso da operação para que outros serviços possam agir em conformidade.

Design da carga de trabalho

Um arquiteto deve avaliar como o padrão de coreografia pode ser usado no design de sua carga de trabalho para abordar as metas e os princípios abordados nos pilares do Azure Well-Architected Framework. Por exemplo:

Pilar Como esse padrão suporta os objetivos do pilar
A Excelência Operacional ajuda a fornecer qualidade de carga de trabalho por meio de processos padronizados e coesão da equipe. Como os componentes distribuídos nesse padrão são autônomos e projetados para serem substituíveis, você pode modificar a carga de trabalho com menos alterações gerais no sistema.

- OE:04 Ferramentas e processos
A Eficiência de Desempenho ajuda sua carga de trabalho a atender às demandas de forma eficiente por meio de otimizações em escala, dados e código. Esse padrão fornece uma alternativa quando gargalos de desempenho ocorrem em uma topologia de orquestração centralizada.

- PE:02 Planeamento da capacidade
- PE:05 Dimensionamento e particionamento

Como em qualquer decisão de design, considere quaisquer compensações em relação aos objetivos dos outros pilares que possam ser introduzidos com esse padrão.

Exemplo

Este exemplo mostra o padrão de coreografia criando uma carga de trabalho nativa da nuvem orientada por eventos executando funções junto com microsserviços. Quando um cliente solicita que um pacote seja enviado, a carga de trabalho atribui um drone. Assim que o pacote estiver pronto para ser retirado pelo drone agendado, o processo de entrega é iniciado. Durante o trânsito, a carga de trabalho lida com a entrega até que ela ganhe o status de remessa.

Este exemplo é uma refatoração da implementação do Drone Delivery que substitui o padrão Orchestrator pelo padrão Coreografia.

Diagrama de uma carga de trabalho nativa de nuvem orientada a eventos implementando padrão coreográfico

O serviço Ingestão trata dos pedidos do cliente e converte-os em mensagens, incluindo os detalhes da entrega. As transações comerciais são iniciadas após o consumo dessas novas mensagens.

Uma transação comercial de um único cliente requer três operações comerciais distintas: criar ou atualizar um pacote, atribuir um drone para entregar o pacote e o manuseio adequado da entrega, que consiste em verificar e, eventualmente, aumentar a conscientização quando enviado. Três microsserviços realizam o processamento do negócio: Pacote, Agendador de Drone e Serviços de Entrega. Em vez de um orquestrador central, os serviços usam mensagens para se comunicar entre si. Cada serviço seria responsável por implementar antecipadamente um protocolo que coordena de forma descentralizada o fluxo de trabalho do negócio.

Estruturar

A transação comercial é processada em uma sequência através de vários saltos. Cada salto está compartilhando um único barramento de mensagem entre todos os serviços empresariais.

Quando um cliente envia uma solicitação de entrega por meio de um ponto de extremidade HTTP, o serviço Ingestão a recebe, converte essa solicitação em uma mensagem e, em seguida, publica a mensagem no barramento de mensagens compartilhadas. Os serviços empresariais subscritos vão consumir novas mensagens adicionadas ao autocarro. Ao receber a mensagem, os serviços empresariais podem concluir a operação com êxito, falha ou o tempo limite da solicitação pode expirar. Se for bem-sucedido, os serviços respondem ao barramento com o código de status Ok, geram uma nova mensagem de operação e a enviam para o barramento de mensagens. Se houver uma falha ou tempo limite, o serviço relata a falha enviando o código de motivo para o barramento de mensagens. Além disso, a mensagem será escrita em letra morta para tratamento posterior. As mensagens que não puderam ser recebidas ou processadas dentro de um período de tempo razoável e apropriado também são movidas para o DLQ.

O design usa vários barramentos de mensagens para processar toda a transação comercial. O Barramento de Serviço do Microsoft Azure e a Grade de Eventos do Microsoft Azure são compostos para fornecer a plataforma de serviço de mensagens para esse design. A carga de trabalho é implantada em Aplicativos de Contêiner do Azure que hospedam o Azure Functions para ingestão e aplicativos que manipulam processamento controlado por eventos que executa a lógica de negócios.

O design garante que a coreografia ocorra em sequência. Um único namespace do Barramento de Serviço do Azure contém um tópico com duas assinaturas e uma fila com reconhecimento de sessão. O serviço Ingestão publica mensagens sobre o tema. O serviço Package e o serviço Drone Scheduler subscrevem o tópico e publicam mensagens comunicando o sucesso à fila. Incluindo um identificador de sessão comum que um GUID associado ao identificador de entrega, permite o tratamento ordenado de sequências não limitadas de mensagens relacionadas. O serviço de Entrega aguarda duas mensagens relacionadas por transação. A primeira mensagem indica que o pacote está pronto para ser enviado e a segunda indica que um drone está programado.

Esse design usa o Barramento de Serviço do Azure para lidar com mensagens de alto valor que não podem ser perdidas ou duplicadas durante todo o processo de entrega. Quando o pacote é enviado, também é publicada uma alteração de estado para a Grade de Eventos do Azure. Neste design, o remetente do evento não tem nenhuma expectativa sobre como a mudança de estado é tratada. Os serviços de organização downstream que não estão incluídos como parte desse design podem estar ouvindo esse tipo de evento e reagir executando uma lógica de propósito comercial específica (ou seja, enviar por e-mail o status do pedido enviado para o usuário).

Se você estiver planejando implantar isso em outro serviço de computação, como o aplicativo de padrão pub-sub AKS , a boilplate pode ser implementada com dois contêineres no mesmo pod. Um contêiner executa o embaixador que interage com seu barramento de mensagens de preferência, enquanto o outro executa a lógica de negócios. A abordagem com dois contêineres no mesmo pod melhora o desempenho e a escalabilidade. O embaixador e o serviço de negócios compartilham a mesma rede, permitindo baixa latência e alta taxa de transferência.

Para evitar operações de repetição em cascata que podem levar a vários esforços, os serviços empresariais devem sinalizar imediatamente mensagens inaceitáveis. É possível enriquecer essas mensagens usando códigos de motivo bem conhecidos ou um código de aplicativo definido, para que possam ser movidos para uma fila de letra morta (DLQ). Considere gerenciar problemas de consistência implementando o Saga a partir de serviços downstream. Por exemplo, outro serviço poderia lidar com mensagens com letras mortas para fins de correção apenas executando uma transação de compensação, rety ou pivot.

Os serviços empresariais são idempotentes para garantir que as operações de repetição não resultem em recursos duplicados. Por exemplo, o serviço de pacote usa operações upsert para adicionar dados ao armazenamento de dados.

Considere esses padrões em seu design para coreografia.