Olá colegas.
Hoje, uma tradução do artigo de Tugberk Ugurlu, que assumiu um volume relativamente pequeno para definir os princípios de design de sistemas de software modernos, é proposta ao seu tribunal. Aqui está o que o autor diz sobre si mesmo na linha de fundo:
Como é absolutamente impossível cobrir um tópico tão colossal no artigo de arquitetura como padrões arquitetônicos + padrões de design a partir de 2019, recomendamos não apenas o texto do Sr. Uruglu, mas também os inúmeros links que ele gentilmente colocou nele. Se você gostar, publicaremos um texto mais especializado sobre o design de sistemas distribuídos.
Isaac Smith Shot de UnsplashSe você nunca teve que enfrentar desafios como projetar um sistema de software do zero, então, quando você inicia esse trabalho, às vezes nem fica claro por onde começar. Acredito que primeiro você precise delinear os limites para poder imaginar com mais ou menos confiança o que vai projetar e, em seguida, arregaçar as mangas e trabalhar sem ultrapassar esses limites. Como ponto de partida, você pode pegar algum produto ou serviço (idealmente - um que você realmente gosta) e entender sua implementação. Você pode se surpreender com a aparência simples deste produto e com a enorme complexidade que está oculta. Lembre-se:
simples é geralmente complexo , e isso é normal.
Acho que o melhor conselho que posso dar para quem começa a projetar o sistema é o seguinte: não faça suposições! Desde o início, é necessário concretizar os fatos conhecidos sobre esse sistema e as expectativas associadas a ele. Aqui estão algumas boas perguntas que podem ajudar você a começar a projetar:
- Qual é o problema que estamos tentando resolver?
- Qual é o número máximo de usuários que irão interagir com nosso sistema?
- Que padrões de escrita e leitura de dados serão usados conosco?
- Quais são as falhas esperadas, como vamos lidar com elas?
- Quais são as expectativas para consistência e disponibilidade do sistema?
- Você precisa levar em consideração algum requisito relacionado à verificação e regulamentação externas?
- Que tipos de dados confidenciais vamos armazenar?
Essas são apenas algumas perguntas que foram úteis tanto para mim quanto para as equipes nas quais tive a chance de participar ao longo dos anos de atividade profissional. Se você souber as respostas para essas perguntas (e quaisquer outras que sejam relevantes no contexto em que você deve trabalhar), poderá se aprofundar gradualmente nos detalhes técnicos da tarefa.
Defina o nível inicialO que quero dizer aqui com "linha de base"? Atualmente, a maioria dos problemas na indústria de software pode ser "resolvida" usando métodos e tecnologias existentes. Assim, ao ser guiado nesse cenário, você obtém um certo avanço, diante de tarefas que alguém tinha que resolver antes de você. Não esqueça que os programas foram criados para resolver os problemas de negócios e usuários, por isso nos esforçamos para resolver o problema da maneira mais direta e simples (do ponto de vista do usuário). Por que isso é necessário lembrar? Talvez em seu sistema de coordenadas você goste de procurar soluções exclusivas para todas as tarefas, pois pensa: "que tipo de programador eu sou se eu seguir padrões em todos os lugares?" De fato, a
arte aqui é tomar decisões sobre onde e o que fazer . Naturalmente, cada um de nós de tempos em tempos precisa enfrentar problemas únicos, cada um dos quais é um verdadeiro desafio. No entanto, se nosso nível inicial for claramente delineado, saberemos em que gastar energia: procurando soluções prontas para o problema que nos é apresentado, ou seu estudo adicional e compreensão mais profunda.
Acho que consegui convencê-lo de que, se um especialista entender com confiança qual é o componente arquitetural de alguns sistemas de software maravilhosos, esse conhecimento será indispensável para dominar a arte de um arquiteto e desenvolver uma base sólida nessa área.
OK, então por onde você começa?
Donna Martin possui um repositório no GitHub chamado
system-design-primer , com base no qual você pode aprender a projetar sistemas em grande escala, além de preparar-se para entrevistas sobre este tópico. O repositório possui uma seção com exemplos de
arquiteturas reais , onde, em particular, é examinado como
algumas empresas conhecidas , como Twitter, Uber etc., abordam o design de seus sistemas.
No entanto, antes de prosseguir para este material, vamos examinar mais de perto os desafios arquitetônicos mais importantes com os quais temos de lidar na prática. Isso é importante, porque você deve especificar MUITOS aspectos do problema intratável e multifacetado e, em seguida, resolvê-lo dentro da estrutura da regulamentação em vigor neste sistema.
Jackson Gabbard , um ex-funcionário do Facebook, gravou um
vídeo de 50 minutos sobre entrevistas de design de sistemas , onde compartilhou sua própria experiência na análise de centenas de candidatos a emprego. Apesar do vídeo se referir expressamente ao design de grandes sistemas e aos critérios de sucesso que são importantes ao procurar um candidato para essa posição, ele servirá como um recurso exaustivo sobre o que é mais importante ao projetar sistemas. Eu também ofereço um
resumo deste vídeo.
Obter conhecimento sobre armazenamento e recuperação de dadosComo regra, sua decisão sobre como você armazenará e exibirá seus dados por um longo tempo afeta criticamente o desempenho do sistema. Portanto, você deve primeiro entender as características esperadas de gravação e leitura de dados em seu sistema. Então você precisa poder avaliar esses indicadores e fazer uma escolha com base nas estimativas feitas. No entanto, você só pode lidar efetivamente com este trabalho se entender os padrões existentes de armazenamento de dados. Em princípio, isso implica conhecimento confiável relacionado à
seleção do banco de dados .
Os bancos de dados podem ser considerados estruturas de dados caracterizadas por excepcional escalabilidade e durabilidade. Portanto, o conhecimento das estruturas de dados deve ser muito útil para você escolher um ou outro banco de dados. Por exemplo,
Redis é um servidor de estrutura de dados que suporta vários tipos de valores. Ele permite que você trabalhe com estruturas de dados como listas e conjuntos, leia dados usando algoritmos conhecidos, por exemplo,
LRU , organizando esse trabalho em um estilo durável e altamente acessível.
Instantâneo de Samuel Zeller de UnsplashQuando você entender bem os vários padrões de armazenamento de dados, continue estudando a consistência e a disponibilidade dos dados. Antes de tudo, você precisará aprender o
teorema da
CAP, pelo menos em termos gerais, e depois aperfeiçoar esse conhecimento examinando com mais detalhes os padrões estabelecidos de
consistência e
acessibilidade . Assim, você desenvolverá seus horizontes nessa área e entenderá que a leitura e gravação de dados são na verdade dois problemas muito diferentes, e cada um deles tem seus próprios desafios especiais. Armado com vários padrões para garantir consistência e acessibilidade, você pode aumentar significativamente o desempenho do sistema, garantindo um fluxo ininterrupto de dados para seus aplicativos.
Por fim, concluindo a discussão sobre problemas de armazenamento de dados, deve-se mencionar também o cache. Ele deve ser executado no cliente e no servidor? Quais dados estarão em seu cache? E porque Como você organiza a invalidação de cache? Será feito regularmente, em intervalos regulares? Se sim, com que frequência? Eu recomendo iniciar o estudo desses tópicos com a
próxima seção do iniciador acima mencionado sobre o design do sistema.
Padrões de comunicaçãoSistemas consistem em vários componentes; pode haver diferentes processos em execução no mesmo nó físico ou diferentes máquinas operando em diferentes partes da sua rede. Alguns desses recursos em sua rede podem ser privados, mas outros devem ser públicos e abertos aos consumidores que os acessam de fora.
É necessário garantir a comunicação desses recursos entre si, bem como a troca de informações entre todo o sistema e o mundo exterior. No contexto do design do sistema, aqui, novamente, somos confrontados com um conjunto de novos desafios únicos. Nós descobrimos como
os fluxos de tarefas assíncronos podem ser úteis e quais os
vários padrões de comunicação disponíveis .
Instantâneo de Tony Stoddard de UnsplashAo organizar a comunicação com o mundo exterior, a
segurança é sempre muito importante, que também deve ser abordada com seriedade e participação ativa.
Distribuição de ConexãoNão tenho certeza de que colocar esse tópico em uma seção independente pareça justificado para todos. No entanto, vou expor esse conceito aqui e acredito que o material nesta seção é descrito com mais precisão pelo termo "distribuição de conexão".
Os sistemas são formados pela conexão correta de muitos componentes, e a comunicação entre eles geralmente é organizada com base em protocolos estabelecidos, por exemplo, TCP e UDP. No entanto, esses protocolos, como tais, geralmente não são suficientes para satisfazer todas as necessidades dos sistemas modernos, que geralmente são operados sob alta carga e também dependem muito das necessidades dos usuários. Muitas vezes, é necessário encontrar maneiras de distribuir compostos para lidar com cargas tão elevadas do sistema.
Essa distribuição é baseada no conhecido
sistema de nomes de domínio (DNS). Esse sistema permite converter um nome de domínio, por exemplo, round robin ponderado e métodos com base em atrasos, que ajudam a distribuir a carga.
O balanceamento de carga é de fundamental importância e quase todos os grandes sistemas da Internet com os quais temos de lidar hoje estão localizados atrás de um ou mais balanceadores de carga. Os balanceadores de carga ajudam a distribuir solicitações de clientes entre as várias instâncias disponíveis. Os balanceadores de carga podem ser hardware ou software; no entanto, na prática, você geralmente precisa lidar com software, por exemplo,
HAProxy e
ELB .
Os proxies reversos são conceitualmente muito semelhantes aos balanceadores de carga, embora haja várias
diferenças distintas entre o primeiro e o segundo. Essas diferenças devem ser levadas em consideração ao projetar o sistema de acordo com suas necessidades.
Você também deve estar ciente das
redes de entrega de
conteúdo (CDNs). CDN é uma rede global distribuída de servidores proxy que fornece informações daqueles nós que estão geograficamente localizados mais perto de um usuário específico. As CDNs são preferenciais se você estiver trabalhando com arquivos estáticos gravados em JavaScript, CSS e HTML. Além disso, hoje em dia, esses serviços em nuvem são populares e fornecem gerenciadores de tráfego, por exemplo, o
Azure Traffic Manager , que fornece distribuição global e atrasos reduzidos ao trabalhar com conteúdo dinâmico. No entanto, esses serviços geralmente são úteis nos casos em que você precisa trabalhar com serviços da Web sem salvar o estado.
Vamos falar sobre lógica de negócios. Estruturando lógica de negócios, fluxos de tarefas e componentesEntão, conseguimos discutir vários aspectos da infraestrutura do sistema. Provavelmente, o usuário nem pensa em todos esses elementos do seu sistema e, francamente, não está nem um pouco preocupado com eles. O usuário está interessado em como interagir com seu sistema, o que pode ser alcançado com isso e como o sistema executa comandos do usuário, o que e como fazer com os dados do usuário.
Como o nome deste artigo indica, eu falaria sobre arquitetura de software e design de sistemas. Dessa forma, não planejei cobrir padrões de design de software que descrevem como os componentes de software são criados. No entanto, quanto mais penso sobre isso, mais me parece que a fronteira entre os padrões de design de software e os padrões de arquitetura fica muito embaçada, e esses dois conceitos estão intimamente relacionados. Veja, por exemplo, a fonte de eventos. Se você adotar esse padrão de arquitetura, ele afetará quase todos os aspectos do seu sistema: armazenamento de dados a longo prazo, o nível de consistência adotado em seu sistema, os contornos dos componentes nele, etc., etc. Por isso, decidi mencionar alguns padrões de arquitetura diretamente relacionados à lógica de negócios. Mesmo que neste artigo você tenha que se limitar a uma lista simples, recomendo que você se familiarize com ela e pense em idéias relacionadas a esses padrões. Aqui está você:
Abordagens colaborativasÉ extremamente improvável que você termine no projeto como o participante que é o único responsável pelo processo de design do sistema. Pelo contrário, muito provavelmente, você terá que interagir com colegas que trabalham tanto na sua tarefa como fora dela. Nesse caso, pode ser necessário avaliar as soluções tecnológicas selecionadas junto com os colegas, isolar as necessidades de negócios e entender como melhor paralelizar as tarefas.
Instantâneo Kaleidico de UnsplashAntes de tudo, será necessário desenvolver uma idéia precisa e universalmente reconhecida de qual é o objetivo comercial que você está tentando alcançar e com quais elementos móveis você terá que lidar. As técnicas de modelagem de grupo, em particular a tempestade de eventos, podem acelerar significativamente esse processo e aumentar suas chances de sucesso. Você pode fazer esse trabalho antes ou depois de descrever os
limites dos seus serviços e aprofundá-lo à medida que o produto amadurece. Com base no nível de consistência que será alcançado aqui, você também pode formular um
idioma único para o contexto limitado em que trabalha. Quando você precisar falar sobre a arquitetura do seu sistema, poderá usar
o modelo C4 proposto por
Simon Brown para isso , especialmente quando precisar entender o quanto precisará aprofundar nos detalhes do problema visualizando as coisas que deseja relatar.
Provavelmente, há outra tecnologia madura neste tópico, não menos útil que o design orientado a assuntos. No entanto, de uma forma ou de outra, voltamos a entender a área de assunto, para que o conhecimento e a experiência no campo do
design orientado à matéria sejam úteis para você.