Microserviços com Spring Cloud: Parte 1
Introdução
Olá galera, quem me acompanha nas redes sociais (Facebook, Instagram, LinkedIn, etc) deve saber que mudei recentemente de projeto. Anteriormente estava a trabalhar em um projeto na OLX, mas há algum tempo atrás mudei de projeto e no momento estou a trabalhar na Accenture.
Na OLX estava a trabalhar com PHP: uma das primeiras linguagens que aprendi, a que trabalho a mais tempo e tenho mais experiência, e apesar de nesse momento eu estar a focar em Go, o projeto que estou atualmente é em Java e como tinha um tempo que não trabalhava com Java, resolvi estudar um pouco e me atualizar.
No projeto atual não usamos Spring, mas como é um Ecossistema (pessoalmente não considero o Spring como um Framework, pois atualmente ele é realmente um ecossistema completo e cheio de ferramentas para projetos Java) que gosto muito de trabalhar com, resolvi aprofundar em alguns assuntos.
Arquitetura
Nessa pequena série de artigos, iremos ver como construir uma arquitetura minimalista utilizando o Spring Cloud. Nossa arquitetura será composta por quatro serviços e será desenvolvida com base em containers Docker para facilitar o processo de “deploy”:
- Serviço de Descoberta (de outros serviços)
- API Gateway
- Dois microserviços REST bem simples
Caso queira ver como a nossa arquitetura irá ficar no final da nossa série de artigos, você pode checar o repositório aqui!!!
Para seguir o passo-a-passo da criação da nossa arquitetura continue lendo esse artigo e os outros artigos dessa série. Para continuar você irá precisar de ter instalado as seguintes ferramentas: JDK 8+, Docker e Maven.
Serviço de descoberta
Nessa primeira parte iremos construir o nosso Serviço de Descoberta que tem por finalidade ser um ponto central onde todos os nossos microserviços irão se registrar para dessa forma termos um controle de quais e quantos serviços temos disponíveis ao decorrer do ciclo de vida da nossa aplicação.
Para iniciar crie um diretório spring-microservices
, esse será o diretório onde iremos criar nossa arquitetura. Agora para criar o nosso primeiro serviço, crie um diretório discovery-service
que será nosso Serviço de Descoberta e entre nele. Como nosso projeto irá utilizar o Maven, crie um arquivo pom.xml
para adicionarmos as nossas dependências (veja o código completo aqui).
Não irei explicar a estrutura de um arquivo pom.xml
pois irei supor que quem está lendo já tenha um conhecimento prévio de como o Maven funciona. Caso você não tenha, antes de continuar a ler esse artigo tire um tempo para ler um pouco sobre o Maven.
Spring Boot Actuator
Uma das dependências que você irá ver em nosso pom.xml
é: spring-boot-starter-actuator
. Essa dependência fornece alguns endpoints “out-of-the-box” para aplicações Spring Boot:
- /health: fornece informações sobre o estado do servidor.
- /info: fornece informações diversas. Na configuração da aplicação podemos definir quais informações queremos disponibilizar.
Além dos endpoints listados acima, o Actuator disponibiliza diversos outros endpoints. Você pode ver uma lista completa aqui.
Spring Cloud Netflix Eureka
A dependência mais importante do nosso Serviço de Descoberta é: spring-cloud-starter-eureka-server
. O Eureka é uma biblioteca para criar uma arquitetura de descoberta de serviços desenvolvido e disponibilizado pela Netflix.
Para criarmos a arquitetura de descoberta e registro de serviços da nossa aplicação iremos utilizar o Eureka. O nosso Serviço de Descoberta será um Eureka Server que, como dito anteriormente, tem a função de ser um ponto central onde nossos serviços irão se registrar.
Criando nosso serviço
Para continuarmos crie a seguinte estrutura de diretórios/arquivos:
pom.xml
src
main
java
br
com
codeshare
microservices
discovery
Application.java
resources
application.yml
banner.txt
test
java
Para criarmos nosso servidor Eureka precisamos apenas de uma classe Java bem simples como podemos ver abaixo:
Criamos nossa classe Application.java que tem apenas um método main para iniciar nossa aplicação. Para quem já trabalhou com o Spring Boot não há nada de especial. A única diferença que temos aqui é que além da anotação @SpringBootApplication
para dizermos que nossa aplicação é uma aplicação Spring Boot, adicionamos a anotação @EnableEurekaServer
para dizermos que nossa aplicação será um servidor Eureka. Agora basta configurar o nosso serviço e pronto.
A configuração do nosso serviço fica no arquivo application.yml
e vamos fazer uma configuração bem simples como a abaixo:
Na nossa configuração definimos a porta que a nosso serviço irá ser executado que será o valor da variável de ambiente PORT caso exista e caso não encontre essa variável de ambiente, irá ser a porta 8761 e definimos o nome da nossa aplicação para discovery-service. A configuração do Eureka que estamos a fazer é bem simples, colocamos que nossa aplicação irá ser executada no localhost e definimos uma configuração de cliente para nosso servidor (isso não é necessário, mas se quisermos ter mais de um Serviço de Descoberta, podemos definir se um Serviço de Descoberta irá se registrar em outro) apenas como exemplo. Com isso nosso serviço está completo, mas caso queira fazer com que seu serviço seja mais “personalizado” podemos criar dentro do diretório resources
um arquivo chamado banner.txt
e nele podemos colocar um texto em ASCII, para que quando a aplicação for executada, irá imprimir no console o texto definido. Por exemplo a nossa aplicação tem o seguinte conteúdo no arquivo banner.txt
:
Você pode usar esse site para criar o seu texto em ASCII personalizado.
Criando nossa imagem Docker
Definimos no nosso pom.xml
que o artefato final do nosso serviço seria um arquivo .jar
(definido em: <packaging>jar</packaging>
) e também definimos que o nome do arquivo seria discovery-service (definido em: <finalName>discovery-service</finalName>
. Então quando fizermos o build de nosso serviço o artefato final será o arquivo discovery-service.jar
que será criado dentro do diretório target
na raiz do nosso serviço. Com nosso serviço é uma aplicação Spring Boot, precisamos apenas do nosso arquivo final e do Java para conseguirmos executar nossa aplicação e, com isso em mente, vamos criar uma imagem simples e leve apenas com o necessário para que nossa aplicação seja executada. Na raiz do nosso serviço crie um arquivo Dockerfile
da seguinte maneira:
Nossa imagem é bem simples, estou a usar como base uma imagem Linux Alpine que é bem leve e tem um tamanho bem reduzido com o JDK 8 já instalado. Estou a definir uma variável de ambiente com nome PORT (que será usada pela nossa aplicação através do arquivo application.yml
). Depois disso eu pego o artefato final da build do nosso serviço e adiciono na nossa imagem com o nome app.jar
e para executar nosso serviço quando o container for executado eu defino que o entrypoint da nossa imagem vai ser executar o arquivo .jar
do nosso serviço. Depois disso apenas faço um expose na porta utilizada pelo nosso serviço para poder fazer bind à essa porta. Vamos agora fazer o build da nossa imagem Docker, na raiz do nosso serviço execute o comando:
docker build -t "codeshare/discovery" .
Testando nosso serviço
Com nosso serviço e nossa imagem criada, podemos finalmente testar o nosso serviço. Execute o comando:
docker run -it -p 8761:8761 codeshare/discovery
No console você verá algo parecido com a imagem abaixo:
Agora vá para http://localhost:8761 e você irá ver uma página como a imagem abaixo:
Como esperado, a lista “Instances currently registered with Eureka” está vazia, pois no momento não temos nenhum outro serviço criado. No próximo artigo dessa série iremos criar nossos dois microserviços REST e registrar eles em nosso Serviço de Descoberta que acabamos de criar.
Espero que tenham gostado!!! Continuem ligados na CodeShare para mais conteúdos de qualidade e para as novidades que estamos a preparar!!! Um grande abraço para todos e até a próxima!!! xD