1.1 Arquitetura do aplicativo

Este curso é destinado a iniciantes, pois você não estará projetando a arquitetura de um aplicativo sério por muito tempo. Mas não se preocupe, a boa arquitetura é a exceção e não a regra. É muito difícil escolher a arquitetura correta do aplicativo antes de criá-lo.

Exemplos de arquiteturas populares para grandes aplicativos de servidor:

  • Arquitetura em camadas (Layered Architecture).
  • Arquitetura em camadas.
  • Arquitetura Orientada a Serviços (SOA).
  • Arquitetura de microsserviços (Microservice Architecture).

Cada um deles tem seus prós e contras. Mas estudá-los não lhe dará nada. Arquitetura é a resposta para a pergunta "como organizar a interação de milhares de objetos dentro do sistema" . E até que você experimente toda a complexidade do problema, não será capaz de entender toda a versatilidade da solução.

Todos os aplicativos usam algum tipo de arquitetura, ou pelo menos fingem usar. Portanto, o conhecimento de abordagens populares para o design de aplicativos permitirá que você entenda melhor e de forma rápida como o aplicativo funciona. E isso significa fazer alterações exatamente onde você precisa.

O que significa “fazer alterações quando necessário”? Existem lugares onde você não precisa fazer alterações? Exatamente.

Para ser específico, digamos que você esteja trabalhando em um projeto de back-end médio . Ele foi escrito por 5 anos por uma equipe de 20 pessoas. O projeto levou 100 anos-homem e contém cerca de 100 mil linhas de código. No total, são duas mil aulas, que são divididas em 10 módulos de diferentes tamanhos.

E adicionar uma dura realidade. A lógica de algumas tarefas está espalhada por vários módulos. Além disso, a lógica de negócios pode estar no frontend (escrita em JavaScript) e/ou escrita como um procedimento armazenado diretamente no banco de dados. Você ainda tem certeza de que pode determinar imediatamente o local exato para fazer as alterações ?

Isto não é um pesadelo que inventei para te assustar. Este é um projeto típico. Acontece ainda pior. Por que isso está acontecendo? Pode haver uma série de razões, mas quase sempre existem:

  • Muitas pessoas trabalham no projeto - cada uma delas o vê de maneira um pouco diferente.
  • Por 5 anos, 10 pessoas mudaram no projeto, os recém-chegados não entenderam muito.
  • Criar software é fazer mudanças constantes que mudam tudo constantemente.
  • Cinco anos atrás, quando decidimos a arquitetura, a ideia do projeto era um pouco diferente.

Mas o principal é que, independentemente da arquitetura do projeto, todos os programadores que trabalham nele aderiram ao mesmo entendimento de como esse projeto funciona. Vamos começar com o conceito mais simples - arquitetura cliente-servidor.

1.2 O conceito de interação cliente-servidor

Agora vamos entender o conceito que está por trás da arquitetura cliente-servidor e permitir que você entenda melhor como se organiza a interação de milhões de programas na Internet.

Como o nome indica, esse conceito envolve duas partes: cliente e servidor . Aqui tudo é como na vida: o cliente é o cliente deste ou daquele serviço, e o servidor é o prestador do serviço. O cliente e o servidor são programas físicos , por exemplo, um cliente típico é um navegador .

Os seguintes exemplos podem ser dados como um servidor:

  • Servidores da Web, como o Tomcat.
  • Servidores de banco de dados, como MySQL.
  • Gateways de pagamento como o Stripe.

O cliente e o servidor geralmente se comunicam via Internet (embora possam trabalhar na mesma rede local e em geral em qualquer outro tipo de rede). A comunicação ocorre através de protocolos padrão, como HTTP, FTP ou protocolos de nível inferior, como TCP ou UDP.

O protocolo geralmente é escolhido de acordo com o tipo de serviço que os servidores fornecem. Por exemplo, se for uma chamada de vídeo, o UDP geralmente é usado.

Lembra como o Tomcat e seus servlets funcionam? O servidor recebe uma mensagem HTTP, descompacta-a, extrai todas as informações necessárias de lá e as passa para o servlet para processamento. Em seguida, o resultado do processamento é empacotado de volta em uma resposta HTTP e enviado ao cliente.

Esta é a típica interação cliente-servidor. O navegador é o cliente da web e o Tomcat é o servidor da web. O Tomcat é até chamado de servidor da web.

Mas se você pensar bem, não é o nome que importa, mas a essência - a distribuição de funções entre os programas. Seu script JS em execução em uma página HTML pode muito bem ser chamado de cliente e seu servlet de servidor . Afinal, eles trabalham em pares dentro da estrutura do conceito cliente-servidor .

1.3 Uma nuance importante

É importante notar também que a interação cliente-servidor é baseada no princípio de que tal interação é iniciada pelo cliente : o servidor apenas responde ao cliente e informa se pode fornecer o serviço ao cliente e, em caso afirmativo, em que condições .

Não importa onde o cliente está fisicamente localizado e onde está o servidor. O software cliente e o software servidor geralmente são instalados em máquinas diferentes, mas também podem ser executados no mesmo computador.

Este conceito foi desenvolvido como um primeiro passo para a simplificação de um sistema complexo. Ela tem esses pontos fortes:

  • Simplificação lógica : o servidor não sabe nada sobre o cliente e como ele usará seus dados no futuro.
  • Pode haver clientes fracos : todas as tarefas com uso intensivo de recursos podem ser transferidas para o servidor.
  • Desenvolvimento independente de código cliente e código servidor.
  • Muitos clientes diferentes, por exemplo, Tomcat e diferentes navegadores.

A versão mais básica da interação entre o cliente e o servidor é mostrada na figura:

servidor cliente

É importante observar dois detalhes aqui. Primeiro, a figura mostra que muitos clientes podem acessar um servidor. Em segundo lugar, eles podem acessá-lo ao mesmo tempo. Esta também é uma parte importante do servidor.

Um cliente geralmente interage com um usuário, muitas vezes até mesmo a autorização não é necessária lá. No entanto, o servidor processa solicitações de milhares de clientes e, ao desenvolver o código para ele, você precisa distinguir entre autorização e autenticação.

Também é importante que o servidor processe milhares de solicitações em paralelo. E isso significa que, ao desenvolver o código de back-end, você precisará pensar constantemente na tarefa de acesso simultâneo aos recursos. Além disso, o código do servidor tem uma probabilidade muito alta de condição de corrida (corrida de threads), deadlock (bloqueio mútuo de threads).

O ciclo de vida de objetos importantes deve ser monitorado:

Você não pode simplesmente iniciar um novo thread no servidor via new Thread().start(). Em vez disso, você precisa ter um ThreadPool que será compartilhado entre todos os threads de serviço.

Além disso, você não pode simplesmente iniciar uma tarefa assíncrona, porque eles também são executados em threads separados. Ao criar tal tarefa, você deve sempre saber qual pool de threads a está executando e o que acontecerá se tal pool transbordar.

Todo o trabalho com arquivos e diretórios deve ser feito por meio de try-with-resources. Se em um aplicativo normal você esqueceu de fechar um stream ou arquivo, isso é um problema? Ele se fechará quando você sair do programa. Mas se você esqueceu de fechar um arquivo no servidor em algum lugar do código e seu servidor está funcionando há meses ... Em breve, milhares desses arquivos não fechados se acumularão e o sistema operacional deixará de abrir novos arquivos para leitura (trabalhar com arquivos é controlado pelo sistema operacional). Teamlead não vai dar tapinhas na sua cabeça...

1.4 Arquitetura cliente-servidor

outro ponto importante. A arquitetura cliente-servidor define apenas os princípios gerais de interação entre computadores , os detalhes da interação são determinados por vários protocolos.

Esse conceito (cliente-servidor) nos diz que precisamos dividir as máquinas da rede em máquinas clientes, que sempre precisam de algo, e máquinas servidores, que fornecem o que precisam. Nesse caso, o cliente sempre inicia a interação, e as regras pelas quais a interação ocorre são descritas pelo protocolo.

Existem dois tipos de arquitetura de interação cliente-servidor: o primeiro é chamado de arquitetura cliente-servidor de duas camadas, o segundo é a arquitetura cliente-servidor de várias camadas (às vezes chamada de arquitetura de três camadas ou arquitetura de três camadas, mas este é um caso especial).

O princípio de operação da arquitetura de duas camadas da interação cliente-servidor é que o processamento de uma solicitação ocorre em um servidor sem referir-se a outros servidores no processo desse processamento.

O modelo de interação cliente-servidor de duas camadas pode ser desenhado como um diagrama simples.

arquitetura de duas camadas de interação cliente-servidor

Aqui você pode ver que o primeiro nível é tudo que diz respeito ao cliente, e o segundo nível é tudo que diz respeito ao servidor.