fundo
The Twelve Factor App

O aplicativo de 12 fatores é um conjunto de características que uma aplicação como serviço escalável deve possuir, estamos reunindo nessa postagem todo o material que já elaboramos sobre esse assunto para facilitar a leitura. Você também pode encontrar esse material em nosso instagram (Possuímos um guia sobre o assunto clique aqui para acessar). Mais informações sobre esses 12 fatores você pode localizar na página independente que reúne informações sobre esses fatores: https://12factor.net/pt_br/  .

  • Estes fatores são:

1. Base de Código

Ter uma boa base de código desde o início da construção da aplicação é essencial para que possamos construir algo sólido e de qualidade. Mas como ter essa base?

  • Uma boa aplicação que utiliza o the twelve factor app além de muitos testes aplicados ela tem um sistema de rastreamento onde ocorre o controle de versão que são os famosos repositórios,  onde mesmo que os devs envolvidos no mesmo tenham versões mais (ou menos) atualizadas, ainda sim a codebase seja sólida o suficiente.

  • Mas cuidado para não violar 12 factor app utilizando a mesma code base para várias aplicações diferentes.


2. Dependências

A maioria das linguagens de programação tem um sistema de gerenciamento de pacotes para distribuição de bibliotecas que facilitam o desenvolvimento de software, como o npm, yarn ou pipenv do python. o isolamento dessas dependências é essencial para que possamos evitar conflitos com as pacotes instalados globalmente. Ou seja, se você não isola suas dependências você esta violando o 12 factor app.

3. Configurações

Esse é um fator que comentamos bastante aqui no minhaStack, mas como quem avisa amigo é, vamos refrescar sua memória. Esse fator está diretamente ligado a alguns quesitos de segurança que toda aplicação deve se preocupar, que implica em cuidar entre cada deploy da sua aplicação das configurações ,que fazem seu projeto funcionar, como as credenciais 'de acesso ao banco de dados, e até parâmetros que vão influenciar o funcionamento da sua aplicação. E para garantir que essas informações sejam armazenadas corretamente, você pode armazená-las nas variáveis de ambiente.

4. Serviços de Apoio

Esse "factor" é bem interessante e pode ser que faça você sentir com dificuldade caso ainda seja iniciante, mas não se preocupa que a gente vai enxugar ao máximo esse assunto para que você entenda rapidamente. Esse quarto fator requer que sua ,aplicação ou serviço consiga trocar os serviços de 'apoio, como os banco de dados sem que seja modificada nenhuma linha de código, apenas a forma com que as requisições são feitas caso isso varie de base de dados pra base de dados.

  • Então vai trocar de base de dados ou algo assim e quer sua aplicação esteja seguindo o 12 factor app? Lembre-se desse post.


5. Construa, lance, execute

Quando estamos desenvolvendo uma aplicação, passamos por essas três etapas sempre. E para que sigamos o 12 factor app, devemos sempre separar esses três processos. O 12 factor usa separação estrita entre os estágios de construção, lançamento )e execução. É impossível alterar código em tempo de execução, já que não há meios de se propagar tais mudanças de volta ao estágio de construção, então separamos todos os processos.

6. Processos

Na prática isso significa dizer que toda persistência de dados deve ser realizada em um serviço de apoio, fazendo assim com que os servidores que rodam nossa aplicação possam ser facilmente descartáveis nos processos de scaling ou escalonamento pois tudo está rodando um serviço de apoio e construção, então separamos todos os processos.

7. Vínculo de porta

Exporte serviços via vínculo de portas. Apps web as vezes são executadas dentro de container de servidor web. Por exemplo, apps PHP podem rodar como um módulo dentro do Apache HTTPD, ou apps Java podem rodar dentro do Tomcat. )0 aplicativo doze-fatores é completamente auto-contido e não depende de injeções de tempo de execução de um servidor web em um ambiente de execução para criar um serviço que defronte a web. O app web exporta o HTTP como um serviço através da vínculação a uma porta, e escuta as requisições que chegam na mesma.

  • Num ambiente de desenvolvimento local, o desenvolvedor visita a URL de um serviço como http://localhost:5000/ para acessar o serviço exportado pelo seu app. Num deploy, uma camada de roteamento manipula as requisições de rotas vindas de um hostname público para os processos web atrelados às portas.

  • Isso é tipicamente implementado usando declaração de dependências para adicionar uma biblioteca de servidor ao app, tal como Tornado para Python, Thin para Ruby, ou Jetty para Java e outra linguagens baseadas na JVM. Isso acontece completamente no espaço do usuário, isso é, dentro do código do app. 

  • O contrato com o ambiente de execução é vincular a uma porta para servir requisições.
  • HTTP não é o único serviço que pode ser exportado via vínculo de portas. Quase todos os tipos de software servidores podem rodar via um processo vinculado a uma porta e aguardar as requisições chegar. Exemplos incluem ejabberd (comunicando via XMPP), e Redis (comunicando via protocolo Redis).

  • Note que a abordagem de vincular portas significa que um app pode se tornar o serviço de apoio para um outro app, provendo a URL do app de apoio como um identificador de recurso na configuração para o app consumido.


8. Concorrência

Escale através do processo modelo Qualquer programa de computador, uma vez executado, está representado por um ou mais processos. Aplicações web têm tomado uma variedade de formas de processo de execução. Por exemplo, processos PHP rodam como processos filhos do Apache, iniciados sob demanda conforme necessário por volume de requisições. Processos Java 1') tomam tomam o caminho inverso, com a JVM proporcionando um processo uber maciço que reserva um grande bloco de recursos do sistema (CPU e memória) na inicialização, com concorrência gerenciada internamente via threads. Em ambos os casos, o(s) processo(os) em execução são apenas minimamente visível para os desenvolvedores da aplicação

  • Na aplicação doze-fatores, processos são cidadãos de primeira classe. Processos na aplicação doze-fatores utilizam fortes sugestões do modelo de processos UNIX para execução de serviços daemon, o desenvolvedor pode arquitetar a aplicação dele para lidar com diversas cargas de trabalho, atribuindo a cada tipo de trabalho a um tipo ,de processo. Por exemplo, solicitações HTTP podem ser 'manipuladas para um processo web, e tarefas background de longa duração podem ser manipuladas por um processo trabalhador.

  • O modelo de processo realmente brilha quando chega a hora de escalar. O compartilhar-nada, natureza horizontal particionada de um processo da aplicação doze-fatores significa que a adição de mais simultaneidade é uma operação simples e de confiança. A matriz de tipos de processo e número de processos de cada tipo é conhecida como o processo de formação.

  • Processos de uma app doze-fatores nunca deveriam daemonizar ou escrever arquivos PID. Em vez disso, confiar no gerente de processo do sistema operacional (como systemd, um gerenciador de processos distribuídos em uma plataforma de nuvem, ou uma ferramenta como Foreman em desenvolvimento) para gerenciar fluxos de saída (falaremos disso no factor 11), responder a processos travados, e lidar com reinícios e desligamentos iniciados pelo usuário.


9. Descartabilidade

Maximize robustez com inicialização rápida e desligamento gracioso Os processos de um app doze-fatores são descartáveis, significando que podem ser iniciados ou parados a qualque momento. Isso facilita o escalonamento elástico, rápido ',deploy de código ou mudanças de configuração, e robustez,; de deploys de produção.

  • Processos devem empenhar-se em minimizar o tempo de inicialização. Idealmente, um processo leva alguns segundos do tempo que o comando de inicialização é executado até o ponto que ele estará pronto para receber requisições ou tarefas. Períodos curtos de inicialização provém mais agilidade para o processo de release e de ;,escalonamento; e ele adiciona robustez, pois o gestor de processos pode mais facilmente mover processos para outras máquinas físicas quando necessário.

  • Processos desligam-se graciosamente quando recebem um sinal SIGTERM do seu gestor de processos. Para um processo web, desligamento gracioso é alcançado quando cessa de escutar à porta de serviço (consequentemente recusando quaisquer requisições novas), permitindo qualquer requisição em andamento terminar, e então ,desligando. Implícito neste modelo é que as requisições HTTP são curtas (não mais que alguns poucos segundos), ou no caso de um longo polling, o cliente deve ser capaz de transparentemente tentar se reconectar quando a conexão for perdida.

  • Para um processo de trabalho (worker), desligamento gracioso é alcançado retornando a tarefa atual para fila de trabalho. Por exemplo, no RabbitMQ o trabalhador pode enviar um NACK; no Beanstalkd, a tarefa é retornada para a fila automaticamente sempre que um trabalhador se desconecta. Sistemas baseados em trava como o Delayed Job precisam ')se certificar de soltar a trava no registro da tarefa. Implícito neste modelo é que todas as tarefas são reentrantes, o que tipicamente é atingindo envolvendo os resultados numa transação, ou tornando a operação idempotente.

  • Processos também devem ser robustos contra morte súbida, no caso de uma falha de hardware. Ao passo que isso é muito menos comum que um desligamento via SIGTERM, isso ainda pode acontecer. 

  • Uma abordagem recomendada é usar um backend de filas robusto, como o Beanstalkd, que retorna tarefas à fila quando clientes desconectam ou esgotam o tempo de resposta. De qualquer forma, um app doze-fatores é arquitetado para lidar com terminações não esperadas e não graciosas. Crash-only design leva este conceito à sua conclusão lógica.


10. Dev/prod semelhantes

Mantenha o desenvolvimento, homologação e produção o mais similares possível Historicamente, houveram lacunas substanciais entre desenvolvimento (um desenvolvedor editando código num deploy local do app) e produção (um deploy acessado pelos usuários finais). Essas lacunas se manifestam em três áreas:

  • A lacuna do tempo: Um desenvolvedor pode trabalhar em código demora dias, semanas ou até meses para ir para produção. - A lacuna de pessoal: Desenvolvedores escrevem código, engenheiros de operação fazem o deploy dele.

  • A lacuna de ferramentas: Desenvolvedores podem estar usando um conjunto como Nginx, SQLite, e OS X, enquanto o app em produção usa Apache, MySQL, e Linux.


11. Logs

Logs provém visibilidade no comportamento de um app em execução. Em ambientes de servidor eles são comumente escritos num arquivo em disco (um "Iogfile"); mas este é apenas um formato de saída.

  • Logs são o fluxo de eventos agregados e ordenados por 'tempo coletados dos fluxos de saída de todos os processos em execução e serviços de apoio. Logs na sua forma crua são tipicamente um formato de texto com um evento por linha (apesar que pilhas de exceção podem ocupar várias linhas). Logs não tem começos ou términos fixos, mas fluem continuamente enquanto o app estiver operante.


12. Processos de Administrador

Rode tarefas de administração/gestão em processos pontuais

  • A formação de processos é o conjunto de processos que são usados para fazer as negociações regulares da app como ela é executada (tais como manipulação de requisições web). Separadamente, os desenvolvedores, muitas vezes desejam fazer tarefas pontuais de administração ou manutenção para a app.