Guia do Projeto: Teste de Carga Visual (Java 21, Gatling, Grafana)
Método 1: Interface Web (start.spring.io)
- Acesse
https://start.spring.io - Configure o “Project Metadata” (Metadados do Projeto):
- Project:
Maven - Language:
Java - Spring Boot:
3.3.0(ou a versão estável mais recente que suporte Java 21) - Group:
com.example - Artifact:
servico-a(repita o processo comservico-bpara o outro módulo) - Name:
servico-a - Packaging:
Jar - Java:
21
- Project:
- Adicione as Dependências (clique em “ADD DEPENDENCIES…“):
Spring Web: (Para criar controladores REST)Spring Boot Actuator: (Para expor endpoints de gerenciamento, como/healthe/metrics)Prometheus: (Para formatar as métricas do Actuator para o Prometheus)
- Clique em “GENERATE”.
- Extraia o arquivo
.zipbaixado. Esta é a estrutura base do seu projeto.
Método 2: Linha de Comando (cURL)
Este método é ideal para automação e evita a interface gráfica.
Para o servico-a
Execute o seguinte comando no seu terminal. Ele baixa e descompacta o projeto.
# Baixa o .zip
curl https://start.spring.io/starter.zip \
-d type=maven-project \
-d language=java \
-d platformVersion=3.3.0 \
-d javaVersion=21 \
-d groupId=com.example \
-d artifactId=servico-a \
-d name=servico-a \
-d packaging=jar \
-d dependencies=web,actuator,prometheus \
-o servico-a.zip
# Descompacta
unzip servico-a.zip -d servico-a
rm servico-a.zipPara o servico-b
# Baixa o .zip
curl https://start.spring.io/starter.zip \
-d type=maven-project \
-d language=java \
-d platformVersion=3.3.0 \
-d javaVersion=21 \
-d groupId=com.example \
-d artifactId=servico-b \
-d name=servico-b \
-d packaging=jar \
-d dependencies=web,actuator,prometheus \
-o servico-b.zip
# Descompacta
unzip servico-b.zip -d servico-b
rm servico-b.zipMétodo 3: Dentro da IDE
IntelliJ IDEA (Ultimate Edition)
- Vá em
File>New>Project.... - Selecione
Spring Initializrno painel esquerdo. - Preencha os metadados:
- Name:
servico-a - Location: (Escolha o diretório pai)
- Language:
Java - Type:
Maven - Group:
com.example - Package name:
com.example.servicoa - Java Version:
SDK 21
- Name:
- Clique em
Next. - Na tela de dependências, selecione a versão do Spring Boot (ex: 3.3.0) e procure por:
- Web:
Spring Web - Ops:
Spring Boot Actuator - Observability:
Prometheus
- Web:
- Clique em
Create.
Visual Studio Code (com o “Spring Initializr Java Support” do Extension Pack for Java)
- Abra a paleta de comandos:
Ctrl+Shift+P(Windows/Linux) ouCmd+Shift+P(macOS). - Digite e selecione
Spring Initializr: Create a Maven Project.... - Selecione a versão do Spring Boot (ex:
3.3.0). - Selecione a linguagem:
Java. - Digite o Group ID:
com.example. - Digite o Artifact ID:
servico-a. - Selecione o tipo de empacotamento:
Jar. - Selecione a versão do Java:
21. - Procure e marque as dependências (pressione
Enterapós selecionar):Spring WebSpring Boot ActuatorPrometheus
- Escolha o local para gerar o projeto.
projeto-teste-carga/
├── .gitignore
├── docker-compose.yml <-- (Módulo 2: Orquestrador do Prometheus e Grafana)
├── prometheus.yml <-- (Módulo 2: Configuração de scrape do Prometheus)
|
├── servico-a/ <-- (Módulo 1: Spring Boot API de Pedidos)
│ ├── .mvn/
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml <-- (Dependências: Web, Actuator, Prometheus)
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── servicoa/
│ │ │ ├── PedidoController.java
│ │ │ └── ServicoAApplication.java
│ │ └── resources/
│ │ └── application.properties <-- (server.port=8081)
│ └── test/
│ └── ...
│
├── servico-b/ <-- (Módulo 1: Spring Boot API de Estoque)
│ ├── .mvn/
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml <-- (Dependências: Web, Actuator, Prometheus)
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── servicob/
│ │ │ ├── EstoqueController.java
│ │ │ └── ServicoBApplication.java
│ │ └── resources/
│ │ └── application.properties <-- (server.port=8082)
│ └── test/
│ └── ...
│
└── gatling-teste/ <-- (Módulo 3: Projeto de Teste de Carga)
├── .mvn/
├── mvnw
├── mvnw.cmd
├── pom.xml <-- (Dependências do Gatling, ex: gatling-maven-plugin)
└── src/
└── test/
├── resources/
│ └── gatling.conf <-- (Configurações opcionais do Gatling)
└── scala/
└── simulations/
└── CargaApiSimulation.scala <-- (Script do teste de carga)
Este guia detalha a criação de um ambiente para testes de carga visuais em tempo real, monitorando a latência e a taxa de transferência entre dois microsserviços Spring Boot 21.
1. Arquitetura Alvo
Utilizaremos uma arquitetura desacoplada para simular um cenário real. O Gatling ataca o servico-a, que por sua vez depende do servico-b. O Prometheus coleta métricas de ambos os serviços, e o Grafana exibe o dashboard.
flowchart TD subgraph "Ferramentas" Gatling("Gatling Engine") Grafana("Grafana Dashboard") Prometheus("Prometheus Scraper") end subgraph "Backend (Java 21 / Spring Boot)" SvcA["Serviço A: Pedidos <br> (Porta: 8081")] SvcB["Serviço B: Estoque <br> (Porta: 8082")] end Gatling -- 1. Carga HTTP (Usuários Virtuais) --> SvcA SvcA -- 2. Chamada REST interna --> SvcB Prometheus -- 3. Scrape (métricas) --> SvcA Prometheus -- 3. Scrape (métricas) --> SvcB Grafana -- 4. Query (PromQL) --> Prometheus
2. Módulo 1: Microsserviços Alvo (Spring Boot 21)
Criaremos dois serviços. Ambos devem ter as mesmas dependências do Micrometer para expor métricas ao Prometheus.
2.1. Dependências Maven (pom.xml)
Adicione a todos os serviços:
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>2.2. Configuração (application.properties)
Serviço B (Estoque): servico-b/src/main/resources/application.properties
# Porta do Serviço B
server.port=8082
# Nome da Aplicação (para métricas)
spring.application.name=servico-b
# Ativa Virtual Threads (Java 21+)
spring.threads.virtual.enabled=true
# Expor o endpoint /actuator/prometheus
management.endpoints.web.exposure.include=prometheus,health
management.endpoint.health.show-details=alwaysServiço A (Pedidos): servico-a/src/main/resources/application.properties
# Porta do Serviço A
server.port=8081
# Nome da Aplicação (para métricas)
spring.application.name=servico-a
# Ativa Virtual Threads (Java 21+)
spring.threads.virtual.enabled=true
# Expor o endpoint /actuator/prometheus
management.endpoints.web.exposure.include=prometheus,health
management.endpoint.health.show-details=always
# URL do serviço dependente
app.servico-b.url=http://localhost:80822.3. Código: Serviço B (Estoque)
Simula uma operação custosa (ex: consulta em banco de dados) com um atraso.
// servico-b/src/main/java/com/example/servicob/EstoqueController.java
package com.example.servicob;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
@RestController
public class EstoqueController {
@GetMapping("/estoque/{produtoId}")
public String getEstoque(@PathVariable String produtoId) {
try {
// Simula latência variável (ex: I/O de banco)
long delay = ThreadLocalRandom.current().nextLong(50, 200);
Thread.sleep(delay);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "Produto " + produtoId + ": 10 unidades";
}
}2.4. Código: Serviço A (Pedidos)
Chama o Serviço B usando RestTemplate (ou WebClient).
// servico-a/src/main/java/com/example/servicoa/PedidoController.java
package com.example.servicoa;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Random;
@RestController
public class PedidoController {
private final RestTemplate restTemplate;
private final String servicoBUrl;
public PedidoController(RestTemplateBuilder builder, @Value("${app.servico-b.url}") String servicoBUrl) {
this.restTemplate = builder.build();
this.servicoBUrl = servicoBUrl;
}
// Endpoint principal que será testado pelo Gatling
@GetMapping("/fazer-pedido")
public String fazerPedido() {
// Simula a busca por um produto aleatório
int produtoId = new Random().nextInt(1000);
// Chama o Serviço B
String estoqueInfo = restTemplate.getForObject(
servicoBUrl + "/estoque/" + produtoId,
String.class
);
return "Pedido criado. Info: " + estoqueInfo;
}
}
3. Módulo 2: Pilha de Observabilidade (Docker)
Usaremos Docker Compose para subir o Prometheus e o Grafana.
3.1. Configuração Prometheus (prometheus.yml)
Crie este arquivo na raiz do projeto. Ele instrui o Prometheus a “raspar” (scrape) as métricas dos endpoints /actuator/prometheus dos nossos serviços.
# prometheus.yml
global:
scrape_interval: 10s # Intervalo de coleta
scrape_configs:
# Coleta métricas do Serviço A (Pedidos)
- job_name: 'servico-a'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['host.docker.internal:8081'] # 'host.docker.internal' permite ao Docker acessar o host local
# Coleta métricas do Serviço B (Estoque)
- job_name: 'servico-b'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['host.docker.internal:8082']3.2. Docker Compose (docker-compose.yml)
Este arquivo orquestra a pilha de monitoramento.
# docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
# Permite que o container acesse os serviços no host
extra_hosts:
- "host.docker.internal:host-gateway"
grafana:
image: grafana/grafana-oss:latest
container_name: grafana
ports:
- "3000:3000"
depends_on:
- prometheus
environment:
# Define o usuário/senha padrão
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin4. Módulo 3: Teste de Carga (Gatling)
4.1. Estrutura do Projeto Gatling
Gatling usa Scala. A estrutura de pastas deve ser:
gatling-teste/
src/
test/
scala/
simulations/
CargaApiSimulation.scala <-- Nosso script de teste
4.2. Script de Simulação (Gatling)
Este script simula 100 usuários acessando o endpoint /fazer-pedido simultaneamente por 30 segundos.
// CargaApiSimulation.scala
package simulations
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class CargaApiSimulation extends Simulation {
// 1. Configuração do Protocolo HTTP
val httpProtocol = http
.baseUrl("http://localhost:8081") // URL base do Serviço A
.acceptHeader("application/json")
.userAgentHeader("Gatling Load Test")
// 2. Definição do Cenário
val scn = scenario("Cenário de Carga API Pedidos")
.exec(
http("Req: Fazer Pedido")
.get("/fazer-pedido")
.check(status.is(200)) // Verifica se a resposta é HTTP 200
)
// 3. Configuração da Carga (Injeção de Usuários)
setUp(
scn.inject(
// rampUsersPerSec(10).to(100).during(10.seconds), // Rampa de subida
// nothingFor(5.seconds), // Pausa
constantUsersPerSec(100).during(30.seconds) // Carga constante
)
).protocols(httpProtocol)
}
5. Módulo 4: Execução e Análise Visual
5.1. Passo 1: Iniciar os Serviços Java
Inicie ambos os serviços Spring Boot (em terminais separados ou pela IDE):
# Terminal 1: Iniciar Serviço B (Estoque)
cd servico-b/
./mvnw spring-boot:run# Terminal 2: Iniciar Serviço A (Pedidos)
cd servico-a/
./mvnw spring-boot:runVerificação: Acesse http://localhost:8081/actuator/prometheus e http://localhost:8082/actuator/prometheus. Você deve ver as métricas.
5.2. Passo 2: Iniciar a Pilha de Monitoramento
# Terminal 3: Iniciar Prometheus e Grafana
docker-compose upVerificação:
- Acesse
http://localhost:9090(Prometheus). - Acesse
http://localhost:3000(Grafana). Login:admin/admin.
5.3. Passo 3: Configurar o Grafana
- Acesse o Grafana (
http://localhost:3000). - Vá para Connections → Data sources → Add new data source.
- Selecione Prometheus.
- No campo “Prometheus server URL”, insira:
http://prometheus:9090(Grafana e Prometheus estão na mesma rede Docker). - Clique em Save & Test.
5.4. Passo 4: Criar o Dashboard de Análise
- Vá em Dashboards → New → New Dashboard.
- Clique em Add visualization.
- Selecione o Data Source Prometheus.
Painel 1: Taxa de Requisições (RPS) no Serviço A
Use a query PromQL para medir a taxa de requisições HTTP no servico-a.
// Mede a taxa de requisições por segundo (RPS) no endpoint /fazer-pedido
rate(http_server_requests_seconds_count{job="servico-a", uri="/fazer-pedido"}[1m])Painel 2: Latência P95 (Serviço A vs Serviço B)
Use esta query para ver a latência (percentil 95) das chamadas.
// Latência P95 do endpoint /fazer-pedido (visão do Svc A)
histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket{job="servico-a", uri="/fazer-pedido"}[1m])) by (le))
// Latência P95 da chamada interna (visão do Svc B)
histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket{job="servico-b", uri="/estoque/{produtoId}"}[1m])) by (le))Painel 3: Requisições com Erro (HTTP 5xx)
// Taxa de erros 5xx no Serviço A
rate(http_server_requests_seconds_count{job="servico-a", status=~"5.*"}[1m])5.5. Passo 5: Executar o Gatling e Observar
- Execute o Gatling (usando o Maven ou o script
gatling.sh).
# Terminal 4: Executar o Teste
cd gatling-teste/
# Se estiver usando o plugin Maven do Gatling
./mvnw gatling:test -Dgatling.simulationClass=simulations.CargaApiSimulation- Enquanto o Gatling executa, observe o dashboard do Grafana (
http://localhost:3000). Você verá os gráficos de RPS subindo, a latência aumentando e, eventualmente, erros (se o sistema não suportar a carga).