Microsserviços em Java: arquitetura e prática do A ao Z
\n\nA arquitetura de microsserviços (MSA) tornou-se o padrão de facto para a construção de aplicações modernas e escaláveis. Ao contrário do monolito, onde todo o código é um único processo grande, os microsserviços dividem o sistema em serviços pequenos e implantados de forma independente. Neste artigo, vamos analisar como projetar e implementar microsserviços em Java usando tecnologias populares: Spring Boot, Docker, Kafka e Spring Cloud. Você obterá receitas prontas e exemplos de código.
\n\n1. Fundamentos da arquitetura de microsserviços em Java
\n\nAntes de escrever código, é importante entender os princípios-chave da MSA:
\n- \n
- Responsabilidade Única (Single Responsibility) — cada serviço é responsável por uma função de negócio (ex: Serviço de Pedidos, Serviço de Usuários). \n
- Implantação Independente — você pode atualizar um serviço sem reiniciar todo o sistema. \n
- Gerenciamento Descentralizado de Dados — cada serviço tem seu próprio banco de dados (Database per Service). \n
- Baixo Acoplamento — os serviços se comunicam através de protocolos leves (REST, gRPC, filas de mensagens). \n
Para Java, o principal framework é o Spring Boot em conjunto com o Spring Cloud (para service discovery, configuração, API gateways). Vamos considerar um exemplo mínimo de microsserviço.
\n\nExemplo: um serviço REST simples com Spring Boot
\n// pom.xml (fragmento de dependências)\n<dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-web</artifactId>\n</dependency>\n\n// UserServiceApplication.java\n@SpringBootApplication\npublic class UserServiceApplication {\n public static void main(String[] args) {\n SpringApplication.run(UserServiceApplication.class, args);\n }\n}\n\n// UserController.java\n@RestController\n@RequestMapping("/api/users")\npublic class UserController {\n\n @GetMapping("/{id}")\n public ResponseEntity<String> getUser(@PathVariable Long id) {\n // Em um projeto real, aqui haveria uma chamada ao repositório\n return ResponseEntity.ok("User with id: " + id);\n }\n}\n\nEste microsserviço escuta na porta 8080 e responde a requisições GET. Para iniciar um segundo serviço (ex: Serviço de Pedidos), basta criar outro projeto Spring Boot com uma porta diferente (server.port=8081).
\n\n2. Prática: Docker, Kafka e comunicação entre serviços
\n\nEm um sistema real, os microsserviços não podem se comunicar diretamente via HTTP sem orquestração. Duas abordagens são usadas: síncrona (REST/Feign) e assíncrona (Message Broker).
\n\n2.1. Containerização com Docker
\nCada microsserviço é empacotado em uma imagem Docker. Exemplo de Dockerfile para um serviço Java:
\nFROM openjdk:17-jdk-slim\nCOPY target/user-service-0.0.1-SNAPSHOT.jar app.jar\nEXPOSE 8080\nENTRYPOINT ["java", "-jar", "/app.jar"]\nEm seguida, use docker-compose.yml para iniciar todos os serviços de uma vez:
version: '3.8'\nservices:\n user-service:\n build: ./user-service\n ports:\n - "8080:8080"\n order-service:\n build: ./order-service\n ports:\n - "8081:8081"\n postgres:\n image: postgres:15\n environment:\n POSTGRES_DB: mydb\n POSTGRES_USER: user\n POSTGRES_PASSWORD: pass\n\n2.2. Comunicação assíncrona via Apache Kafka
\nQuando um serviço precisa notificar outros serviços sobre um evento (ex: "pedido criado"), é melhor usar Kafka. Isso desacopla os serviços e aumenta a tolerância a falhas.
\n\nExemplo de produtor (Order Service envia o evento):
\n// KafkaProducerConfig.java\n@Configuration\npublic class KafkaProducerConfig {\n @Bean\n public ProducerFactory<String, String> producerFactory() {\n Map<String, Object> props = new Ha