Metodologia de doze fatores em um microsserviço de inicialização por mola

Metodologia de doze fatores em um microsserviço de inicialização por mola

1. Visão geral

Neste tutorial, vamos entenderthe twelve-factor app methodology.

Também entenderemos como desenvolver um microsserviço com a ajuda do Spring Boot. No processo, veremos como aplicar a metodologia de doze fatores para desenvolver tal microsserviço.

2. O que é a metodologia de doze fatores?

The twelve-factor methodology is a set of twelve best practices to develop applications developed to run as a service. Isso foi originalmente elaborado pela Heroku para aplicativos implantados como serviços em sua plataforma em nuvem, em 2011. Com o tempo, isso provou ser genérico o suficiente para qualquer desenvolvimentosoftware-as-a-service (SaaS).

Então, o que queremos dizer com software como serviço? Tradicionalmente, projetamos, desenvolvemos, implantamos e mantemos soluções de software para derivar o valor comercial. Mas, não temos que nos envolver neste processo para alcançar o mesmo resultado necessariamente. Por exemplo, calcular o imposto aplicável é uma função genérica em muitos domínios.

Agora, podemos decidir construir e gerenciar este serviço nós mesmos ousubscribe to a commercial service offering. Talservice offerings are what we know as software-as-a-service.

Embora o software como serviço não imponha nenhuma restrição à arquitetura na qual é desenvolvido; é muito útil adotar algumas práticas recomendadas.

Se projetarmos nosso software para ser modular, portátil e escalonável em plataformas de nuvem modernas, ele será bastante acessível às nossas ofertas de serviço. É aqui que a metodologia de doze fatores ajuda. Nós os veremos em ação posteriormente no tutorial.

3. Microsserviço com Spring Boot

Microservice é um estilo de arquitetura para desenvolver software como serviços fracamente acoplados. O principal requisito aqui é que oservices should be organized around business domain boundaries. Geralmente, é a parte mais difícil de identificar.

Além disso, um serviço aqui tem autoridade exclusiva sobre seus dados e expõe operações a outros serviços. A comunicação entre serviços geralmente é feita através de protocolos leves como HTTP. Isso resulta em serviços implementáveis ​​e escaláveis ​​de forma independente.

Agora, a arquitetura de microsserviço e o software como serviço não dependem um do outro. Mas, não é difícil entender isso, quandodeveloping software-as-a-service, leveraging the microservice architecture is quite beneficial. Ajuda a alcançar muitos objetivos que discutimos anteriormente, como modularidade e escalabilidade.

Spring Boot é uma estrutura de aplicativo baseada no Spring que elimina muitos clichês associados ao desenvolvimento de um aplicativo corporativo. Ele nos fornece uma plataforma altamente opinativa, mas flexível, para desenvolver microsserviços. Para este tutorial, vamos aproveitar o Spring Boot para fornecer um microsserviço usando a metodologia de doze fatores.

4. Aplicando a Metodologia de Doze Fatores

Vamos agora definir um aplicativo simples que tentaremos desenvolver com as ferramentas e práticas que acabamos de discutir. Todos nós amamos assistir filmes, mas é um desafio acompanhar os filmes que já assistimos.

Agora, quem gostaria de começar um filme e depois abandoná-lo mais tarde? O que precisamos é de um serviço simples para gravar e consultar os filmes que assistimos: https: //www.example.com/wp-content/uploads/2019/09/12-factpr-app.jpg [image]

Este é um microsserviço simples e padrão, com um armazenamento de dados e pontos de extremidade REST. Precisamos definir um modelo que também será mapeado para persistência:

@Entity
public class Movie {
    @Id
    private Long id;
    private String title;
    private String year;
    private String rating;
    // getters and setters
}

Definimos uma entidade JPA com um id e alguns outros atributos. Vamos agora ver a aparência do controlador REST:

@RestController
public class MovieController {

    @Autowired
    private MovieRepository movieRepository;
    @GetMapping("/movies")
    public List retrieveAllStudents() {
        return movieRepository.findAll();
    }

    @GetMapping("/movies/{id}")
    public Movie retrieveStudent(@PathVariable Long id) {
        return movieRepository.findById(id).get();
    }

    @PostMapping("/movies")
    public Long createStudent(@RequestBody Movie movie) {
        return movieRepository.save(movie).getId();
    }
}

Isso cobre a base do nosso serviço simples. Percorreremos o restante do aplicativo enquanto discutimos como implementamos a metodologia de doze fatores nas subseções a seguir.

4.1. Codebase

A primeira prática recomendada de aplicativos de doze fatores é rastreá-lo em um sistema de controle de versão. Git é o sistema de controle de versão mais popular em uso hoje e é quase onipresente. O princípio afirma quean app should be tracked in a single code repository and must not share that repository with any other apps.

Spring Boot oferece muitas maneiras convenientes de inicializar um aplicativo, incluindo uma ferramenta de linha de comando ea web interface. Depois de gerar o aplicativo de autoinicialização, podemos convertê-lo em um repositório git:

git init

Este comando deve ser executado a partir da raiz do aplicativo. O aplicativo neste estágio já contém um arquivo .gitignore que efetivamente impede que os arquivos gerados sejam controlados por versão. Portanto, podemos criar imediatamente um commit inicial:

git add .
git commit -m "Adding the bootstrap of the application."

Finalmente, podemos adicionar um controle remoto e enviar nossos commits para o controle remoto, se desejarmos (este não é um requisito estrito):

git remote add origin https://github.com//12-factor-app.git
git push -u origin master

4.2. Dependências

Em seguida, otwelve-factor app should always explicitly declare all its dependencies. Deveríamos fazer isso usando um manifesto de declaração de dependência. Java possui várias ferramentas de gerenciamento de dependências, como Maven e Gradle. Podemos usar um deles para atingir esse objetivo.

Portanto, nosso aplicativo simples depende de algumas bibliotecas externas, como uma biblioteca para facilitar as APIs REST e conectar-se a um banco de dados. Vamos ver como podemos defini-los declarativamente usando Maven.

O Maven exige que descrevamos as dependências de um projeto em um arquivo XML, normalmente conhecido comoProject Object Model (POM):


    
        org.springframework.boot
        spring-boot-starter-web
    
    
        com.h2database
        h2
        runtime
    

Embora isso pareça claro e simples, essas dependências geralmente têm outras dependências transitivas. Isso complica até certo ponto, mas nos ajuda a alcançar nosso objetivo. Agora, nosso aplicativo não tem uma dependência direta que não seja explicitamente descrita.

4.3. Configurações

Um aplicativo geralmente possui muitas configurações, algumas das quais podem variar entre implantações, enquanto outras permanecem as mesmas.

Em nosso exemplo, temos um banco de dados persistente. Precisamos do endereço e das credenciais do banco de dados ao qual nos conectaremos. É mais provável que isso mude entre implantações.

A twelve-factor app should externalize all such configurations that vary between deployments. A recomendação aqui é usar variáveis ​​de ambiente para essas configurações. Isso leva a uma separação limpa de configuração e código.

O Spring fornece um arquivo de configuração onde podemos declarar essas configurações e anexá-las às variáveis ​​de ambiente:

spring.datasource.url=jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/movies
spring.datasource.username=${MYSQL_USER}
spring.datasource.password=${MYSQL_PASSWORD}

Aqui, definimos a URL e as credenciais do banco de dados como configurações e mapeamos os valores reais a serem escolhidos na variável de ambiente.

No Windows, podemos definir a variável de ambiente antes de iniciar o aplicativo:

set MYSQL_HOST=localhost
set MYSQL_PORT=3306
set MYSQL_USER=movies
set MYSQL_PASSWORD=password

Podemos usar uma ferramenta de gerenciamento de configuração comoAnsible ouChef para automatizar esse processo.

4.4. Serviços de apoio

Serviços de suporte são serviços dos quais o aplicativo depende para operação. Por exemplo, um banco de dados ou um intermediário de mensagens. A twelve-factor app should treat all such backing services as attached resources. O que isso significa efetivamente é que não deve exigir nenhuma mudança de código para trocar um serviço de apoio compatível. A única alteração deve estar nas configurações.

Em nosso aplicativo, usamosMySQL como o serviço de apoio para fornecer persistência.

Spring JPA torna o código bastante agnóstico para o provedor de banco de dados real. Só precisamos definir um repositório que forneça todas as operações padrão:

@Repository
public interface MovieRepository extends JpaRepository {
}

Como podemos ver, isso não depende diretamente do MySQL. O Spring detecta o driver MySQL no caminho de classe e fornece uma implementação específica da MySQL dessa interface dinamicamente. Além disso, ele extrai outros detalhes das configurações diretamente.

Então, se tivermos que mudar de MySQL para Oracle, tudo o que temos a fazer é substituir o driver em nossas dependências e substituir as configurações.

4.5. Construir, liberar e executar

A metodologia de doze fatoresstrictly separates the process of converting codebase into a running application como três estágios distintos:

  • Fase de Construção: É aqui que pegamos a base de código, executamos verificações estáticas e dinâmicas e geramos um pacote executável como um JAR. Usando uma ferramenta comoMaven, isso é bastante trivial:

     mvn clean compile test package
  • Estágio de lançamento: é o estágio em que pegamos o pacote executável e o combinamos com as configurações corretas. Aqui, podemos usarPacker com um provisionador comoAnsible para criar imagens Docker:

     packer build application.json
  • Executar estágio: Finalmente, este é o estágio em que executamos o aplicativo em um ambiente de execução de destino. Se usarmosDocker como o contêiner para lançar nosso aplicativo, a execução do aplicativo pode ser simples o suficiente:

     docker run --name  -it 

Finalmente, não precisamos necessariamente realizar essas etapas manualmente. É aqui queJenkins se torna muito útil com seu pipeline declarativo.

4.6. Processos

A twelve-factor app is expected to run in an execution environment as stateless processes. Em outras palavras, eles não podem armazenar estado persistente localmente entre as solicitações. Eles podem gerar dados persistentes que precisam ser armazenados em um ou mais serviços de backup com estado.

No caso do nosso exemplo, temos vários endpoints expostos. Uma solicitação em qualquer um desses pontos de extremidade é totalmente independente de qualquer solicitação feita antes dele. Por exemplo, se acompanharmos as solicitações do usuário na memória e usarmos essas informações para atender a solicitações futuras, ela violará um aplicativo de doze fatores.

Portanto, um aplicativo de doze fatores não impõe essa restrição, como sessões complicadas. Isso torna esse aplicativo altamente portátil e escalável. Em um ambiente de execução em nuvem que oferece escalonamento automatizado, é um comportamento bastante desejável dos aplicativos.

4.7. Ligação de porta

Um aplicativo da web tradicional em Java é desenvolvido como um WAR ou arquivo da web. Normalmente, é uma coleção de Servlets com dependências e espera um tempo de execução do contêiner compatível, como o Tomcat. A twelve-factor app, on the contrary, expects no such runtime dependency. É totalmente independente e requer apenas um runtime de execução como Java.

Em nosso caso, desenvolvemos um aplicativo usando Spring Boot. O Spring Boot, além de muitos outros benefícios, fornece um servidor de aplicativos incorporado padrão. Portanto, o JAR que geramos anteriormente usando o Maven é totalmente capaz de executar em qualquer ambiente apenas com um tempo de execução Java compatível:

java -jar application.jar

Aqui, nosso aplicativo simples expõe seus pontos de extremidade através de uma ligação HTTP a uma porta específica como 8080. Ao iniciar o aplicativo, como fizemos acima, deve ser possível acessar os serviços exportados, como HTTP.

Um aplicativo pode exportar vários serviços como FTP ouWebSocket vinculando-se a várias portas.

4.8. Concorrência

Java ofereceThread como um modelo clássico para lidar com a simultaneidade em um aplicativo. Os threads são como processos leves e representam vários caminhos de execução em um programa. Os encadeamentos são poderosos, mas têm limitações em termos de quanto isso pode ajudar a uma aplicação escalar.

The twelve-factor methodology suggests apps to rely on processes for scaling. O que isso significa efetivamente é que os aplicativos devem ser projetados para distribuir a carga de trabalho em vários processos. Os processos individuais, no entanto, podem aproveitar um modelo de simultaneidade comoThread internamente.

Um aplicativo Java, quando iniciado, obtém um único processo que está vinculado à JVM subjacente. O que precisamos efetivamente é uma maneira de iniciar várias instâncias do aplicativo com distribuição de carga inteligente entre elas. Como já empacotamos nosso aplicativo como um contêinerDocker,Kubernetes é uma escolha natural para tal orquestração.

4.9. Descartabilidade

Os processos de aplicativos podem ser encerrados de propósito ou por meio de um evento inesperado. Em qualquer caso,a twelve-factor app is supposed to handle it gracefully. Em outras palavras, um processo de aplicação deve ser completamente descartável sem efeitos colaterais indesejados. Além disso, os processos devem começar rapidamente

Por exemplo, em nosso aplicativo, um dos pontos de extremidade é criar um novo registro de banco de dados para um filme. Agora, um aplicativo que manipula essa solicitação pode falhar inesperadamente. No entanto, isso não deve afetar o estado do aplicativo. Quando um cliente envia a mesma solicitação novamente, isso não deve resultar em registros duplicados.

Em resumo, o aplicativo deve expor serviços idempotentes. Esse é outro atributo muito desejável de um serviço destinado a implantações na nuvem. Isso oferece flexibilidade para interromper, mover ou girar novos serviços a qualquer momento, sem outras considerações.

4.10. Dev/Prod Parity

É típico que os aplicativos sejam desenvolvidos em máquinas locais, testados em alguns outros ambientes e finalmente implantados em produção. Muitas vezes é o caso em que esses ambientes são diferentes. Por exemplo, a equipe de desenvolvimento trabalha em máquinas Windows, enquanto a implantação da produção acontece em máquinas Linux.

The twelve-factor methodology suggests keeping the gap between development and production environment as minimal as possible. Essas lacunas podem resultar de longos ciclos de desenvolvimento, diferentes equipes envolvidas ou diferentes pilhas de tecnologia em uso.

Agora, tecnologias como Spring Boot e Docker preenchem automaticamente essa lacuna em grande parte. Espera-se que um aplicativo em contêiner se comporte da mesma maneira, não importa onde o executemos. Devemos usar os mesmos serviços de apoio - como o banco de dados - também.

Além disso, devemos ter os processos certos, como integração e entrega contínuas, para facilitar a ponte ainda mais sobre essa lacuna.

4.11. Logs

Logs são dados essenciais que um aplicativo gera durante sua vida útil. Eles fornecem informações valiosas sobre o funcionamento do aplicativo. Normalmente, um aplicativo pode gerar logs em vários níveis, com diversos detalhes e saída ii em vários formatos diferentes.

Um aplicativo de doze fatores, no entanto, se separa da geração e do processamento de logs. For such an app, logs are nothing but a time-ordered stream of events. Ele simplesmente grava esses eventos na saída padrão do ambiente de execução. A captura, armazenamento, curadoria e arquivamento desse fluxo devem ser tratados pelo ambiente de execução.

Existem várias ferramentas disponíveis para esse fim. Para começar, podemos usarSLF4J para lidar com o log de maneira abstrata em nosso aplicativo. Além disso, podemos usar uma ferramenta comoFluentd para coletar o fluxo de logs de aplicativos e serviços de apoio.

Isso podemos alimentar emElasticsearch para armazenamento e indexação. Finalmente, podemos gerar painéis significativos para visualização emKibana.

4.12. Processos de administração

Freqüentemente, precisamos executar algumas tarefas pontuais ou procedimentos de rotina com o estado do aplicativo. Por exemplo, consertando registros incorretos. Agora, existem várias maneiras pelas quais podemos conseguir isso. Como nem sempre é necessário, podemos escrever um pequeno script para executá-lo separadamente de outro ambiente.

Agora,the twelve-factor methodology strongly suggests keeping such admin scripts together with the application codebase. Ao fazer isso, deve seguir os mesmos princípios que aplicamos à base de código do aplicativo principal. Também é aconselhável usar uma ferramenta REPL integrada do ambiente de execução para executar esses scripts em servidores de produção.

Em nosso exemplo, como semeamos nosso aplicativo com os filmes já assistidos até agora? Embora possamos usar nosso pequeno e doce ponto final, mas isso pode parecer impraticável. O que precisamos é de um script para executar uma carga única. Podemos escrever uma pequena função Java para ler uma lista de filmes de um arquivo e salvá-los em lote no banco de dados.

Além disso, podemos usar o tempo de execuçãoGroovy integrated with Java para iniciar esses processos.

5. Aplicações práticas

Então, agora vimos todos os fatores sugeridos pela metodologia de doze fatores. Desenvolvendo um aplicativo para ser umtwelve-factor app certainly has its benefits, especially when we wish to deploy them as services on the cloud. Mas, como todas as outras diretrizes, estrutura, padrões, devemos perguntar: isso é uma bala de prata?

Honestamente, nenhuma metodologia única em design e desenvolvimento de software afirma ser uma bala de prata. A metodologia de doze fatores não é exceção. Enquantosome of these factors are quite intuitive, e provavelmente já estamos fazendo,others may not apply to us. É essencial avaliar esses fatores no contexto de nossos objetivos e, em seguida, escolher sabiamente.

É importante observar que todos esses fatores sãothere to help us develop an application which is modular, independent, portable, scalable, and observable. Dependendo da aplicação, podemos alcançá-los de outras formas. Também não é necessário adotar todos os fatores juntos, mesmo alguns deles pode nos tornar melhores do que éramos

Finalmente, esses fatores são bastante simples e elegantes. Eles têm maior importância em uma época em que exigimos que nossos aplicativos tenham maior taxa de transferência e menor latência, praticamente sem tempo de inatividade e falha. Adopting these factors gives us the right start from the beginning. Combinados com a arquitetura de microsserviço e a conteinerização de aplicativos, eles parecem ter chegado ao ponto certo.

6. Conclusão

Neste tutorial, examinamos os conceitos da metodologia de doze fatores. Discutimos como alavancar uma arquitetura de microsserviço com o Spring Boot para entregá-los efetivamente. Além disso, exploramos cada fator em detalhes e como aplicá-los ao nosso aplicativo. Também exploramos várias ferramentas para aplicar esses fatores individuais de maneira eficaz com sucesso.