Muitos programadores ouviram dizer que às vezes o código deve ser alocado para separar bibliotecas para reutilização adicional. No entanto, a questão de que tipo de código deve ser destacado como uma entidade separada confunde muitos desenvolvedores. Ao ler artigos / conversas sobre esse tópico, o problema de generalização prematura é geralmente lembrado.
Programadores experientes geralmente têm suas próprias regras, após as quais eles entendem se o código deve ser distinguido como reutilizável. Por exemplo, se esse código (ou muito semelhante) for usado em três locais ou mais. No entanto, todos com quem tive a oportunidade de falar sobre esse assunto concordam que esse código reutilizável deve existir, sua criação é uma bênção e vale a pena gastar seu tempo.
Quero levantar o tópico da reutilização de código no contexto da criação de uma arquitetura orientada a serviços e de microsserviços.
O que é código reutilizável?
Código reutilizável é um código isolado em uma entidade separada, chamada de maneira diferente em diferentes idiomas - biblioteca, pacote, dependência etc. Normalmente, esse código é armazenado em um repositório separado e há documentação para conectar e usar esse código (README.md). Além disso, o código pode ser coberto por testes, pode haver instruções para fazer alterações (CONTRIBUTING.md) e o IC pode ser configurado. Vários emblemas anexados à descrição apenas melhoram a representação visual da maturidade de uma determinada entidade, e o número de estrelas atribuídas indicará a popularidade desta solução. Você não precisa ir longe para obter exemplos - basta abrir a página do github de qualquer uma das estruturas populares em seu idioma favorito, por exemplo,
vue.js. Em geral, os métodos de design de alta qualidade das bibliotecas são uma carroça e um carrinho pequeno.
Serviços e microsserviços
Neste artigo, um serviço é uma entidade completa que executa um conjunto específico de tarefas específicas em seu domínio de responsabilidade e fornece uma interface para interação. O serviço ou microsserviço neste artigo, do ponto de vista da arquitetura, pode ser conceitos idênticos, a questão é apenas em escala. Um serviço pode consistir em um conjunto de microsserviços que implementam seu setor de lógica de negócios ou ser um microsserviço orgulhoso.
A arquitetura orientada a serviços pressupõe que cada serviço esteja minimamente conectado com outros. No entanto, a interação interserviços não é excluída, mas supõe-se que deve ser minimizada. Para receber solicitações, um serviço geralmente implementa alguma API padronizada. Pode ser qualquer coisa - REST, SOAP, JSONRPC ou o GraphQL novo.
Convencionalmente, os serviços podem ser divididos em infraestrutura e mercearia. Serviços de produto são aqueles que implementam a lógica de um produto cliente. Por exemplo, eles trabalham com aplicativos para sua conexão ou organizam o suporte para este produto durante todo o ciclo de vida de um cliente. Os serviços de infraestrutura são mais sobre a funcionalidade básica de uma empresa (ou projeto), por exemplo, um serviço que contém informações do cliente ou um serviço que armazena informações sobre determinados pedidos. Além disso, os serviços de infraestrutura incluem serviços que implementam funcionalidade auxiliar, por exemplo, um serviço de informações do cliente (enviando mensagens push ou SMS) ou um serviço para interagir com a dadata.
Um pouco de fantasia
Suponha que exista uma loja on-line hipotética construída em uma arquitetura orientada a serviços. Os desenvolvedores deste milagre da engenharia conseguiram concordar entre si e chegaram à conclusão de que todos os seus serviços funcionarão como APIs, por exemplo, usando o protocolo jsonrpc. No entanto, como a loja on-line é grande, não fica parada e está se desenvolvendo ativamente, existem vários grupos de desenvolvimento, que sejam mais de dois - dois de design, um acompanhado pelo que já foi escrito. Além disso, para aprimorar o efeito, todas as equipes escrevem na mesma pilha.
A arquitetura de uma hipotética loja online:
Somente o serviço de API instalado na Internet fornece acesso a todos os sistemas front-end - a interface da web da loja online, bem como aplicativos móveis.
O serviço de informações do cliente armazena informações sobre os clientes, sabe como iniciá-los, autorizar, emitir as informações necessárias sobre eles.
O serviço de informações do produto armazena informações sobre produtos, seus saldos e disponibilidade para pedidos, também fornece métodos para obter convenientemente as informações necessárias.
O serviço de pedidos opera com pedidos. Aqui está a lógica da formação do pedido, sua confirmação, a escolha do tipo de pagamento e o endereço de entrega, etc.
O serviço de informações do cliente pode enviar mensagens PUSH / SMS / e-mail. O tipo de comunicação, por exemplo, depende das configurações de um cliente específico, e o cliente também pode definir o tempo desejado para o recebimento de notificações.
Esses serviços são condicionalmente infraestruturais, porque sem eles uma loja on-line não pode funcionar como tal.
Os serviços de promoções, ofertas e distribuição do resumo devem ser desenvolvidos em um futuro próximo pelas equipes do projeto. Esses serviços são condicionalmente mantimentos.
Obviamente, em qualquer caso, qualquer novo serviço de produto não poderá existir sem a interação com os serviços de infraestrutura - provavelmente precisará receber informações sobre os clientes ou precisar enviar notificações.
No exemplo descrito acima, os detalhes da implementação de cada serviço são intencionalmente ocultos. Portanto, por exemplo, um serviço de informações do cliente provavelmente possui um mecanismo de execução de código atrasado, como uma fila de execução, e um serviço de informações do produto pode ter seu próprio painel de administração para gerenciamento conveniente de mercadorias, e a API para sistemas front-end provavelmente possui várias réplicas. Além disso, a arquitetura descrita pode não ser ideal; é simplesmente retirada da cabeça.
No contexto da arquitetura proposta, fica imediatamente claro que as bibliotecas prontas são essenciais para o desenvolvimento rápido do produto. Portanto, é importante ter uma implementação pronta do servidor jsonrpc, bem como o cliente, pois esse é o principal protocolo para organizar a interação entre serviços. Também neste exemplo, a questão de documentar a API atinge todo o seu potencial. Obviamente, as equipes também devem ter uma ferramenta pronta para gerar documentação. Se assumirmos que ainda existe uma ferramenta pronta para gerar esquemas smd para servidores jsonrpc, a velocidade do desenvolvimento de novos serviços pode aumentar ainda mais. Como resultado, dentro da empresa, idealmente, deve haver um conjunto de bibliotecas prontas que todas as equipes usam para executar tarefas típicas. Essas bibliotecas podem ser proprietárias ou de código aberto, o principal é que elas executem bem suas tarefas. Obviamente, uma equipe que está na pilha geral e grava serviços usando bibliotecas prontas será mais eficaz do que uma equipe que faz ciclos constantes. A presença de uma única estrutura e um único banco de dados de bibliotecas que são usados em todas as equipes de projeto, eu chamo de um único ecossistema.
E as grandes empresas?
Nas grandes empresas, existem muito mais serviços de infraestrutura, bem como os protocolos de interação utilizados. O número de bibliotecas concluídas pode ir para dezenas ou até centenas. O destaque no código reutilizável aqui é ainda mais relevante.
Aconteceu que eu tenho experiência em uma empresa que emprega cerca de 200 desenvolvedores que escrevem em idiomas diferentes - java, c #, php, python, go, js, etc. Surpreendentemente, o ecossistema comum, no contexto de uma única pilha, longe de todas as equipes de desenvolvimento têm e usam. Parece que o óbvio - preparar código reutilizável, formatá-lo adequadamente e usá-lo - está longe de ser óbvio. Obviamente, as equipes de desenvolvimento resolvem seus problemas. Alguém usa um modelo de serviço - um conjunto de códigos que compõe o núcleo de cada novo serviço, do qual tudo o que é desnecessário é descartado e o necessário é adicionado.
Outras equipes de desenvolvimento usam suas próprias bicicletas, copiam e colam de um projeto para outro, e não se preocupam em documentá-las e testá-las. Em geral, há muita desunião nas ferramentas e abordagens usadas na mesma pilha em uma empresa. Além disso, geograficamente localizado em uma cidade.
Os benefícios de um único ecossistema
A formação de um único ecossistema pode resolver muitas dificuldades e tem um enorme potencial para aumentar a produtividade de uma grande empresa. De fato, essa prática é retirada da comunidade Open Source - as melhores soluções em seu campo sobrevivem e são mais populares. Agora basta abrir qualquer gerenciador de dependências e se surpreender com a abundância das soluções propostas. Mas apenas essa abordagem pode ser implementada dentro da empresa. As vantagens dessa abordagem ao implementar um novo serviço são as seguintes:
- Alta estabilidade - o uso de bibliotecas bem documentadas e cobertas por testes aumenta a estabilidade do serviço como um todo;
- Fácil rotação de colegas entre equipes - se todas as equipes estiverem dentro de um único ecossistema, ao passar de uma equipe para outra, o desenvolvedor não precisará gastar muito tempo conhecendo as ferramentas usadas, porque ele já as conhece;
- Concentração na lógica de negócios - na verdade, o desenvolvimento de um novo serviço se resume à necessidade de reforçar as dependências necessárias que resolvem todas as tarefas de infraestrutura e gravam apenas a lógica de negócios;
- Aceleração do desenvolvimento - não há necessidade de pedalar, tudo está pronto, exceto a lógica de negócios;
- Simplificação de teste - somente a lógica de negócios precisa ser testada, porque as bibliotecas já foram testadas;
Voar na pomada
É claro que, para alcançar essa abordagem, algumas práticas devem ser seguidas, a saber, desenvolver bibliotecas usando versão semântica, cuidar da documentação e testes e ter o ci configurado. Esse é um tipo de indicador de maturidade, não apenas da equipe de desenvolvimento, mas também dos desenvolvedores da empresa como um todo.
PS
E a abordagem orientada a pacotes é apenas porque o código reutilizável na minha pilha é chamado de pacote. Bem, isso parece engraçado. Recentemente, tive um diálogo com um dos meus colegas que me levou a escrever este artigo:
- Colega: você se transforma em um caixa em cinco
- eu: significado?)
- Colega: em breve você perguntará "você precisa de um pacote?"
- I: por favor, abra um pensamento. eu não entendo
- Colega: bem, pela enésima vez você tem um pacote pronto para resolver meu problema
O fato é que, em nossa comunidade de desenvolvedores da empresa, existem cerca de 20 pacotes de pacotes prontos, e a criação de um novo serviço se traduz em extrair as dependências necessárias e em escrever lógica de negócios. O custo da ligação em termos de escrita de código é quase nulo.