CoreografiaChoreography

Fazer 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.Have each component of the system participate in the decision-making process about the workflow of a business transaction, instead of relying on a central point of control.

Contexto e problemaContext and problem

Na arquitetura de microsserviços, muitas vezes é o caso de que um aplicativo baseado em nuvem é dividido em vários pequenos serviços que trabalham juntos para processar uma transação comercial de ponta a ponta.In microservices architecture, it’s often the case that a cloud-based application is divided into several small services that work together to process a business transaction end-to-end. Para diminuir o acoplamento entre os serviços, cada serviço é responsável por uma única operação comercial.To lower coupling between services, each service is responsible for a single business operation. Alguns benefícios incluem desenvolvimento mais rápido, base de código menor e escalabilidade.Some benefits include faster development, smaller code base, and scalability. No entanto, projetar um fluxo de trabalho eficiente e escalável é um desafio e muitas vezes requer uma comunicação intersporizada complexa.However, designing an efficient and scalable workflow is a challenge and often requires complex interservice communication.

Os serviços se comunicam entre si usando APIs bem definidas.The services communicate with each other by using well-defined APIs. Mesmo uma única operação de negócios pode resultar em várias chamadas ponto a ponto entre todos os serviços.Even a single business operation can result in multiple point-to-point calls among all services. Um padrão comum de comunicação é usar um serviço centralizado que atua como o orquestrador.A common pattern for communication is to use a centralized service that acts as the orchestrator. Reconhece todas as solicitações recebidas e delega operações aos respectivos serviços.It acknowledges all incoming requests and delegates operations to the respective services. Ao fazer isso, também gerencia o fluxo de trabalho de toda a transação comercial.In doing so, it also manages the workflow of the entire business transaction. Cada serviço apenas completa uma operação e não está ciente do fluxo de trabalho geral.Each service just completes an operation and is not aware of the overall workflow.

O padrão orquestrador reduz a comunicação ponto a ponto entre os serviços, mas tem algumas desvantagens devido ao acoplamento apertado entre o orquestrador e outros serviços que participam no processamento da transação comercial.The orchestrator pattern reduces point-to-point communication between services but has some drawbacks because of the tight coupling between the orchestrator and other services that participate in processing of the business transaction. Para executar tarefas em sequência, o orquestrador precisa ter algum conhecimento de domínio sobre as responsabilidades desses serviços.To execute tasks in a sequence, the orchestrator needs to have some domain knowledge about the responsibilities of those services. Se você quiser adicionar ou remover serviços, a lógica existente quebrará e você precisará religar partes do caminho de comunicação.If you want to add or remove services, existing logic will break, and you'll need to rewire portions of the communication path. Embora você possa configurar o fluxo de trabalho, adicionar ou remover serviços facilmente com um orquestrador bem projetado, tal implementação é complexa e difícil de manter.While you can configure the workflow, add or remove services easily with a well-designed orchestrator, such an implementation is complex and hard to maintain.

Processando uma solicitação usando um orquestrador central

SoluçãoSolution

Permita que cada serviço decida quando e como uma operação comercial será processada, em vez de depender de um orquestrador central.Let each service decide when and how a business operation is processed, instead of depending on a central orchestrator.

Uma maneira de implementar a coreografia é usar o padrão de mensagens assíncronas para coordenar as operações de negócios.One way to implement choreography is to use the asynchronous messaging pattern to coordinate the business operations.

Processando uma solicitação usando um coreógrafo

Uma solicitação de cliente publica mensagens em uma fila de mensagens.A client request publishes messages to a message queue. À medida que as mensagens chegam, elas são empurradas para assinantes, ou serviços, interessados nessa mensagem.As messages arrive, they are pushed to subscribers, or services, interested in that message. Cada serviço subscrito faz sua operação conforme indicado pela mensagem e responde à fila de mensagens com sucesso ou falha da operação.Each subscribed service does their operation as indicated by the message and responds to the message queue with success or failure of the operation. 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.In case of success, the service can push a message back to the same queue or a different message queue so that another service can continue the workflow if needed. Se uma operação falhar, o barramento de mensagens pode tentar novamente essa operação.If an operation fails, the message bus can retry that operation.

Dessa forma, os serviços coreografam o fluxo de trabalho entre si sem depender de um orquestrador ou ter comunicação direta entre eles.This way, the services choreograph the workflow among themselves without depending on an orchestrator or having direct communication between them.

Como não há comunicação ponto a ponto, esse padrão ajuda a reduzir o acoplamento entre os serviços.Because there isn't point-to-point communication, this pattern helps reduce coupling between services. Além disso, ele pode remover o gargalo de desempenho causado pelo orquestrador quando ele tem que lidar com todas as transações.Also, it can remove the performance bottleneck caused by the orchestrator when it has to deal with all transactions.

Quando usar esse padrãoWhen to use this pattern

Use o padrão de coreografia se você espera atualizar, remover ou adicionar novos serviços com freqüência.Use the choreography pattern if you expect to update, remove, or add new services frequently. Todo o aplicativo pode ser modificado com menor esforço e interrupção mínima dos serviços existentes.The entire app can be modified with lesser effort and minimal disruption to existing services.

Considere este padrão se você experimentar gargalos de desempenho no orquestrador central.Consider this pattern if you experience performance bottlenecks in the central orchestrator.

Esse padrão é um modelo natural para a arquitetura sem servidor, onde todos os serviços podem ter vida curta ou impulsionados por eventos.This pattern is a natural model for the serverless architecture where all services can be short lived, or event driven. Os serviços podem girar por causa de um evento, fazer sua tarefa e são removidos quando a tarefa é concluída.Services can spin up because of an event, do their task, and are removed when the task is finished.

Problemas e consideraçõesIssues and considerations

Descentralizar o orquestrador pode causar problemas ao gerenciar o fluxo de trabalho.Decentralizing the orchestrator can cause issues while managing the workflow.

Se um serviço não concluir uma operação de negócios, pode ser difícil recuperar-se dessa falha.If a service fails to complete a business operation, it can be difficult to recover from that failure. Uma maneira é fazer com que o serviço indique falha ao disparar um evento.One way is to have the service indicate failure by firing an event. Outro serviço subscrito a esses eventos fracassados toma as ações necessárias, como aplicar transações compensatórias para desfazer operações bem sucedidas em uma solicitação.Another service subscribes to those failed events takes necessary actions such as applying compensating transactions to undo successful operations in a request. O serviço falho também pode falhar em disparar um evento para a falha.The failed service might also fail to fire an event for the failure. Nesse caso, considere usar um mecanismo de repetição e, ou tempo para fora, para reconhecer essa operação como uma falha.In that case, consider using a retry and, or time out mechanism to recognize that operation as a failure. Por exemplo, consulte a seção Exemplo.For an example, see the Example section.

É simples implementar um fluxo de trabalho quando você deseja processar operações de negócios independentes em paralelo.It's simple to implement a workflow when you want to process independent business operations in parallel. Você pode usar um único ônibus de mensagem.You can use a single message bus. No entanto, o fluxo de trabalho pode se complicar quando a coreografia precisa ocorrer em uma sequência.However, the workflow can become complicated when choreography needs to occur in a sequence. Por exemplo, o Serviço C só pode iniciar sua operação depois que o Serviço A e o Serviço B tiverem concluído suas operações com sucesso.For instance, Service C can start its operation only after Service A and Service B have completed their operations with success. Uma abordagem é ter vários ônibus de mensagens que recebem mensagens na ordem necessária.One approach is to have multiple message buses that get messages in the required order. Para obter mais informações, consulte a seção Exemplo.For more information, see the Example section.

O padrão coreográfico se torna um desafio se o número de serviços crescer rapidamente.The choreography pattern becomes a challenge if the number of services grow rapidly. Dado o alto número de peças móveis independentes, o fluxo de trabalho entre os serviços tende a ficar complexo.Given the high number of independent moving parts, the workflow between services tends to get complex. Além disso, o rastreamento distribuído torna-se difícil.Also, distributed tracing becomes difficult.

O orquestrador gerencia centralmente a resiliência do fluxo de trabalho e pode se tornar um único ponto de falha.The orchestrator centrally manages the resiliency of the workflow and it can become a single point of failure. Por outro lado, para a coreografia, o papel é distribuído entre todos os serviços e a resiliência se torna menos robusta.On the other hand, for choreography, the role is distributed between all services and resiliency becomes less robust.

Cada serviço não é responsável apenas pela resiliência de sua operação, mas também pelo fluxo de trabalho.Each service isn't only responsible for the resiliency of its operation but also the workflow. Essa responsabilidade pode ser pesada para o serviço e difícil de implementar.This responsibility can be burdensome for the service and hard to implement. Cada serviço deve tentar novamente falhas transitórias, não transitórias e de tempo, de modo que a solicitação termine graciosamente, se necessário.Each service must retry transient, nontransient, and time-out failures, so that the request terminates gracefully, if needed. Além disso, o serviço deve ser diligente em comunicar o sucesso ou o fracasso da operação para que outros serviços possam agir de acordo.Also, the service must be diligent about communicating the success or failure of the operation so that other services can act accordingly.

ExemploExample

Este exemplo mostra o padrão de coreografia com o aplicativo Drone Delivery.This example shows the choreography pattern with the Drone Delivery app. Quando um cliente solicita uma retirada, o aplicativo atribui um drone e notifica o cliente.When a client requests a pickup, the app assigns a drone and notifies the client.

Logotipo do GitHub Um exemplo desse padrão está disponível no GitHub.GitHub logo An example of this pattern is available on GitHub.

Um close-up de uma descrição do mapa gerada automaticamente

Uma única transação comercial de cliente requer três operações comerciais distintas: criar ou atualizar um pacote, atribuir um drone para entregar o pacote e verificar o status de entrega.A single client business transaction requires three distinct business operations: creating or updating a package, assigning a drone to deliver the package, and checking the delivery status. Essas operações são realizadas por três microserviços: Pacote, Agendador de Drones e Serviços de Entrega.Those operations are performed by three microservices: Package, Drone Scheduler, and Delivery services. Em vez de um orquestrador central, os serviços usam mensagens para colaborar e coordenar a solicitação entre si.Instead of a central orchestrator, the services use messaging to collaborate and coordinate the request among themselves.

DesignDesign

A transação comercial é processada em uma seqüência através de vários saltos.The business transaction is processed in a sequence through multiple hops. Cada salto tem um ônibus de mensagem e o respectivo serviço de negócios.Each hop has a message bus and the respective business service.

Quando um cliente envia uma solicitação de entrega através de um ponto final HTTP, o serviço Ingestion recebe-o, levanta um evento de operação e envia-o para um barramento de mensagens.When a client sends a delivery request through an HTTP endpoint, the Ingestion service receives it, raises an operation event, and sends it to a message bus. O ônibus invoca o serviço de negócios subscrito e envia o evento em uma solicitação POST.The bus invokes the subscribed business service and sends the event in a POST request. Ao receber o evento, o serviço de negócios pode concluir a operação com sucesso, falha ou a solicitação pode ficar sem tempo. Se for bem-sucedido, o serviço responde ao ônibus com o código de status Ok, levanta um novo evento de operação e envia-o para o ônibus de mensagem do próximo salto.On receiving the event, the business service can complete the operation with success, failure, or the request can time out. If successful, the service responds to the bus with the Ok status code, raises a new operation event, and sends it to the message bus of the next hop. Em caso de falha ou intervalo, o serviço relata falha enviando o código BadRequest para o barramento de mensagens que enviou a solicitação post original.In case of a failure or time-out, the service reports failure by sending the BadRequest code to the message bus that sent the original POST request. O ônibus de mensagens tenta novamente a operação com base em uma política de repetição.The message bus retries the operation based on a retry policy. Após esse período expirar, o ônibus de mensagem sinaliza a operação falha e o processamento adicional de toda a solicitação pára.After that period expires, message bus flags the failed operation and further processing of the entire request stops.

Este fluxo de trabalho continua até que toda a solicitação tenha sido processada.This workflow continues until the entire request has been processed.

O design usa vários barramentos de mensagens para processar toda a transação comercial.The design uses multiple message buses to process the entire business transaction. O Microsoft Azure Event Grid fornece o serviço de mensagens.Microsoft Azure Event Grid provides the messaging service. O aplicativo é implantado em um cluster Azure Kubernetes Service (AKS) com dois contêineres no mesmo pod.The app is deployed in an Azure Kubernetes Service (AKS) cluster with two containers in the same pod. Um contêiner executa o embaixador que interage com a Event Grid, enquanto o outro executa um serviço de negócios.One container runs the ambassador that interacts with Event Grid while the other runs a business service. A abordagem com dois recipientes no mesmo pod melhora o desempenho e a escalabilidade.The approach with two containers in the same pod improves performance and scalability. O embaixador e o serviço de negócios compartilham a mesma rede permitindo baixa latência e alta remuneração.The ambassador and the business service share the same network allowing for low latency and high throughput.

Para evitar operações de repetição em cascata que possam levar a vários esforços, apenas a Event Grid tenta uma operação em vez do serviço de negócios.To avoid cascading retry operations that might lead to multiple efforts, only Event Grid retries an operation instead of the business service. Ele sinaliza uma solicitação falha enviando uma mensagem para uma fila de letras mortas (DLQ).It flags a failed request by sending a messaging to a dead letter queue (DLQ).

Os serviços de negócios são impotentes para garantir que as operações de reteste não resultem em recursos duplicados.The business services are idempotent to make sure retry operations don’t result in duplicate resources. Por exemplo, o serviço Pacote usa operações upsert para adicionar dados ao armazenamento de dados.For example, the Package service uses upsert operations to add data to the data store.

O exemplo implementa uma solução personalizada para correlacionar chamadas em todos os serviços e saltos da Event Grid.The example implements a custom solution to correlate calls across all services and Event Grid hops.

Aqui está um exemplo de código que mostra o padrão de coreografia entre todos os serviços de negócios.Here’s a code example that shows the choreography pattern between all business services. Ele mostra o fluxo de trabalho das transações do aplicativo Drone Delivery.It shows the workflow of the Drone Delivery app transactions. O código para o manuseio e o registro de exceções foram removidos por brevidade.Code for exception handling and logging have been removed for brevity.

[HttpPost]
[Route("/api/[controller]/operation")]
[ProducesResponseType(typeof(void), 200)]
[ProducesResponseType(typeof(void), 400)]
[ProducesResponseType(typeof(void), 500)]

public async Task<IActionResult> Post([FromBody] EventGridEvent[] events)
{

   if (events == null)
   {
       return BadRequest("No Event for Choreography");
   }

   foreach(var e in events)
   {

        List<EventGridEvent> listEvents = new List<EventGridEvent>();
        e.Topic = eventRepository.GetTopic();
        e.EventTime = DateTime.Now;
        switch (e.EventType)
        {
            case Operations.ChoreographyOperation.ScheduleDelivery:
            {
                var packageGen = await packageServiceCaller.UpsertPackageAsync(delivery.PackageInfo).ConfigureAwait(false);
                if (packageGen is null)
                {
                    //BadRequest allows the event to be reprocessed by Event Grid
                    return BadRequest("Package creation failed.");
                }

                //we set the event type to the next choreography step
                e.EventType = Operations.ChoreographyOperation.CreatePackage;
                listEvents.Add(e);
                await eventRepository.SendEventAsync(listEvents);
                return Ok("Created Package Completed");
            }
            case Operations.ChoreographyOperation.CreatePackage:
            {
                var droneId = await droneSchedulerServiceCaller.GetDroneIdAsync(delivery).ConfigureAwait(false);
                if (droneId is null)
                {
                    //BadRequest allows the event to be reprocessed by Event Grid
                    return BadRequest("could not get a drone id");
                }
                e.Subject = droneId;
                e.EventType = Operations.ChoreographyOperation.GetDrone;
                listEvents.Add(e);
                await eventRepository.SendEventAsync(listEvents);
                return Ok("Drone Completed");
            }
            case Operations.ChoreographyOperation.GetDrone:
            {
                var deliverySchedule = await deliveryServiceCaller.ScheduleDeliveryAsync(delivery, e.Subject);
                return Ok("Delivery Completed");
            }
            return BadRequest();
    }
}

Considere esses padrões em seu projeto para coreografia.Consider these patterns in your design for choreography.