12 Factor App (Boas práticas para criar uma aplicação SaaS)

Odilio Noronha
RapaduraTech
Published in
8 min readOct 13, 2021

Introdução

A empresa Heroku- criadora do famoso plataform-as-a-service — mantém um tipo de manifesto chamado “The Twelve Factor App”. Este manifesto descreve doze práticas para serem seguidas ao criar aplicações voltadas para nuvem(e consequentemente, microsserviços). Eu recomendo acessar o site oficial e ler os detalhes, já que não vamos repetir tudo o que já está escrito lá. O objetivo deste post é entender brevemente cada um dos fatores e como eles se relacionam com o mundo dos microsserviços.

Na era moderna, software é comumente entregue como um serviço: denominados web apps, ou software-como-serviço. A 12 Factor App é uma metodologia para construir softwares-como-serviço que:

  • Usam formatos declarativos para automatizar a configuração inicial, minimizar tempo e custo para novos desenvolvedores participarem do projeto;
  • Tem um contrato claro com o sistema operacional que o suporta, oferecendo portabilidade máxima entre ambientes que o executem;
  • São adequados para implantação em modernas plataformas em nuvem, evitando a necessidade por servidores e administração do sistema;
  • Minimizam a divergência entre desenvolvimento e produção, permitindo a implantação contínua para máxima agilidade;
  • E podem escalar sem significativas mudanças em ferramentas, arquiteturas, ou práticas de desenvolvimento.

A metodologia doze-fatores pode ser aplicada a aplicações escritas em qualquer linguagem de programação, e que utilizem qualquer combinação de serviços de suportes (banco de dados, filas, cache de memória, etc).

Os Doze Fatores

I. Base de Código

Uma base de código com rastreamento utilizando controle de revisão, muitos deploys

Este princípio aconselha que cada aplicação tenha sua própria base de código. Esta base de código normalmente está versionada em sistemas de controle de versão(Git, Subversion, etc).

Nos microsserviços, cada microsserviço deve ter sua própria base de dados, assim o mesmo código não é compartilhado entre os eles. Com um sistema de controle de versões é possível ter inúmeras versões da aplicação em execução, a partir de uma mesma base. Por exemplo, no Git, você pode ter sua aplicação executando a partir do código da branch master, ao mesmo tempo em que desenvolve novas funcionalidades na branch develop

II. Dependências

Declare e isole as dependências

Quando pensamos em dependências geralmente pensamos nas bibliotecas dependentes. Para estes casos é só utilizar as ferramentas de gerenciamento de pacote(npm, yarn, maven, gradle) que o básico será garantido. Porém, os problemas podem começar quando é necessário gerenciar dependências externas — conexões com banco de dados, serviços, etc. Para estes casos, é interessante dar uma olhada em algumas ferramentas que auxiliam neste processo, por exemplo Chef, Puppet e Kubernetes. Ter as dependências declaradas desta forma é realmente benéfico, pois auxilia no processo de integração de novas pessoas na equipe e também no deploy do produto final.

III. Configurações

Armazene as configurações no ambiente

É muito fácil cometer um erro ao trabalhar com configurações em microsserviços. No começo, é muito simples criar apenas alguns arquivos de configuração e carregá-los dependendo do ambiente em que o serviço está sendo executado. Porém, quando o número de serviços e ambientes cresce, a dificuldade de manter as configurações cresce exponencialmente. Outro problema de manter as configurações em arquivos é a falha de segurança. A solução para isto é manter suas configurações externamente ao código da sua aplicação, como por exemplo em variáveis de ambiente ou bancos de dados.

IV. Serviços de Apoio

Trate os serviços de apoio, como recursos ligados

Todos os serviços devem ser acessados por uma URL. Todos serviços possuem a necessidade de conversar com recursos externos durante o ciclo de vida de sua execução. Por exemplo, eles podem escutar ou enviar mensagens para sistemas de mensageria, enviar um e-mail, persistir um dado em um banco de dados e assim por diante. Todos os serviços citados, devem ser acessados por meio de uma URL, sem necessidade de uma comunicação complexa.

V. Build, Release, Run

Separe estritamente os builds e execute em estágios

Divide o processo de implantação em três estágios ​​que podem ser instanciados a qualquer momento. O Build é onde o código é recuperado do sistema de gerenciamento de código-fonte e construído / compilado em artefatos armazenados em um repositório de artefato, como Docker Hub ou um repositório Maven. Depois que o código é construído, as definições de configuração são aplicadas no Release. Em seguida, no estágio de execução, um ambiente de tempo de execução é provisionado por meio de scripts usando uma ferramenta como Ansible. O aplicativo e suas dependências são implementados no ambiente de tempo de execução recém-provisionado.

VI. Processos

Execute a aplicação como um ou mais processos que não armazenam estado

Sugere que os processos devem ser stateless (sem estado) e não compartilhar nada. Consequentemente, a aplicação torna-se tolerante a falhas e facilmente escalável.

Para o correto funcionamento da arquitetura, todos microsserviços devem ser projetados para serem stateless. Se existir qualquer necessidade de armazenar o estado, o mesmo deverá ser feito pelo próprio serviço. Utilizando, por exemplo, algum banco de dados.

VII. Vínculo de porta

Exporte serviços por ligação de porta

Assim como no princípio anterior, este é importante para garantir que os serviços sejam escaláveis e independentes. Este princípio recomenda que, quando necessário, a visibilidade entre os serviços seja dada através de port-binding (portas visíveis). Desta forma, todos serviços possuem capacidade de se comunicarem quando necessário.

VIII. Concorrência

Dimensione por um modelo de processo

Estabelece que processos devem separados por seu proposito, assim eles podem ser separados e escalados de acordo com sua necessidade. No mundo dos microsserviços, ferramentas como o Kubernetes ajudam neste quesito. A ideia é que, quando for necessário escalar, a sua aplicação que dever ser replicada (fazendo cópias dos processos), em vez de subir uma instância nova — com uma máquina mais potente.

IX. Disposability

Maximizar a robustez com inicialização e desligamento rápido

Disposability em um aplicativo permite que ele seja iniciado ou interrompido rapidamente.

O aplicativo não pode escalar, implantar ou recuperar rapidamente se levar muito tempo para entrar em um estado estável e desligar normalmente. Se nosso aplicativo estiver sob carga crescente e precisarmos trazer mais instâncias para lidar com essa carga, qualquer atraso na inicialização pode significar a negação de solicitações durante o tempo em que o aplicativo está inicializando.

Os aplicativos Spring Boot devem ser executados dentro de contêineres para torná-los descartáveis. Os contêineres são efêmeros e podem ser iniciados ou interrompidos a qualquer momento.

Portanto, é importante minimizar o tempo de inicialização e garantir que o aplicativo seja encerrado normalmente quando o contêiner parar. O tempo de inicialização é minimizado com a inicialização lenta de recursos dependentes e com a construção de imagens de contêiner otimizadas.

X. Dev/prod Parity

Mantenha o desenvolvimento, teste, produção o mais semelhante possível

O princípio Dev/Prod parity significa que todos os ambientes de implantação são semelhantes, mas independentes e que nenhuma implantação “salta” para outro destino de implantação.

A figura acima mostra duas versões do código de um aplicativo. A versão V1 é direcionada para lançamento no ambiente de produção. Uma nova versão, V2, é direcionada para um ambiente de desenvolvimento. Tanto a V1 quanto a V2 seguem um caminho de implantação semelhante, da construção ao lançamento e, em seguida, à execução. Caso a versão V2 do código seja considerada pronta para produção, os artefatos e configurações relevantes para V2 NÃO serão copiados para o ambiente de produção.

Em vez disso, o processo de CI / CD será ajustado para definir a meta de implantação de V2 para Produção. O processo de CI / CD seguirá o padrão de construção, liberação e execução esperado para esse novo destino.

Como você pode ver, Dev / Prod Parity é muito semelhante a Build, Release e Run. A distinção importante é que a Paridade Dev / Prod garante o mesmo processo de implantação para Produção e Desenvolvimento.

XI. Logs

Trate logs como fluxo de eventos

No mundo dos microsserviços, a escalabilidade e dimensionamento é comum. Isto quer dizer que máquinas/containers podem morrer ou nascer a qualquer momento, e com isso, os logs de arquivos físicos são perdidos. É por isto que este princípio é essencial para uma aplicação com com esta arquitetura.

Tratando os logs como fluxo de eventos e armazenando-os em ferramentas de gerenciamento de Logs, por exemplo, Graylog, ELK, Splunk, etc. É possível acompanhar os logs do seu sistema distribuído em tempo real e até criar alertas para monitoramento.

XII. Processos de Admin

Executar tarefas de administração/gerenciamento como processos pontuais

O princípio dos Processos Administrativos afirma que os processos administrativos são cidadãos de primeira classe no ciclo de vida de desenvolvimento de software e precisam ser tratados como tal. Processos como executar scripts de migração de banco de dados, comandos de Shell script e outros, são parte essencial do trabalho de desenvolvimento. Este princípio aconselha utilizar um ambiente idêntico para tais manutenções, isto é, mesma versão de sistemas, pacotes, ferramentas e mesmos arquivos de configuração, assim como no principio Dev/prod Parity. Desta maneira é minimizado os riscos de problemas de sincronização de versões entre diferentes ambientes.

Porque usar Os 12 Fatores

O que pode parecer trivial agora pode ser de extrema importância quando você estiver executando 15/20 (ou mais) serviços em 4 ambientes diferentes. Se você já tem microsserviços para cuidar, veja se há pontos que você perdeu e talvez eles possam ajudá-lo a resolver problemas que você não conseguia corrigir antes.

Muitas empresas encontraram valor na adoção dos princípios e práticas que impulsionam os 12 Fatores. Eles fizeram o trabalho pesado. Eles viram a luz. Se os 12 Fatores funciona para eles, os princípios podem funcionar para você também. Tudo que você precisa fazer é dar o primeiro passo.

--

--