Princípios para desenvolver aplicativos modernos do NGINX. Parte 1

Olá amigos. Em antecipação ao lançamento do curso Desenvolvedor back-end PHP, tradicionalmente compartilham com você a tradução de material útil.

O software resolve cada vez mais tarefas cotidianas, tornando-se cada vez mais complexo. Como Marc Andressen disse uma vez, ele consome o mundo.

Princípios para desenvolver aplicativos modernos do NGINX. Parte 1

Como resultado, a forma como os aplicativos são desenvolvidos e entregues mudou drasticamente nos últimos anos. Estas foram mudanças de escala tectônica que resultaram em um conjunto de princípios. Esses princípios provaram ser úteis na formação de equipes, no design, no desenvolvimento e na entrega de seu aplicativo aos usuários finais.

Os princípios podem ser resumidos da seguinte forma: o aplicativo deve ser pequeno, baseado na web e ter uma arquitetura centrada no desenvolvedor. Com esses três princípios em mente, você pode criar um aplicativo robusto de ponta a ponta que pode ser entregue com rapidez e segurança ao usuário final e é facilmente escalável e extensível.

Princípios para desenvolver aplicativos modernos do NGINX. Parte 1

Cada um dos princípios propostos possui vários aspectos que discutiremos para mostrar como cada princípio contribui para o objetivo final, que é a entrega rápida de aplicativos confiáveis, fáceis de manter e usar. Veremos os princípios em relação aos seus opostos para esclarecer o que significa, digamos: "Certifique-se de usar princípio da pequenez".

Esperamos que este artigo o encoraje a usar os princípios propostos para construir aplicativos modernos, que fornecerão uma abordagem unificada para projetar no contexto de uma pilha de tecnologia em constante crescimento.

Ao aplicar esses princípios, você estará aproveitando as últimas tendências em desenvolvimento de software, incluindo o DevOps para o desenvolvimento e entrega de aplicativos, o uso de contêineres (por exemplo, Estivador) e estruturas de orquestração de contêiner (por exemplo, Kubernetes), o uso de microsserviços (incluindo a arquitetura de microsserviços NGINX и arquitetura de comunicação de rede para aplicações de microsserviços.

O que é um aplicativo moderno?

Aplicações modernas? Pilha moderna? O que exatamente significa "moderno"?

A maioria dos desenvolvedores tem apenas uma ideia geral do que consiste um aplicativo moderno, por isso é necessário definir claramente esse conceito.

Um aplicativo moderno oferece suporte a vários clientes, seja uma interface de usuário da biblioteca React JavaScript, um aplicativo móvel Android ou iOS ou um aplicativo que se conecta a outra API. Uma aplicação moderna implica um número indefinido de clientes para os quais fornece dados ou serviços.

Um aplicativo moderno fornece uma API para acessar os dados e serviços solicitados. A API deve ser imutável e constante e não escrita especificamente para uma solicitação específica de um cliente específico. A API está disponível por HTTP(S) e fornece acesso a todas as funcionalidades disponíveis na GUI ou CLI.

Os dados devem estar disponíveis em um formato interoperável comumente aceito, como JSON. Uma API expõe objetos e serviços de forma limpa e organizada, como RESTful API ou GraphQL fornecem uma interface decente.

Os aplicativos modernos são criados na pilha moderna, e a pilha moderna é a pilha que oferece suporte a esses aplicativos, respectivamente. Essa pilha permite que um desenvolvedor crie facilmente um aplicativo com uma interface HTTP e terminais de API claros. A abordagem escolhida permitirá que seu aplicativo receba e envie facilmente dados no formato JSON. Em outras palavras, a pilha moderna corresponde aos elementos da Aplicação de Doze Fatores para microsserviços.

Versões populares desse tipo de pilha são baseadas em Java, Python, Node , Ruby, PHP и Go. Arquitetura de microsserviços NGINX representa um exemplo de uma pilha moderna implementada em cada uma das linguagens mencionadas.

Observe que não estamos defendendo uma abordagem exclusivamente de microsserviço. Muitos de vocês estão trabalhando com monólitos que precisam evoluir, enquanto outros estão lidando com aplicativos SOA que estão se expandindo e evoluindo para se tornarem aplicativos de microsserviço. Outros ainda estão migrando para aplicativos sem servidor e alguns estão implementando combinações dos itens acima. Os princípios descritos no artigo se aplicam a cada um desses sistemas com apenas algumas pequenas modificações.

Princípios

Agora que temos um entendimento comum do que são um aplicativo moderno e uma pilha moderna, é hora de mergulhar na arquitetura e nos princípios de desenvolvimento que o servirão bem no desenvolvimento, implementação e manutenção de um aplicativo moderno.

Um dos princípios soa como "fazer pequenas aplicações", vamos chamá-lo princípio da pequenez. Existem aplicativos incrivelmente complexos compostos de muitas partes móveis. Por sua vez, construir um aplicativo a partir de componentes pequenos e discretos torna mais fácil projetar, manter e trabalhar com ele como um todo. (Observe que dissemos "simplifica" e não "torna simples").

O segundo princípio é que podemos aumentar a produtividade do desenvolvedor ajudando-os a se concentrar nos recursos que estão desenvolvendo, ao mesmo tempo em que os libera das preocupações de infraestrutura e CI/CD durante a implementação. Então, em poucas palavras, nossa abordagem focado em desenvolvedores.

Por fim, tudo sobre seu aplicativo deve estar conectado à rede. Nos últimos 20 anos, demos grandes passos em direção a um futuro conectado à medida que as redes se tornam mais rápidas e os aplicativos mais complexos. Como vimos, um aplicativo moderno deve ser usado em uma rede por muitos clientes diferentes. Aplicar o pensamento de rede à arquitetura tem benefícios significativos que vão bem com princípio da pequenez e o conceito da abordagem, orientado para o desenvolvedor.

Se você mantiver esses princípios em mente ao projetar e implementar um aplicativo, terá uma vantagem inegável no desenvolvimento e entrega de seu produto.

Vejamos esses três princípios com mais detalhes.

princípio da pequenez

É difícil para o cérebro humano perceber uma grande quantidade de informações ao mesmo tempo. Em psicologia, o termo carga cognitiva refere-se à quantidade total de esforço mental necessário para reter informações na memória. Reduzir a carga cognitiva dos desenvolvedores é uma prioridade porque permite que eles se concentrem na solução do problema, em vez de manter o modelo complexo atual de todo o aplicativo e os recursos que estão sendo desenvolvidos em suas cabeças.

Princípios para desenvolver aplicativos modernos do NGINX. Parte 1

Os aplicativos se decompõem pelos seguintes motivos:

  • Carga cognitiva reduzida nos desenvolvedores;
  • Aceleração e simplificação de testes;
  • Entrega rápida de alterações no aplicativo.


Existem várias maneiras de reduzir a carga cognitiva dos desenvolvedores, e é aqui que entra em jogo o princípio da pequenez.

Então, aqui estão três maneiras de reduzir a carga cognitiva:

  1. Reduza o prazo que eles devem considerar ao desenvolver um novo recurso – quanto menor o prazo, menor a carga cognitiva.
  2. Reduza a quantidade de código em que o trabalho único é realizado - menos código - menos carga.
  3. Simplifique o processo de fazer alterações incrementais em um aplicativo.

Reduzindo o prazo de desenvolvimento

Voltemos aos tempos em que a metodologia waterfall era o padrão para o processo de desenvolvimento, e prazos de seis meses a dois anos para desenvolver ou atualizar um aplicativo eram uma prática comum. Normalmente, os engenheiros primeiro liam os documentos relevantes, como os requisitos do produto (PRD), o documento de referência do sistema (SRD), o projeto da arquitetura e começavam a combinar todas essas coisas em um modelo cognitivo, de acordo com o qual eles codificavam. À medida que os requisitos e, consequentemente, a arquitetura foram mudando, um grande esforço teve que ser feito para informar toda a equipe sobre as atualizações do modelo cognitivo. Tal abordagem, na pior das hipóteses, poderia simplesmente paralisar o trabalho.

A maior mudança no processo de desenvolvimento de aplicativos foi a introdução da metodologia ágil. Uma das principais características da metodologia agile é um desenvolvimento iterativo. Por sua vez, isso leva a uma redução na carga cognitiva dos engenheiros. Em vez de exigir que a equipe de desenvolvimento implemente o aplicativo em um longo ciclo, agile A abordagem permite que você se concentre em pequenas quantidades de código que podem ser rapidamente testadas e implantadas, ao mesmo tempo em que recebe feedback. A carga cognitiva do aplicativo mudou de um período de seis meses para dois anos, com uma grande quantidade de especificações para um acréscimo de duas semanas ou alteração de recurso visando uma compreensão mais confusa de um aplicativo grande.

Mudar o foco de um aplicativo massivo para pequenos recursos específicos que podem ser concluídos em um sprint de duas semanas, com não mais do que um recurso antes do próximo sprint em mente, é uma mudança significativa. Isso nos permitiu aumentar a produtividade do desenvolvimento enquanto reduzíamos a carga cognitiva, que flutuava constantemente.

na metodologia agile espera-se que o aplicativo final seja uma versão ligeiramente modificada do conceito original, portanto, o ponto final do desenvolvimento é necessariamente ambíguo. Somente os resultados de cada sprint específico podem ser claros e precisos.

Bases de código pequenas

A próxima etapa na redução da carga cognitiva é reduzir a base de código. Como regra, os aplicativos modernos são enormes - um aplicativo corporativo robusto pode consistir em milhares de arquivos e centenas de milhares de linhas de código. Dependendo de como os arquivos são organizados, links e dependências entre código e arquivos podem ser óbvios ou vice-versa. Mesmo a própria execução do código de depuração pode ser problemática, dependendo das bibliotecas usadas e quão bem as ferramentas de depuração distinguem entre bibliotecas/pacotes/módulos e código personalizado.

Construir um modelo mental de trabalho do código de um aplicativo pode levar uma quantidade impressionante de tempo e, mais uma vez, colocar uma grande carga cognitiva no desenvolvedor. Isso é especialmente verdadeiro para bases de código monolíticas, onde há uma grande quantidade de código, cuja interação entre os componentes funcionais não é claramente definida e a separação de objetos de atenção geralmente é confusa porque os limites funcionais não são respeitados.

Uma das maneiras eficazes de reduzir a carga cognitiva dos engenheiros é migrar para uma arquitetura de microsserviços. Em uma abordagem de microsserviço, cada serviço se concentra em um conjunto de recursos; enquanto o significado do serviço é geralmente definido e compreensível. Os limites de um serviço também são claros - lembre-se de que a comunicação com um serviço é feita por meio de uma API, portanto, os dados gerados por um serviço podem ser facilmente passados ​​para outro.

A interação com outros serviços geralmente é limitada a alguns serviços de usuário e alguns serviços de provedor que usam chamadas de API simples e limpas, como o uso de REST. Isso significa que a carga cognitiva do engenheiro é seriamente reduzida. O maior desafio continua sendo entender o modelo de interação do serviço e como coisas como transações acontecem em vários serviços. Como resultado, o uso de microsserviços reduz a carga cognitiva reduzindo a quantidade de código, definindo limites de serviço claros e fornecendo uma compreensão do relacionamento entre usuários e provedores.

Pequenas mudanças incrementais

O último elemento do princípio pequenez é o gerenciamento de mudanças. É uma tentação particular para os desenvolvedores olhar para a base do código (até mesmo, talvez, seu próprio código mais antigo) e dizer: "Isso é uma porcaria, precisamos reescrever tudo." Às vezes, esta é a decisão certa e às vezes não. Isso coloca o ônus da mudança de modelo global na equipe de desenvolvimento, o que, por sua vez, leva a uma carga cognitiva massiva. É melhor que os engenheiros se concentrem nas mudanças que podem fazer durante o sprint, para que possam implantar a funcionalidade necessária em tempo hábil, embora gradualmente. O produto final deve se assemelhar ao pré-planejado, mas com algumas modificações e testes para atender às necessidades do cliente.

Ao reescrever grandes porções de código, às vezes não é possível entregar a mudança rapidamente porque outras dependências do sistema entram em jogo. Para controlar o fluxo de alterações, você pode usar a ocultação de recursos. Em princípio, isso significa que a funcionalidade está em produção, mas não está disponível usando as configurações da variável de ambiente (env-var) ou algum outro mecanismo de configuração. Se o código passou por todos os processos de controle de qualidade, pode acabar em produção em estado latente. No entanto, essa estratégia só funciona se o recurso for eventualmente habilitado. Caso contrário, apenas sobrecarregará o código e adicionará uma carga cognitiva com a qual o desenvolvedor terá que lidar para ser produtivo. O gerenciamento de alterações e as próprias alterações incrementais ajudam a manter a carga cognitiva dos desenvolvedores em um nível acessível.

Os engenheiros precisam superar muitas dificuldades, mesmo com a simples introdução de funcionalidades adicionais. Por parte da administração, seria prudente reduzir a carga desnecessária da equipe para que ela pudesse se concentrar nos principais elementos funcionais. Há três coisas que você pode fazer para ajudar sua equipe de desenvolvimento:

  1. Usar metodologia agilepara limitar o período de tempo em que a equipe deve se concentrar nos principais recursos.
  2. Implemente seu aplicativo como vários microsserviços. Isso limitará o número de recursos que podem ser implementados e reforçará os limites que mantêm a carga cognitiva em funcionamento.
  3. Prefira alterações incrementais em vez de grandes e difíceis de manejar, altere pequenos pedaços de código. Use a ocultação de recursos para implementar alterações, mesmo que não sejam visíveis imediatamente após serem adicionadas.

Se você aplicar o princípio da pequenez em seu trabalho, sua equipe ficará muito mais feliz, mais focada na implementação dos recursos necessários e mais propensa a implementar mudanças qualitativas mais rapidamente. Mas isto não significa que o trabalho não possa tornar-se mais complicado, por vezes, pelo contrário, a introdução de novas funcionalidades obriga à modificação de vários serviços, podendo este processo ser mais difícil do que semelhante numa arquitetura monolítica. De qualquer forma, os benefícios de adotar a abordagem da pequenez valem a pena.

O final da primeira parte.

Em breve publicaremos a segunda parte da tradução, e agora esperamos seus comentários e convidamos você a Dia Aberto, que terá lugar hoje às 20.00hXNUMX.

Fonte: habr.com

Adicionar um comentário