Blocos de construção de aplicativos distribuídos. Aproximação zero

Blocos de construção de aplicativos distribuídos. Aproximação zero

O mundo não fica parado. O progresso cria novos desafios tecnológicos. De acordo com a evolução dos requisitos, a arquitectura dos sistemas de informação deve evoluir. Hoje falaremos sobre arquitetura orientada a eventos, simultaneidade, simultaneidade, assincronia e como você pode conviver pacificamente com tudo isso em Erlang.

Introdução

Dependendo do tamanho do sistema projetado e dos requisitos para ele, nós, os desenvolvedores, escolhemos o método de troca de informações no sistema. Na maioria dos casos, para organizar a interação de serviços, uma opção de trabalho pode ser um esquema com uma corretora, por exemplo, baseado em RabbitMQ ou kafka. Mas às vezes o fluxo de eventos, o SLA e o nível de controle sobre o sistema são tais que as mensagens prontas não são adequadas para nós. Claro, você pode complicar um pouco o sistema assumindo a responsabilidade pela camada de transporte e formação de cluster, por exemplo, usando ZeroMQ ou nanomsg. Mas se o sistema tiver rendimento e capacidades suficientes de um cluster Erlang padrão, então a questão da introdução de uma entidade adicional requer um estudo detalhado e justificação económica.

O tópico de aplicativos distribuídos reativos é bastante amplo. Para manter o formato do artigo, o assunto da discussão de hoje serão apenas ambientes homogêneos construídos em Erlang/Elixir. O ecossistema Erlang/OTP permite implementar uma arquitetura reativa com o mínimo de esforço. Mas em qualquer caso, precisaremos de uma camada de mensagens.

Base teórica

O design começa com a definição de objetivos e restrições. O objetivo principal não está na área do desenvolvimento pelo desenvolvimento. Precisamos de obter uma ferramenta segura e escalável com base na qual possamos criar e, mais importante ainda, desenvolver aplicações modernas de vários níveis: começando com aplicações de servidor único que servem um pequeno público, que podem posteriormente evoluir para clusters de até 50 -60 nós, terminando com federações de cluster. Assim, o objetivo principal é maximizar os lucros reduzindo o custo de desenvolvimento e propriedade do sistema final.

Destacamos 4 requisitos principais para o sistema final:

  • Сorientado a eventos.
    O sistema está sempre pronto para passar pelo fluxo de eventos e realizar as ações necessárias;
  • Мescalabilidade.
    Blocos individuais podem ser dimensionados vertical e horizontalmente. Todo o sistema deve ser capaz de crescimento horizontal infinito;
  • Оtolerância ao erro.
    Todos os níveis e todos os serviços devem ser capazes de recuperar automaticamente de falhas;
  • Гtempo de resposta garantido.
    O tempo é valioso e os usuários não devem esperar muito.

Lembra-se do velho conto de fadas sobre “O pequeno motor que podia”? Para que o sistema projetado saia com sucesso da fase de protótipo e seja progressivo, sua fundação deve atender aos requisitos mínimos SMOG.

Mais um ponto se soma ao mensageria como ferramenta de infraestrutura e base de todos os serviços: facilidade de uso para programadores.

Orientado para eventos

Para que um aplicativo cresça de um único servidor para um cluster, sua arquitetura deve suportar acoplamento fraco. O modelo assíncrono atende a esse requisito. Nele, remetente e destinatário se preocupam com a carga de informações da mensagem e não se preocupam com transmissão e roteamento dentro do sistema.

Escalabilidade

Escalabilidade e eficiência do sistema estão próximas uma da outra. Os componentes do aplicativo devem ser capazes de utilizar todos os recursos disponíveis. Quanto mais eficientemente pudermos utilizar a capacidade e quanto mais otimizados forem os nossos métodos de processamento, menos dinheiro gastaremos em equipamentos.

Dentro de uma única máquina, Erlang cria um ambiente altamente competitivo. O equilíbrio entre simultaneidade e paralelismo pode ser definido escolhendo o número de threads do sistema operacional disponíveis para a VM Erlang e o número de agendadores que utilizam esses threads.
Os processos Erlang não compartilham estado e operam em modo sem bloqueio. Isso fornece latência relativamente baixa e maior rendimento do que aplicativos tradicionais baseados em bloqueio. O agendador de Erlang garante uma alocação justa de CPU e IO, e a ausência de bloqueio permite que o aplicativo responda mesmo durante picos de carga ou falhas.

No nível do cluster, o problema do descarte também existe. É importante que todas as máquinas do cluster estejam carregadas uniformemente e que a rede não esteja sobrecarregada. Vamos imaginar uma situação: o tráfego do usuário chega aos balanceadores de entrada (haproxy, nginx, etc.), eles distribuem as solicitações de processamento da maneira mais uniforme possível entre o conjunto de back-ends disponíveis. Dentro da infraestrutura de aplicação, o serviço que implementa a interface necessária é apenas a última etapa e precisará solicitar vários outros serviços para responder à solicitação inicial. As solicitações internas também exigem roteamento e balanceamento.
Para gerenciar efetivamente os fluxos de dados, o sistema de mensagens deve fornecer aos desenvolvedores uma interface para gerenciar o roteamento e o balanceamento de carga. Graças a isso, os desenvolvedores poderão, usando padrões de microsserviços (agregador, proxy, cadeia, filial, etc), resolver tanto problemas padrão quanto aqueles que raramente surgem.

Do ponto de vista empresarial, a escalabilidade é uma das ferramentas de gestão de risco. O principal é satisfazer as solicitações dos clientes utilizando o equipamento de forma otimizada:

  • Quando a potência do equipamento aumenta como resultado do progresso. Não ficará ocioso devido a software imperfeito. Erlang é bem dimensionado verticalmente e sempre será capaz de utilizar todos os núcleos da CPU e memória disponível;
  • Em ambientes cloud podemos gerir a quantidade de equipamentos em função da carga atual ou prevista e garantir SLA.

tolerância ao erro

Consideremos dois axiomas: “Falhas são inaceitáveis” e “Sempre haverá falhas”. Para uma empresa, a falha de software significa perda de dinheiro e, o que é pior, perda de reputação. Equilibrando entre possíveis perdas e o custo de desenvolvimento de software tolerante a falhas, muitas vezes pode ser encontrado um compromisso.

No curto prazo, uma arquitetura que incorpora tolerância a falhas economiza dinheiro na compra de soluções de cluster prontas para uso. Eles são caros e também têm bugs.
No longo prazo, uma arquitetura tolerante a falhas se paga muitas vezes em todos os estágios de desenvolvimento.
As mensagens dentro da base de código permitem trabalhar detalhadamente a interação dos componentes dentro do sistema no estágio de desenvolvimento. Isso simplifica a tarefa de responder e gerenciar falhas, uma vez que todos os componentes críticos lidam com falhas e o sistema resultante sabe como retornar automaticamente ao normal após uma falha por design.

Capacidade de resposta

Independentemente das falhas, a aplicação deve responder às solicitações e cumprir o SLA. A realidade é que as pessoas não querem esperar, por isso as empresas devem adaptar-se em conformidade. Espera-se que cada vez mais aplicativos sejam altamente responsivos.
Aplicativos responsivos operam quase em tempo real. Erlang VM opera em modo suave em tempo real. Para algumas áreas, como negociação de ações, medicina e controle de equipamentos industriais, o modo rígido em tempo real é importante.
Sistemas responsivos melhoram a UX e beneficiam o negócio.

Resultado preliminar

Ao planejar este artigo, gostaria de compartilhar minha experiência na criação de um corretor de mensagens e na construção de sistemas complexos baseados nele. Mas a parte teórica e motivacional acabou por ser bastante extensa.
Na segunda parte do artigo falarei sobre as nuances da implementação de pontos de troca, padrões de mensagens e sua aplicação.
Na terceira parte consideraremos questões gerais de organização de serviços, roteamento e balanceamento. Vamos falar sobre o lado prático da escalabilidade e tolerância a falhas dos sistemas.

O final da primeira parte.

foto @lucabravo.

Fonte: habr.com

Adicionar um comentário