Brevemente sobre os tipos de arquiteturas de software e qual escolhemos para o provedor de IaaS

Existem muitos tipos de arquiteturas de software com seus prós e contras. Em seguida, falaremos sobre os recursos dos mais populares deles e sobre nossa transição para microsserviços.


/ libreshot / PD

Tipos de arquiteturas de software


Arquitetura em camadas

Essa é uma das arquiteturas mais comuns. Basicamente, muitas estruturas grandes são construídas - Java EE, Drupal, Express. Talvez o exemplo mais famoso dessa arquitetura seja o modelo de rede OSI .

O sistema é dividido em níveis, cada um dos quais interage com apenas dois vizinhos. Portanto, as consultas ao banco de dados, que geralmente está localizado no final da cadeia de interação, passam sequencialmente por cada "camada".

A arquitetura não implica nenhum número obrigatório de níveis - pode haver três, quatro, cinco ou mais. Na maioria das vezes, sistemas de três camadas são usados: com um nível de apresentação (cliente), um nível lógico e um nível de dados.


Inúmeros livros e artigos foram escritos sobre arquitetura multinível. E havia opiniões diferentes sobre suas vantagens e desvantagens.

Prós:

Cada nível dessa arquitetura executa um conjunto estritamente limitado de funções (que não são repetidas de camada para camada) e não sabe como os outros níveis são organizados. Portanto, o "conteúdo" dos níveis pode ser alterado sem o risco de conflitos globais entre as camadas.

Em geral, os aplicativos multiníveis são tão difundidos que geradores de modelos especiais são criados para seu desenvolvimento. Por exemplo, o LASG para Visual Studio oferece vários métodos de geração de código que automatizam tarefas de rotina e ajudam a criar camadas de aplicativos.

Desvantagens:

Na programação, há um ditado que diz que qualquer problema pode ser resolvido adicionando outro nível de abstração. No entanto, essa abordagem pode levar a uma organização ruim do código e confundir os desenvolvedores.

Outro problema surge disso - baixa velocidade. Muitas informações começam a passar inutilmente de uma camada para outra, sem usar a lógica de negócios. Às vezes, esse problema é chamado de antipadrão de sumidouro, um padrão de design quando o número de operações inúteis começa a prevalecer sobre as úteis.

Encontrar bugs em sistemas multicamadas também pode ser difícil . Antes de entrar no banco de dados, as informações passam por todos os níveis (já que o banco de dados é o componente final). Se, por algum motivo, essas informações forem danificadas (ou perdidas), para encontrar um erro, é necessário analisar cada nível separadamente.

Bom ajuste:

  • Para criar novos aplicativos que precisam ser implantados rapidamente. Este é um tipo de "modelo de uso geral".

    Quando começamos a trabalhar nos sistemas internos de nosso provedor de infraestrutura virtual no 1cloud , usamos esse tipo específico de arquitetura. No começo, não tivemos a tarefa de criar um serviço IaaS capaz de processar o tráfego de dezenas ou centenas de milhares de usuários. Decidimos lançar rapidamente o produto no mercado e começar a construir uma base de clientes e resolver os problemas de dimensionamento à medida que estiverem disponíveis (e agora estamos transferindo todos os sistemas para uma arquitetura de microsserviço, que será discutida mais adiante).

    Entre os desenvolvedores, existe uma opinião de que não é necessário, desde os primeiros dias do projeto, prepará-lo para cargas colossais (escreva um software à prova de futuro). Os requisitos reais para o aplicativo ou serviço podem diferir das expectativas e os objetivos de negócios podem mudar . Portanto, um código escrito de olho no futuro distante arrisca se tornar uma dívida técnica.
  • Segundo O'Reilly, a arquitetura em camadas é uma escolha natural para muitos aplicativos corporativos. Como as empresas (especialmente as grandes) geralmente compartilham competências: existe uma equipe responsável pelo front-end, há pessoas responsáveis ​​pelo back-end e assim por diante. Isso implica a divisão natural dos aplicativos em níveis: alguns desenvolvedores trabalham no cliente, outros na lógica.

    Uma relação semelhante entre a estrutura da organização e as abordagens de desenvolvimento de aplicativos também é ditada pela lei de Conway , formulada em 1967. Diz: "Ao desenvolver um sistema, as organizações são forçadas a aderir a um esquema que repete a estrutura das comunicações dentro da empresa".

Arquitetura Orientada a Eventos

Nesse caso, o desenvolvedor prescreve comportamento (reações) para o programa quando ocorrer algum evento. Um evento no sistema é considerado uma mudança significativa em seu estado.

Você pode fazer uma analogia com a compra de um carro na cabine. Quando um carro encontra um novo proprietário, sua condição muda de "à venda" para "vendido". Este evento inicia o processo de preparação da pré-venda - instalação de equipamentos adicionais, verificação das condições técnicas, lavagem, etc.

Um sistema orientado a eventos normalmente contém dois componentes: fontes de eventos (agentes) e seus consumidores (coletores). Geralmente, também existem dois tipos de eventos: um evento inicial e um evento ao qual os consumidores respondem.

Um exemplo da implementação dessa arquitetura é a biblioteca Java Swing. Se a classe precisar de um alerta sobre um evento, o desenvolvedor implementará o chamado ouvinte - ActionListener (ele "captura" o evento correspondente) e o anexa ao objeto que esse evento pode gerar.

O código de implementação a seguir para esse mecanismo é fornecido no Wiki:
public class FooPanel extends JPanel implements ActionListener { public FooPanel() { super(); JButton btn = new JButton("Click Me!"); btn.addActionListener(this); this.add(btn); } @Override public void actionPerformed(ActionEvent ae) { System.out.println("Button has been clicked!"); } } 

Vantagens da arquitetura:

Como os aplicativos consistem em um grande número de módulos assíncronos (que não têm informações sobre a implementação um do outro), eles são fáceis de dimensionar. Esses sistemas são montados como construtores - você não precisa registrar dependências, basta implementar um novo módulo. Além disso, o modelo assíncrono permite alto desempenho do aplicativo.

Desvantagens:

A natureza assíncrona desses aplicativos complica a depuração. Um evento pode acionar várias cadeias de ações ao mesmo tempo. Se houver muitas dessas cadeias, pode ser difícil entender o que exatamente causou a falha. Para resolver o problema, precisamos resolver as condições difíceis para o tratamento de erros. A partir daqui, segue o problema com o registro - os logs são difíceis de estruturar.

Adequado para:

  • Criação de sistemas assíncronos. Isso é óbvio porque a própria arquitetura consiste em um grande número de módulos assíncronos.
  • Pode ser usado para criar uma interface do usuário. Uma página da web atua como um contêiner no qual cada um de seus componentes é isolado e responde a determinadas ações do usuário.
  • Organizar mensagens entre vários sistemas de informação.

Arquitetura de microkernel

Esse tipo de arquitetura consiste em dois componentes: o núcleo do sistema e plug-ins. Os plugins são responsáveis ​​pela lógica comercial, e o kernel gerencia seu carregamento e descarregamento.


Como um exemplo da arquitetura de microkernel, o livro O'Reilly fornece um IDE Eclipse. Este é um editor simples que abre arquivos, permite que sejam editados e executa processos em segundo plano. Mas com a adição de plugins (por exemplo, o compilador Java), sua funcionalidade se expande.

A arquitetura do microkernel já usou o sistema operacional Symbian para dispositivos móveis (o desenvolvimento foi interrompido em 2012). Em seu microkernel, havia um agendador de tarefas, sistemas e drivers de gerenciamento de memória, e o sistema de arquivos e os componentes responsáveis ​​pelas comunicações telefônicas atuavam como plug-ins.

Vantagens da arquitetura:

É fácil portar um aplicativo de um ambiente para outro, pois apenas o microkernel precisa ser modificado. A separação de políticas de alto nível e mecanismos de baixo nível simplifica o suporte ao sistema e garante sua extensibilidade.

Desvantagens:

O desempenho do aplicativo é reduzido se você conectar muitos módulos. No entanto, pode ser problemático encontrar um equilíbrio entre o número de plug-ins e o número de tarefas de micronúcleo (geralmente ele contém apenas o código usado com frequência).

Também é difícil determinar antecipadamente (antes do desenvolvimento do aplicativo) o grau ideal de fragmentação do código dos micronúcleos. E mudar a abordagem mais tarde é quase impossível.

Bom para:

  • Crie aplicativos extensíveis usados ​​por um grande número de pessoas. Por exemplo, o iPhone OS tem raízes de “microkernel” - seus desenvolvedores se inspiraram em Mach (este é um dos primeiros exemplos de um microkernel).
  • Criação de aplicativos com uma clara separação de métodos básicos e regras de alto nível.
  • Desenvolvimento de sistemas com um conjunto de regras que muda dinamicamente e que precisam ser atualizados com frequência.

Microsserviços

Semelhante à arquitetura orientada a eventos e ao microkernel. Mas eles são usados ​​quando tarefas de aplicativos individuais podem ser facilmente divididas em pequenas funções - serviços independentes . Esses serviços podem ser escritos em diferentes linguagens de programação porque se comunicam usando a API REST (por exemplo, usando JSON ou Thrift ).

Em que proporções o código é dividido, o desenvolvedor decide, mas Sam Newman, autor do livro " Criando microsserviços " , recomenda que você aloque tantas linhas de código no microsserviço quanto a equipe puder reproduzir em duas semanas. Segundo ele, isso permitirá evitar o "inchaço" excessivo da arquitetura.

Na maioria das vezes, os microsserviços são lançados nos chamados contêineres. Esses contêineres são acessíveis pela rede a outros microsserviços e aplicativos, e o sistema de orquestração gerencia todos eles: exemplos incluem Kubernetes, Docker Swarm, etc.

Vantagens:

A arquitetura de microsserviço simplifica o dimensionamento de aplicativos. Para implementar um novo recurso, basta escrever um novo serviço. Se a função não for mais necessária, o microsserviço poderá ser desativado. Cada microsserviço é um projeto separado, portanto, é fácil distribuir o trabalho neles entre equipes de desenvolvimento.

Leia mais sobre os mecanismos de dimensionamento de sistemas de microsserviço no livro de Martin L. Abbott, The Art of Scalability.

Desvantagens:

É difícil procurar erros. Diferente dos sistemas monolíticos (quando todas as funções estão no mesmo kernel), pode ser difícil determinar por que a solicitação "caiu". Para obter detalhes, você deve acessar os registros do processo de "culpado" (se houver vários, o problema será agravado).

Isso cria uma sobrecarga adicional para a transmissão de mensagens entre microsserviços. Segundo nossas estimativas, o crescimento dos custos da rede pode chegar a 25%.

Outra desvantagem é a necessidade de aturar o conceito de consistência eventual ( coerência a longo prazo ). Os microsserviços possuem seus próprios data warehouses, que são acessados ​​por outros microsserviços. As informações sobre alterações nesses dados não são distribuídas instantaneamente pelo sistema. Portanto, surgem situações em que alguns microsserviços (embora por um período extremamente curto) tenham dados desatualizados.

Onde usar:

  • Em grandes projetos com alta carga. Por exemplo, microsserviços são usados ​​por plataformas de streaming. Os sistemas de entrega de conteúdo e outros serviços de suporte podem ser escalados independentemente um do outro, adaptando-se às mudanças de carga.
  • Em sistemas que usam recursos "mistos". Se uma parte do aplicativo precisa de mais tempo do processador e a segunda - memória, faz sentido dividi-las em microsserviços. Em seguida, eles podem ser hospedados em máquinas diferentes - com uma CPU poderosa ou uma grande quantidade de memória, respectivamente.
  • Quando a segurança é necessária . Como os microsserviços são isolados e se comunicam pela API, pode-se garantir que apenas as informações necessárias para um serviço específico serão transmitidas. Isso é importante ao trabalhar com senhas ou dados do cartão de pagamento.

Por que estamos mudando para microsserviços no 1cloud


Como já dissemos, a base dos serviços que fornecemos ( nuvem privada , servidores virtuais , armazenamento em nuvem de objetos etc.) se baseia em uma arquitetura de vários níveis. Ela mostrou-se do lado bom, mas agora sua capacidade de escalar começou a se esgotar.

Estamos nos tornando cada vez mais parceiros que fornecem suas soluções com base em nossa plataforma de franquia. Existem sites e serviços remotos que se tornam difíceis de gerenciar a partir de um único ponto (em particular, nosso equipamento está localizado em vários data centers na Rússia, Cazaquistão e Bielorrússia ).

Para facilitar o dimensionamento das funções existentes e a introdução de novos recursos, transferimos toda a nossa infraestrutura para microsserviços no 1cloud .



Queremos separá-los em módulos separados e, em vez de um banco de dados complexo, obter N simples. Assim, na nova arquitetura, cada recurso terá um banco de dados separado. É muito mais conveniente e eficiente em suporte e desenvolvimento.

Poderemos dividir o trabalho em serviços entre vários desenvolvedores (destacar especializações na empresa) e escalar efetivamente horizontalmente - quando necessário, basta conectar novos microsserviços.

Nossos clientes também receberão uma série de vantagens. Como os microsserviços não estão conectados entre si, quando um serviço específico falhar, apenas ele estará indisponível, todo o resto continuará funcionando normalmente. Além disso, mesmo que ocorra uma queda global em nosso serviço, o painel de controle continuará funcionando.

Os clientes do Cazaquistão e da Bielorrússia (e outros países onde abriremos escritórios de representação) perceberão um aumento significativo na velocidade e capacidade de resposta das interfaces, uma vez que os painéis de controle estarão localizados localmente.

O que já foi feito

Até agora, implementamos apenas o primeiro piloto: "Serviço de Monitoramento". Os demais serviços serão transferidos para uma nova faixa no final de 2018 - início de 2019.

Ao mesmo tempo, a nova arquitetura estabelece as bases tecnológicas para o próximo estágio - migração para contêineres. Agora usamos a infraestrutura do Windows e, para mudar para contêineres, precisamos reescrever todo o código acumulado no .NetCore e transferi-lo para o Linux.

Planejamos iniciar uma nova transição no início de 2019 e finalizá-la no final do próximo ano.

Em palavras simples, sobre o que vale a pena lembrar sobre arquitetura
  • Arquitetura multinível - o aplicativo é dividido em níveis, cada um dos quais executa um conjunto estritamente definido de funções. Cada nível pode ser modificado individualmente. Entre as deficiências estão a baixa velocidade do código e a dificuldade de encontrar bugs.

    Adequado para o desenvolvimento de aplicativos que precisam ser rapidamente lançados no mercado. Geralmente usado para criar serviços corporativos.
  • Arquitetura orientada a eventos - aqui o desenvolvedor prescreve a reação do sistema a qualquer evento. Por exemplo, se os dados forem recebidos, grave-os em um arquivo. Os aplicativos baseados em uma arquitetura orientada a eventos são fáceis de escalar, pois todos os manipuladores de eventos não sabem nada sobre a implementação um do outro. No entanto, a depuração desses sistemas é difícil - uma única ação pode causar várias cadeias de ações ao mesmo tempo (é difícil entender qual causou a falha).

    Usado para criar sistemas assíncronos, organização de interfaces gráficas e sistemas de mensagens.
  • Arquitetura de microkernel - consiste em dois componentes principais: plugins e o kernel. Os plug-ins são responsáveis ​​pela lógica de negócios e o kernel é responsável por carregá-los e descarregá-los. Essa separação de tarefas simplifica o suporte ao sistema. No entanto, isso pode afetar o desempenho - depende diretamente do número de módulos conectados e ativos.

    É adequado para o desenvolvimento de aplicativos extensíveis usados ​​por um grande número de pessoas e sistemas com um conjunto de regras que geralmente precisam ser atualizadas (os plugins garantem facilidade de atualização).
  • Arquitetura de microsserviço - os aplicativos são divididos em funções - microsserviços. Cada microsserviço é um componente independente com sua própria lógica de negócios. Esses componentes se comunicam usando a API. Tais aplicativos são fáceis de desenvolver (é possível distribuir o trabalho entre equipes de desenvolvimento), mas é difícil depurar.

    Utilizado em grandes projetos com alta carga, que exigem maior segurança.



O que mais estamos escrevendo no 1cloud Blog:

Source: https://habr.com/ru/post/pt424911/


All Articles