Microservices com Go: Guia Completo

Go é a linguagem perfeita para microservices: rápida, compila para binário único, e tem excelente suporte a concorrência.

Por que Go para Microservices?

  1. Binários standalone — Sem dependências externas, deploy simples
  2. Baixo consumo de memória — Containers leves
  3. Startup instantâneo — Ideal para escalar
  4. Concorrência nativa — Goroutines são perfeitas para I/O
  5. Biblioteca padrão robusta — HTTP, JSON, gRPC incluídos

Arquitetura Básica

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   Gateway   │────▶│  Service A  │────▶│  Database   │
│   (API)     │     │  (Users)    │     │  (Postgres) │
└─────────────┘     └─────────────┘     └─────────────┘
       │            ┌─────────────┐     ┌─────────────┐
       └───────────▶│  Service B  │────▶│    Redis    │
                    │  (Orders)   │     │   (Cache)   │
                    └─────────────┘     └─────────────┘

Estrutura de um Microservice

user-service/
├── cmd/
│   └── main.go           # Entrypoint
├── internal/
│   ├── handler/          # HTTP handlers
│   ├── service/          # Business logic
│   └── repository/       # Data access
├── pkg/
│   └── models/           # Shared models
├── Dockerfile
├── go.mod
└── go.sum

Service Básico

// cmd/main.go
package main

import (
    "log"
    "net/http"
    "os"
    
    "user-service/internal/handler"
)

func main() {
    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }
    
    mux := http.NewServeMux()
    
    // Health check - essencial para Kubernetes
    mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(http.StatusOK)
        w.Write([]byte("OK"))
    })
    
    // Rotas do serviço
    mux.HandleFunc("/users", handler.ListUsers)
    mux.HandleFunc("/users/", handler.GetUser)
    
    log.Printf("Server starting on port %s", port)
    log.Fatal(http.ListenAndServe(":"+port, mux))
}

Comunicação entre Services

HTTP/REST

// Chamando outro service
func GetUserFromService(userID string) (*User, error) {
    resp, err := http.Get("http://user-service:8080/users/" + userID)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    var user User
    if err := json.NewDecoder(resp.Body).Decode(&user); err != nil {
        return nil, err
    }
    return &user, nil
}

gRPC (Mais Performático)

// user.proto
syntax = "proto3";

service UserService {
    rpc GetUser(GetUserRequest) returns (User);
    rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
}

message User {
    string id = 1;
    string name = 2;
    string email = 3;
}
// Cliente gRPC
conn, err := grpc.Dial("user-service:50051", grpc.WithInsecure())
client := pb.NewUserServiceClient(conn)

user, err := client.GetUser(ctx, &pb.GetUserRequest{Id: "123"})

Docker

# Build stage
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /service ./cmd/main.go

# Runtime stage
FROM alpine:3.19
RUN apk --no-cache add ca-certificates
WORKDIR /app
COPY --from=builder /service .
EXPOSE 8080
CMD ["./service"]
# Build e run
docker build -t user-service .
docker run -p 8080:8080 user-service

Docker Compose (Desenvolvimento)

version: '3.8'

services:
  user-service:
    build: ./user-service
    ports:
      - "8081:8080"
    environment:
      - DATABASE_URL=postgres://postgres:pass@db:5432/users
    depends_on:
      - db

  order-service:
    build: ./order-service
    ports:
      - "8082:8080"
    environment:
      - USER_SERVICE_URL=http://user-service:8080
      - REDIS_URL=redis://redis:6379

  db:
    image: postgres:15
    environment:
      - POSTGRES_PASSWORD=pass

  redis:
    image: redis:7

Kubernetes

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: user-service:latest
        ports:
        - containerPort: 8080
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        resources:
          limits:
            memory: "128Mi"
            cpu: "100m"

Service

apiVersion: v1
kind: Service
metadata:
  name: user-service
spec:
  selector:
    app: user-service
  ports:
  - port: 8080
    targetPort: 8080
  type: ClusterIP

Padrões Essenciais

1. Circuit Breaker

import "github.com/sony/gobreaker"

cb := gobreaker.NewCircuitBreaker(gobreaker.Settings{
    Name:        "user-service",
    MaxRequests: 5,
    Interval:    10 * time.Second,
    Timeout:     30 * time.Second,
})

result, err := cb.Execute(func() (interface{}, error) {
    return http.Get("http://user-service/users")
})

2. Retry com Backoff

func fetchWithRetry(url string, maxRetries int) (*http.Response, error) {
    var resp *http.Response
    var err error
    
    for i := 0; i < maxRetries; i++ {
        resp, err = http.Get(url)
        if err == nil && resp.StatusCode == 200 {
            return resp, nil
        }
        
        backoff := time.Duration(math.Pow(2, float64(i))) * time.Second
        time.Sleep(backoff)
    }
    return nil, fmt.Errorf("max retries reached: %w", err)
}

3. Distributed Tracing

import "go.opentelemetry.io/otel"

tracer := otel.Tracer("user-service")
ctx, span := tracer.Start(ctx, "GetUser")
defer span.End()

Monitoramento

Métricas com Prometheus

import "github.com/prometheus/client_golang/prometheus"

var httpRequestsTotal = prometheus.NewCounterVec(
    prometheus.CounterOpts{
        Name: "http_requests_total",
        Help: "Total HTTP requests",
    },
    []string{"method", "endpoint", "status"},
)

func init() {
    prometheus.MustRegister(httpRequestsTotal)
}

Logs Estruturados

import "go.uber.org/zap"

logger, _ := zap.NewProduction()
logger.Info("user created",
    zap.String("user_id", user.ID),
    zap.String("email", user.Email),
)

Checklist de Produção

  • Health checks (/health, /ready)
  • Graceful shutdown
  • Configuração via environment variables
  • Logs estruturados (JSON)
  • Métricas Prometheus
  • Tracing distribuído
  • Circuit breakers
  • Rate limiting
  • Autenticação (JWT)
  • Testes de integração

Veja Também


Última atualização: Fevereiro 2026