Sobes.tech
Middle+

Que padrões de microserviços conhece?

sobes.tech IA

Resposta da IA

  • Descoberta de Serviços: Permite que os serviços encontrem uns aos outros. Implementa-se através de um registo centralizado (por exemplo, ZooKeeper, Consul, etcd).
  • API Gateway: Ponto de entrada único para os clientes, que encaminha as requisições para os serviços correspondentes. Fornece autenticação, autorização e balanceamento de carga.
  • Circuit Breaker (Disjuntor): Previna falhas em cascata, desligando temporariamente as chamadas a serviços com problemas.
  • Bulkhead: Isola os recursos de diferentes serviços, evitando sua influência mútua em caso de falhas.
  • Saga: Gerencia transações distribuídas, garantindo a consistência dos dados entre vários serviços através de uma sequência de transações locais e ações compensatórias.
  • Event Sourcing (Armazenamento baseado em eventos): Regista todas as alterações de dados na forma de uma sequência de eventos, fornecendo um histórico completo de estados.
  • CQRS (Segregação de Responsabilidades de Comando e Consulta): Divide a lógica de leitura e escrita de dados em modelos diferentes, otimizando o desempenho para cada tipo de operação.
  • Base de Dados por Serviço: Cada serviço tem a sua própria base de dados para garantir independência e descentralização.
  • Strangler Fig: Substituição progressiva de uma aplicação monolítica por microserviços, redirecionando partes do tráfego.

Exemplo de implementação de Circuit Breaker em PHP (pseudocódigo):

<?php
// Classe Circuit Breaker
class CircuitBreaker
{
    private $threshold; // Limite de falhas
    private $timeout; // Tempo que o disjuntor permanece aberto
    private $failures = 0; // Número atual de falhas
    private $lastFailureTime = 0; // Hora da última falha
    private $state = 'CLOSED'; // Estado atual: CLOSED, OPEN, HALF_OPEN

    public function __construct(int $threshold, int $timeout)
    {
        $this->threshold = $threshold;
        $this->timeout = $timeout;
    }

    public function execute(callable $operation)
    {
        switch ($this->state) {
            case 'OPEN':
                if (time() - $this->lastFailureTime > $this->timeout) {
                    $this->state = 'HALF_OPEN';
                    // Tentativa de executar em estado HALF-OPEN
                    try {
                        $result = $operation();
                        $this->reset(); // Sucesso, reiniciar
                        return $result;
                    } catch (\Exception $e) {
                        $this->recordFailure(); // Falha em HALF-OPEN, voltar a OPEN
                        throw $e;
                    }
                } else {
                    throw new \Exception("Circuit breaker is open"); // Disjuntor aberto
                }
                break;
            case 'HALF_OPEN':
                // A lógica em HALF-OPEN já está acima
                break;
            case 'CLOSED':
            default:
                try {
                    $result = $operation();
                    $this->reset(); // Sucesso, reiniciar
                    return $result;
                } catch (\Exception $e) {
                    $this->recordFailure(); // Falha, incrementar contagem
                    throw $e;
                }
                break;
        }
    }

    private function recordFailure(): void
    {
        $this->failures++;
        $this->lastFailureTime = time();
        if ($this->failures >= $this->threshold) {
            $this->state = 'OPEN'; // Mudança para OPEN ao atingir o limite
        }
    }

    private function reset(): void
    {
        $this->failures = 0;
        $this->lastFailureTime = 0;
        $this->state = 'CLOSED'; // Mudança para CLOSED em sucesso
    }
}

// Uso
$breaker = new CircuitBreaker(3, 60); // Limite de 3 falhas, timeout de 60 segundos

try {
    $data = $breaker->execute(function() {
        // Código de chamada a serviço externo
        if (rand(0, 1) == 0) { // Simulação de falha
             throw new \Exception("Service unavailable");
        }
        return ['status' => 'ok'];
    });
    echo "Success: " . json_encode($data) . "\n";
} catch (\Exception $e) {
    echo "Failure: " . $e->getMessage() . "\n";
}