Projetando arquitetura orientada a eventos para vários serviços

5

Criei cerca de uma dúzia de serviços para uma intranet. Agora cheguei ao ponto em que esses serviços são mais acoplados uns aos outros do que me sinto confortável, e tenho tido problemas onde o serviço uma vez pode fazer com que alguns outros serviços sejam degradados.

Eu tenho trabalhado em um projeto de EDA para que eu possa tornar esses serviços dissociados uns dos outros, mas como eu sou o único programador aqui eu preciso de algum feedback.

O design visa solucionar esses cenários:

Cenário 1: O Cliente solicita dados do Serviço A, para atender a essa solicitação O Serviço A precisa de dados do Serviço B, mas o Serviço B falhou e não responde

Cenário 2: O cliente atualiza uma entidade no Serviço B, a referência a essa entidade precisa ser atualizada no Serviço A e C

Eu dividi o design em duas partes, Operações e Eventos

Uma operação é enviada por um serviço ou cliente para alterar uma entidade em um serviço. Isso sempre resulta em um evento sendo disparado. Cada operação contém um ID de usuário, código de operação e alguns timestamps.

Um evento é uma reação a uma operação, ele notifica qualquer pessoa que esteja ouvindo que ocorreu uma alteração. Cada evento contém o id da operação que o iniciou, o id do usuário que o causou e alguns timestamps. Cada evento também tem um hash da entidade completa para que qualquer ouvinte possa comparar com suas versões.

Estou usando o RabbitMQ como um barramento de mensagens e cada serviço tem filas persistentes e duráveis para armazenar eventos ou operações pendentes.

Para dissociar o serviço um do outro, cada serviço armazena em cache as entidades das quais depende e que pertencem a outros serviços.

Quando um serviço requer uma entidade de outro serviço, ele busca e armazena em uma tabela em seu banco de dados. Em seguida, ele escuta as alterações feitas em qualquer entidade em seu cache e as atualiza quando ocorre um evento relacionado a ela.

Quando o armazenamento ou a busca de uma entidade do cache falhar, ela será recuperada do serviço apropriado.

Para a auditoria, eu tenho um serviço que ouve eventos de todos os serviços e os armazena. Pode, então, recriar qualquer entidade em qualquer momento específico.

Eu adoraria comentários de alguém mais experiente do que eu e se há algum problema gritante com o design.

    
por grimurd 16.02.2018 / 17:23
fonte

2 respostas

2

Eu tenho algumas coisas que gostaria de destacar:

  1. Eu me referiria a comandos em vez de operações . Isso se encaixa na linguagem em torno do sistema que você está modelando melhor, eu acho.
  2. Parece que você está usando os eventos como um acionador para recuperar dados de outros serviços. Você também usará os eventos para criar essas entidades? Se for esse o caso, sugiro strongmente que introduza alguma forma de EventStore para cada aplicativo para armazenar os eventos nos quais você está publicando. Você pode então reutilizar esses eventos para recriar suas entidades, se necessário. A maioria das pessoas se refere a isso como Sourcing de Eventos, embora eu prefira usar esse termo para o lado da gravação (o 'tratamento de operação' no seu exemplo) do aplicativo. No entanto, eu criaria suas entidades nesses eventos também. Se você adotasse essa abordagem, poderia até permitir que os outros serviços ouvissem todos esses eventos e criassem a entidade necessária, o que omitiria a necessidade de consultar as entidades.
  3. Você indica que adicionará outro serviço para auditoria. Se você seguir minha sugestão do ponto 2, sua loja de eventos também será automaticamente seu log de auditoria. Obviamente, isso só será válido se você modelar seus eventos corretamente, mas, no entanto, acho que tornar seus eventos cidadãos de primeira classe e armazená-los imediatamente após a publicação omite a necessidade de um serviço de log de auditoria dedicado.
  4. Sem saber em que linguagem de programação você está, sugiro ainda dar uma olhada em alguns frameworks CQRS / EDA / DDD, como o Axon Framework por exemplo. É baseado em Java, mas mesmo se você não estiver em Java, os conceitos que o framework tenta ajudá-lo se parecem com o que você está tentando fazer.

Em suma, acho que remodelar seu aplicativo como algo que é uma sugestão é uma coisa boa. Tornar a sua mensagem de comunicação baseada e a localização dos seus serviços transparente garante que você perca o acoplamento com o qual está preocupado neste momento.

    
por 19.02.2018 / 17:06
fonte
2

Primeiro, se o serviço A precisar de dados do serviço B, então os limites do seu serviço estarão errados. Parece que os critérios usados para dividir seu sistema são por entidade. Ele se correlaciona ao conceito de serviços em camadas, que já era considerado ruim em 2007 .

A abordagem que estou defendendo é baseada no conceito de capacidade de negócios. Você identifica algumas áreas em seu domínio que são realmente muito coesas, que compreendem alguns dados encapsulados usados somente nessa área, processos de negócios implementados, aplicativos e pessoas. Então você se aprofunda nessas áreas e repete essa etapa. Acho conveniente usar uma análise da cadeia de valor para isso. Considere o seu processo de negócios principal. Como você ganha dinheiro, qual é o principal motivo da existência de sua empresa? Dê uma olhada neste processo como uma seqüência de etapas. Se alguma etapa contiver alguns processos de negócios que não estejam conectados a nenhuma outra etapa, provavelmente esses passos podem ser um serviço independente.

Seus serviços técnicos mapeiam para esses serviços de negócios como 1: 1.

uma série de postagens em SOA que contêm alguns exemplos também , confira.

    
por 20.02.2018 / 19:15
fonte