A arquitetura de microsserviços amadureceu significativamente em 2026. Depois de anos de “inferno de microsserviços”, onde as equipes criaram muitos serviços pequenos demais, a indústria convergiu para padrões que equilibram modularidade com simplicidade operacional. Este guia aborda quando usar microsserviços, como projetá-los e como lidar com as partes difíceis.
📋 Table of Contents
Monólito vs Microsserviços vs Monólito Modular
| Abordagem | Quando usar | Compensações |
|---|---|---|
| Monólito | Startup, <10 engenheiros, domínio desconhecido | Simples de construir/depurar, difícil de escalar de forma independente |
| Monólito Modular | Equipe em crescimento, contextos claros e delimitados, implantação única | O melhor dos dois mundos – modular, mas simples |
| Microsserviços | Organização grande, dimensionamento de equipe independente, tecnologia poliglota | Dimensionamento/implantação independente, sistema distribuído complexo |
Consenso de 2026: Comece com o monólito modular, extraia serviços quando tiver um motivo claro (escala, implantação independente, autonomia da equipe).
Contextos limitados e design de serviço
Bons microsserviços se alinham com contextos limitados de Domain-Driven Design (DDD):
E-commerce domain bounded contexts:
Order Service (owns orders, order items)
- Create order
- Update order status
- Get order history
Product Service (owns products, inventory)
- List products
- Update inventory
- Product search
User Service (owns users, auth)
- Register, login
- Profile management
- Authentication tokens
Payment Service (owns payment processing)
- Process payment
- Handle refunds
- Payment status
Notification Service (owns notifications)
- Email, SMS, push
- Triggered by events from other services
Each service:
- Has its own database (database-per-service pattern)
- Is owned by one team
- Can be deployed independently
- Communicates via API or events (not shared DB)
Padrões de comunicação
Síncrono (REST/gRPC)
# REST API call between services
import httpx
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=10))
async def get_user(user_id: int) -> dict:
async with httpx.AsyncClient(base_url="http://user-service:8001") as client:
r = await client.get(f"/api/users/{user_id}", timeout=5.0)
r.raise_for_status()
return r.json()
# Use circuit breaker for resilience
from circuitbreaker import circuit
@circuit(failure_threshold=5, recovery_timeout=30)
async def call_payment_service(order_id: int, amount: float):
async with httpx.AsyncClient(timeout=10) as client:
return await client.post("http://payment-service/payments",
json={"order_id": order_id, "amount": amount})
Assíncrono (orientado a eventos com Kafka)
from aiokafka import AIOKafkaProducer, AIOKafkaConsumer
import json
# Produce event when order is created
async def publish_order_created(order: dict):
producer = AIOKafkaProducer(bootstrap_servers="kafka:9092")
await producer.start()
try:
event = {
"event_type": "order.created",
"order_id": order["id"],
"user_id": order["user_id"],
"total": order["total"],
"timestamp": datetime.utcnow().isoformat()
}
await producer.send("orders", json.dumps(event).encode())
finally:
await producer.stop()
# Notification service consumes the event
async def consume_order_events():
consumer = AIOKafkaConsumer(
"orders",
bootstrap_servers="kafka:9092",
group_id="notification-service",
auto_offset_reset="earliest"
)
await consumer.start()
async for msg in consumer:
event = json.loads(msg.value)
if event["event_type"] == "order.created":
await send_confirmation_email(event["user_id"], event["order_id"])
Padrão de gateway de API
# Kong / nginx / custom gateway routes
# All clients talk to one entry point:
# POST /api/orders -> Order Service :8001
# GET /api/products -> Product Service :8002
# POST /api/auth -> User Service :8003
# Kong route configuration
routes:
- name: orders
paths: ["/api/orders"]
service: order-service
plugins:
- name: jwt # validate JWT
- name: rate-limiting # 100/min per user
- name: request-transformer
- name: products
paths: ["/api/products"]
service: product-service
plugins:
- name: response-ratelimiting
Rastreamento Distribuído
# OpenTelemetry — trace requests across services
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.trace.export import BatchSpanProcessor
# Setup (once at startup)
provider = TracerProvider()
jaeger_exporter = JaegerExporter(agent_host_name="jaeger", agent_port=6831)
provider.add_span_processor(BatchSpanProcessor(jaeger_exporter))
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)
# Instrument FastAPI
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
FastAPIInstrumentor.instrument_app(app) # auto-instruments all routes
HTTPXClientInstrumentor().instrument() # auto-instruments httpx calls
# Manual span for business logic
async def process_order(order_id: int):
with tracer.start_as_current_span("process_order") as span:
span.set_attribute("order.id", order_id)
order = await get_order(order_id)
span.set_attribute("order.total", order["total"])
await charge_payment(order)
await send_confirmation(order)
Integridade e resiliência do serviço
from fastapi import FastAPI
from datetime import datetime
app = FastAPI()
@app.get("/health")
async def health():
return {
"status": "healthy",
"timestamp": datetime.utcnow().isoformat(),
"version": "1.2.3",
"dependencies": {
"database": await check_db(),
"redis": await check_redis(),
}
}
@app.get("/ready")
async def readiness():
# Check if service can handle traffic
if not db_pool or not redis_client:
raise HTTPException(503, "Service not ready")
return {"status": "ready"}
# Kubernetes probes:
# livenessProbe: /health (if fails: restart container)
# readinessProbe: /ready (if fails: remove from load balancer)
Quando NÃO usar microsserviços
- Equipe pequena (menos de 5 engenheiros)– sobrecarga operacional mata velocidade
- Produto inicial— limites de domínio ainda não claros
- Aplicativo CRUD simples– sem justificativa de escala
- A latência da rede é crítica— chamadas entre serviços adicionam latência
- Sem maturidade DevOps— precisa de CI/CD, monitoramento e rastreamento primeiro
Os microsserviços em 2026 funcionam melhor quando: as equipes são grandes o suficiente para possuir serviços de forma independente, os contextos limitados são claros e você tem a infraestrutura DevOps para lidar com sistemas distribuídos. Comece com um monólito modular bem estruturado e extraia serviços somente quando você atingir pontos problemáticos claros.
🔗 Share this article
✍️ Leave a Comment