
Enquanto nossa venda continua para os gostos mais exigentes, voltamos sua atenção para outro tema de nossa busca criativa: Event-Driven Architecture (EDA). Abaixo do corte você encontrará lindos fluxogramas e uma história sobre como esse paradigma inovador auxilia no desenvolvimento de aplicações web.
Este artigo examinará alguns dos desafios que impulsionam a inovação no desenvolvimento da web moderno. A seguir, vamos mergulhar na Arquitetura Orientada a Eventos (EDA) para resolver esses problemas redefinindo a arquitetura do servidor.
Os aplicativos da Web evoluíram muito desde os dias em que o conteúdo HTML estático era servido de um servidor. Hoje, os aplicativos da web se tornaram muito mais complexos, eles usam uma variedade de estruturas, centros de dados e tecnologias. Nos últimos dois anos, duas tendências podem ser observadas que determinam o desenvolvimento do mercado de TI:
- Transferência de aplicativos para a nuvem ;
- Implementação de arquitetura de microsserviço .
Essas idéias determinam em grande parte como o software é projetado e construído hoje. Podemos dizer que hoje não estamos mais construindo aplicativos, mas plataformas. Os aplicativos não ocupam mais espaço de computação compartilhado. Em vez disso, eles precisam trocar informações entre si usando protocolos de comunicação leves, como APIs REST ou chamadas de procedimento remoto (RPC). Esse modelo gerou ótimos produtos como Facebook, Netflix, Uber e muito mais.
Este artigo explorará alguns dos desafios que impulsionam a inovação no desenvolvimento da web moderno. A seguir, vamos mergulhar na Arquitetura Orientada a Eventos (EDA), que aborda esses problemas redefinindo a arquitetura do servidor.
Problemas atuais da web moderna
Qualquer tecnologia da web deve enfrentar os desafios que os aplicativos assíncronos multiusuário modernos devem enfrentar, projetados para funcionar sem problemas:
Disponibilidade
Agora não trabalhamos com um aplicativo, mas com muitos - dezenas ou até centenas - de serviços relacionados, e cada um deles deve resolver seus problemas 24 horas por dia, sete dias por semana. Como isso pode ser alcançado? Na maioria das vezes, o serviço é dimensionado horizontalmente para várias instâncias que podem ser distribuídas em vários data centers para garantir alta disponibilidade. Todas as solicitações desse serviço específico são roteadas e distribuídas uniformemente em todas as instâncias. Algumas ferramentas de implantação fornecem recursos de autocorreção; portanto, se uma instância falhar, outra será criada para substituí-la.
Escalabilidade
A escalabilidade é, em muitos aspectos, semelhante à disponibilidade. A essência da acessibilidade é garantir que pelo menos uma instância do serviço esteja ativa e em execução, pronta para atender às solicitações de entrada. A escalabilidade, por sua vez, está principalmente relacionada ao desempenho. Se um aplicativo estiver sobrecarregado, novas instâncias desse aplicativo serão criadas para acomodar o aumento do número de solicitações. Mas dimensionar aplicativos verticalmente não é uma tarefa trivial, especialmente quando se trata de aplicativos com estado .
Uma fonte de verdade
Antes do advento dos microsserviços, essa era uma tarefa bastante simples. Todos os dados estavam localizados em um local, via de regra, era um ou outro banco de dados relacional. No entanto, quando vários serviços compartilham um banco de dados, podem ser criados problemas como dependências entre equipes diferentes em relação a alterações de esquema ou problemas de desempenho. Normalmente, esse problema era resolvido alocando seu próprio banco de dados para cada serviço. A fonte distribuída da verdade é muito boa para ajudar a manter uma arquitetura limpa, mas em tal situação você tem que lidar com transações distribuídas e a complexidade de suportar múltiplos bancos de dados.
Sincronicidade
Em um cenário típico de solicitação-resposta, o cliente espera a resposta do servidor; ele bloqueia todas as ações até receber uma resposta ou até que o atraso especificado expire. Se você pegar esse comportamento e implementá-lo em uma arquitetura de microsserviço usando cadeias de chamadas que percorrem todo o sistema, poderá facilmente se encontrar no chamado "inferno do microsserviço". Tudo começa com a chamada de apenas um serviço, vamos chamá-lo de "serviço A". Mas então o serviço A precisa chamar o serviço B e a diversão começa. O problema com esse comportamento é o seguinte: se o próprio serviço estiver associado a recursos bloqueados (por exemplo, uma thread está travada), os atrasos aumentam exponencialmente. Se permitirmos um atraso de 500 ms por serviço e houver cinco chamadas de serviço na cadeia, o primeiro serviço precisará de um atraso de 2.500 ms (2,5 segundos) e o último - 500 ms.

Os desafios da web moderna
Introdução à arquitetura orientada a eventos
Event-Driven Architecture (EDA) é um paradigma de arquitetura de software que facilita a geração, descoberta, consumo de eventos e a resposta a eles.
Em aplicativos clássicos de três camadas, o núcleo do sistema é o banco de dados. No EDA, o foco muda para os eventos e como eles são filtrados pelo sistema. Essa mudança de foco permite uma mudança completa na abordagem do design do aplicativo e na solução dos problemas mencionados.
Antes de ver exatamente como isso é feito no EDA, vamos ver o que é um "evento". Um evento é uma ação que inicia alguma notificação ou uma mudança no estado do aplicativo. A luz acendeu (notificação), o termostato desligou o sistema de aquecimento (notificação), o usuário mudou de endereço (mudança de estado), um de seus amigos mudou o número de telefone (mudança de estado). Todos são eventos, mas ainda não é um fato que devemos adicioná-los a uma solução baseada em eventos. Presume-se que apenas eventos relevantes para os negócios sejam adicionados à arquitetura. O evento “usuário faz um pedido” é importante do ponto de vista do negócio, mas “usuário come uma pizza ou almoço pedido” não é.
Se você pensar em alguns eventos, então, em alguns, fica imediatamente claro que eles são importantes para os negócios, e sobre alguns - não. Especialmente sobre aqueles que ocorrem em resposta a outros eventos. Uma técnica chamada " assalto de evento " é usada para identificar eventos que passam pelo sistema . Os participantes do desenvolvimento de aplicativos (de programadores a desenvolvedores de lógica de negócios e especialistas no assunto) são convocados e, em conjunto, mapeiam todos os processos de negócios, apresentando-os na forma de eventos específicos. Quando esse mapa está pronto, o resultado do trabalho é formulado na forma de requisitos que devem ser atendidos no desenvolvimento de aplicações.

Um exemplo de um pedido de reserva descrito pelo método de assalto de evento
Tendo identificado os eventos que nos interessam e tendo decidido como identificá-los, vamos ver como este paradigma pode resolver os problemas típicos mencionados acima.
O fluxo de eventos é unidirecional: do produtor ao consumidor. Compare esta situação com uma chamada REST. O produtor do evento não espera, em princípio, uma resposta do consumidor, ao passo que, no caso de uma chamada REST, sempre haverá uma resposta. Nenhuma resposta significa que não há necessidade de bloquear a execução do código até que algo mais aconteça. Nesse caso, os eventos se tornam assíncronos por natureza, o que elimina completamente o risco de ficar preso em atrasos.
Os eventos acontecem como resultado de uma ação, portanto, não existe um sistema de destino; o serviço A não pode disparar eventos no serviço B; mas podemos dizer que o serviço B está interessado nos eventos gerados pelo serviço A. É verdade que pode haver outras "partes interessadas" neste sistema, por exemplo, os serviços C ou D.
Como podemos ter certeza de que um evento iniciado em um determinado sistema atingirá todos Serviços "interessados"? Normalmente, esses sistemas são resolvidos usando intermediários de mensagens. Um corretor é simplesmente um aplicativo que atua como intermediário entre o emissor do evento (o aplicativo que gerou o evento) e o consumidor do evento. Assim, os aplicativos podem ser facilmente separados uns dos outros, cuidando do problema de acessibilidade, que foi discutido acima neste post. Se o aplicativo estiver indisponível no momento, então, voltando online, ele começará a consumir eventos e processá-los, compensando todos os eventos que aconteceram durante o período em que permaneceu indisponível.
E quanto ao data warehouse? Os eventos podem ser armazenados em um banco de dados ou algo mais é necessário em vez de um banco de dados? Certamente, os eventos podem ser armazenados em bancos de dados, mas, neste caso, sua essência de "evento" é perdida. Depois que um evento ocorre, não podemos mais corrigi-lo, portanto, os eventos são inerentemente imutáveis. Os bancos de dados, por sua vez ... são mutáveis, após inserir os dados no banco de dados, eles podem ser alterados.
Melhor armazenar eventos em logs de eventos . Os registros de eventos nada mais são do que centralizadosdata warehouse, onde cada evento é registrado como uma sequência de registros imutáveis, o chamado “log”. Um log pode ser comparado a um log, onde cada novo evento é adicionado ao final da lista. Você sempre pode recriar o estado mais atual reproduzindo todos os eventos de log do início ao presente.
Portanto, cobrimos todos os problemas, exceto escalabilidade. Os serviços orientados a eventos são sempre projetados para serem implantados em várias instâncias. Como o estado como tal é armazenado no log de eventos, o serviço em si não terá estado, o que permite o dimensionamento cirurgicamente preciso de qualquer serviço de interesse.
A única exceção a esse princípio são os serviços projetados para criar visualizações materializadas.... Em essência, uma visão materializada é um estado que descreve um log de eventos em um ponto específico no tempo. Essa abordagem é usada para facilitar a consulta de dados. Voltando à questão do dimensionamento, uma visão materializada é simplesmente uma visão agregada de eventos que se assemelha a uma mesa; mas onde armazenamos essas tabelas? Na maioria das vezes, você vê essas agregações na memória e, ao mesmo tempo, nosso serviço se transforma automaticamente em um stateful. Uma solução rápida e fácil é fornecer um banco de dados local para cada serviço que cria visualizações materializadas. Dessa forma, o estado é armazenado no banco de dados e o serviço é executado sem estado.

Embora a arquitetura orientada a eventos já exista há mais de 15 anos, só recentemente ganhou grande popularidade, e isso não é coincidência. A maioria das empresas está passando por um estágio de " transformação digital " com demandas selvagens. Devido à complexidade desses requisitos, os engenheiros precisam dominar novas abordagens para o design de software, o que implica, em particular, enfraquecer a conectividade dos serviços entre si e reduzir o custo de manutenção dos serviços. EDA é uma solução possível para esses problemas, mas não a única. Além disso, não espere que todos os problemas sejam resolvidos se você apenas mudar para o EDA. Alguns recursos ainda podem exigir APIs REST antigas e robustas ou armazenar informações em um banco de dados. Escolha aquele que funciona melhor para você e projete-o corretamente!