Arquitetura de microsserviços: implemente localmente com Java, Spring e MongoDB
Maxime Beugnet4 min read • Published Aug 29, 2024 • Updated Aug 29, 2024
APLICATIVO COMPLETO
Avaliar este tutorial
"Os microsserviços são incríveis e os aplicativos monolíticos são maus."
Se você está lendo este artigo, você já o leu um milhão de vezes, e não serei eu que lhe direi o contrário!
Neste post, criaremos uma arquitetura de microsserviços usando o MongoDB.
O código fonte está disponível nestes dois repositórios.
1 git clone git@github.com:mongodb-developer/microservices-architecture-mongodb.git 2 git clone git@github.com:mongodb-developer/microservices-architecture-mongodb-config-repo.git
Vamos usar as dependências Spring Boot e Spring Cloud para construir nossa arquitetura.
Precisamos de vários serviços para executar este projeto. Vamos falar sobre eles um por um.
As you read this post, I suggest that you follow the instructions in the README.md file and start the service related to each section.
O primeiro serviço de que precisamos é de um servidor de configuração.
Esse serviço nos permite armazenar todos os arquivos de configuração de nossos microsserviços em um único repositório para que nossas configurações sejam fáceis de versão e armazenamento.
A configuração do nosso servidor de configuração é simples e direta ao ponto:
1 spring.application.name=config-server 2 server.port=8888 3 spring.cloud.config.server.git.uri=${HOME}/Work/microservices-architecture-mongodb-config-repo 4 spring.cloud.config.label=main
Ele nos permite localizar o repositório git que armazena nossa configuração de microsserviços e a ramificação que deve ser
usado.
Note that the only "trick" you need in your Spring Boot project to start a config server is the
@EnableConfigServer
annotation.1 package com.mongodb.configserver; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.cloud.config.server.EnableConfigServer; 6 7 8 9 public class ConfigServerApplication { 10 public static void main(String[] args) { 11 SpringApplication.run(ConfigServerApplication.class, args); 12 } 13 }
Um registro de serviço é como uma lista telefônica para microsserviços. Ele monitora quais microsserviços estão em execução e onde
eles estão localizados (endereço IP e porta). Outros serviços podem procurar essas informações para encontrar e se comunicar com o
microsserviços de que precisam.
Um registro de serviço é útil porque permite o balanceamento de carga no lado do cliente e separa os provedores de serviços dos consumidores sem a necessidade de DNS.
Again, you don't need much to be able to start a Spring Boot service registry. The
@EnableEurekaServer
annotation
makes all the magic happen.1 package com.mongodb.serviceregistry; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 7 8 9 public class ServiceRegistryApplication { 10 public static void main(String[] args) { 11 SpringApplication.run(ServiceRegistryApplication.class, args); 12 } 13 }
A configuração também vai ao ponto:
1 spring.application.name=service-registry 2 server.port=8761 3 eureka.client.register-with-eureka=false 4 eureka.client.fetch-registry=false
As duas últimas linhas impedem que o registro de serviço se registre para si mesmo e recupere o registro de si mesmo.
O serviço de gateway de API nos permite ter um único ponto de entrada para acessar todos os nossos microsserviços. Claro, você deveria
têm mais de um em produção, mas todos eles poderão se comunicar com todos os microsserviços e distribuir
a carga de trabalho uniformemente, balanceando a carga das consultas em seu pool de microsserviços.
Além disso, um gateway de API é útil para abordar preocupações transversais, como segurança, monitoramento, coleta de métricas e resiliência.
Quando nossos microsserviços iniciam, eles se registram no registro de serviços. O gateway de API pode usar esse registro para localizar os microsserviços e distribuir as queries de acordo com sua configuração de roteamento.
1 server: 2 port: 8080 3 4 spring: 5 application: 6 name: api-gateway 7 cloud: 8 gateway: 9 routes: 10 - id: company-service 11 uri: lb://company-service 12 predicates: 13 - Path=/api/company/**,/api/companies 14 - id: employee-service 15 uri: lb://employee-service 16 predicates: 17 - Path=/api/employee/**,/api/employees 18 19 eureka: 20 client: 21 register-with-eureka: true 22 fetch-registry: true 23 service-url: 24 defaultZone: http://localhost:8761/eureka/ 25 instance: 26 hostname: localhost
Observe que nosso gateway de API é executado na porta 8080.
Finalmente, temos nossos microsserviços MongoDB.
Os microsserviços devem ser independentes uns dos outros. Por esse motivo, precisamos de duas instâncias do MongoDB: uma para cada microsserviço.
Note that in
the configuration files for the
company and employee services, they are respectively running on ports 8081 and 8082.
1 spring.data.mongodb.uri=${MONGODB_URI_1:mongodb://localhost:27017} 2 spring.threads.virtual.enabled=true 3 management.endpoints.web.exposure.include=* 4 management.info.env.enabled=true 5 info.app.name=Company Microservice 6 info.app.java.version=21 7 info.app.type=Spring Boot 8 server.port=8081 9 eureka.client.register-with-eureka=true 10 eureka.client.fetch-registry=true 11 eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ 12 eureka.instance.hostname=localhost
1 spring.data.mongodb.uri=${MONGODB_URI_2:mongodb://localhost:27018} 2 spring.threads.virtual.enabled=true 3 management.endpoints.web.exposure.include=* 4 management.info.env.enabled=true 5 info.app.name=Employee Microservice 6 info.app.java.version=21 7 info.app.type=Spring Boot 8 server.port=8082 9 eureka.client.register-with-eureka=true 10 eureka.client.fetch-registry=true 11 eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ 12 eureka.instance.hostname=localhost
Observe que os dois microsserviços estão conectados a dois clusters MongoDB diferentes para manter sua dependência. O serviço da empresa está usando o nó do MongoDB na porta 27017 e o serviço do funcionário está na porta 27018.
Of course, this is only if you are running everything locally. In production, I would recommend to use two clusters on
MongoDB Atlas. You can overwrite the MongoDB URI with the environment variables (see README.md).
Neste ponto, você deve ter cinco serviços em execução:
- Um servidor de configuração na porta 8888
- Um registro de serviço na porta 8761
- Um gateway de API na porta 8080
- Dois microsserviços:
- serviço de empresa na porta 8081
- serviço de funcionário na porta 8082
E dois nós do MongoDB nas portas 27017 e 27018 ou dois clusters do MongoDB no MongoDB Atlas.
1 DELETE Companies 2 2 3 DELETE Employees 4 2 5 6 POST Company 'MongoDB' 7 POST Company 'Google' 8 9 GET Company 'MongoDB' by 'id' 10 { 11 "id": "661aac7904e1bf066ee8e214", 12 "name": "MongoDB", 13 "headquarters": "New York", 14 "created": "2009-02-11T00:00:00.000+00:00" 15 } 16 17 GET Company 'Google' by 'name' 18 { 19 "id": "661aac7904e1bf066ee8e216", 20 "name": "Google", 21 "headquarters": "Mountain View", 22 "created": "1998-09-04T00:00:00.000+00:00" 23 } 24 25 GET Companies 26 [ 27 { 28 "id": "661aac7904e1bf066ee8e214", 29 "name": "MongoDB", 30 "headquarters": "New York", 31 "created": "2009-02-11T00:00:00.000+00:00" 32 }, 33 { 34 "id": "661aac7904e1bf066ee8e216", 35 "name": "Google", 36 "headquarters": "Mountain View", 37 "created": "1998-09-04T00:00:00.000+00:00" 38 } 39 ] 40 41 POST Employee Maxime 42 POST Employee Tim 43 44 GET Employee 'Maxime' by 'id' 45 { 46 "id": "661aac79cf04401110c03516", 47 "firstName": "Maxime", 48 "lastName": "Beugnet", 49 "company": "Google", 50 "headquarters": "Mountain View", 51 "created": "1998-09-04T00:00:00.000+00:00", 52 "joined": "2018-02-12T00:00:00.000+00:00", 53 "salary": 2468 54 } 55 56 GET Employee 'Tim' by 'id' 57 { 58 "id": "661aac79cf04401110c03518", 59 "firstName": "Tim", 60 "lastName": "Kelly", 61 "company": "MongoDB", 62 "headquarters": "New York", 63 "created": "2009-02-11T00:00:00.000+00:00", 64 "joined": "2023-08-23T00:00:00.000+00:00", 65 "salary": 13579 66 } 67 68 GET Employees 69 [ 70 { 71 "id": "661aac79cf04401110c03516", 72 "firstName": "Maxime", 73 "lastName": "Beugnet", 74 "company": "Google", 75 "headquarters": "Mountain View", 76 "created": "1998-09-04T00:00:00.000+00:00", 77 "joined": "2018-02-12T00:00:00.000+00:00", 78 "salary": 2468 79 }, 80 { 81 "id": "661aac79cf04401110c03518", 82 "firstName": "Tim", 83 "lastName": "Kelly", 84 "company": "MongoDB", 85 "headquarters": "New York", 86 "created": "2009-02-11T00:00:00.000+00:00", 87 "joined": "2023-08-23T00:00:00.000+00:00", 88 "salary": 13579 89 } 90 ]
Observe que o serviço de funcionário envia consultas ao serviço da empresa para recuperar os detalhes da empresa dos funcionários.
Isso confirma que o registro de serviço está fazendo seu trabalho corretamente porque a URL contém apenas uma referência ao microsserviço da empresa, não a seu IP e porta diretos.
1 private CompanyDTO getCompany(String company) { 2 String url = "http://company-service/api/company/name/"; 3 CompanyDTO companyDTO = restTemplate.getForObject(url + company, CompanyDTO.class); 4 if (companyDTO == null) { 5 throw new EntityNotFoundException("Company not found: ", company); 6 } 7 return companyDTO; 8 }
E voilà! Agora você tem uma arquitetura básica de microsserviço em execução que é fácil de usar para iniciar seu projeto.
Nessa arquitetura, pudemos integrar perfeitamente recursos adicionais para melhorar o desempenho e a capacidade de manutenção em
produção. O cache seria essencial, principalmente com um número potencialmente grande de funcionários dentro do mesmo
empresa, aliviando significativamente a carga no serviço da empresa.
The addition of a Spring Cloud Circuit Breaker could also
improve the resiliency in production and a Spring Cloud Sleuth would
help with distributed tracing and auto-configuration.
If you have questions, please head to our Developer Community website where the MongoDB engineers and the MongoDB community will help you build your next big idea with MongoDB.
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.