Middle+
¿Qué patrones de microservicios conoces?
sobes.tech AI
Respuesta de la IA
- Descubrimiento de servicios: Permite que los servicios se encuentren entre sí. Se implementa a través de un registro centralizado (por ejemplo, ZooKeeper, Consul, etcd).
- API Gateway: Punto de entrada único para los clientes, que enruta las solicitudes a los servicios correspondientes. Proporciona autenticación, autorización y balanceo de carga.
- Circuit Breaker (Interruptor automático): Previene fallos en cascada, desconectando temporalmente las llamadas a servicios defectuosos.
- Bulkhead: Aísla los recursos de diferentes servicios, evitando su influencia mutua en caso de fallos.
- Saga: Gestiona transacciones distribuidas, asegurando la coherencia de los datos entre varios servicios mediante una secuencia de transacciones locales y acciones compensatorias.
- Event Sourcing (Almacenamiento orientado a eventos): Guarda todos los cambios de datos en forma de secuencia de eventos, proporcionando un historial completo de estados.
- CQRS (Segregación de responsabilidades de comando y consulta): Divide la lógica de lectura y escritura de datos en modelos diferentes, optimizando el rendimiento para cada tipo de operación.
- Base de datos por servicio: A cada servicio se le asigna su propia base de datos para garantizar independencia y descentralización.
- Strangler Fig: Sustitución progresiva de una aplicación monolítica por microservicios, redirigiendo partes del tráfico.
Ejemplo de implementación de Circuit Breaker en PHP (pseudocódigo):
<?php
// Clase Circuit Breaker
class CircuitBreaker
{
private $threshold; // Umbral de fallos
private $timeout; // Tiempo que el interruptor permanece abierto
private $failures = 0; // Número actual de fallos
private $lastFailureTime = 0; // Tiempo del último fallo
private $state = 'CLOSED'; // Estado actual: 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';
// Intento de ejecutar en estado HALF-OPEN
try {
$result = $operation();
$this->reset(); // Éxito, reiniciar
return $result;
} catch (\Exception $e) {
$this->recordFailure(); // Fallo en HALF-OPEN, volver a OPEN
throw $e;
}
} else {
throw new \Exception("Circuit breaker is open"); // Interruptor abierto
}
break;
case 'HALF_OPEN':
// La lógica en HALF_OPEN ya está arriba
break;
case 'CLOSED':
default:
try {
$result = $operation();
$this->reset(); // Éxito, reiniciar
return $result;
} catch (\Exception $e) {
$this->recordFailure(); // Fallo, incrementar contador
throw $e;
}
break;
}
}
private function recordFailure(): void
{
$this->failures++;
$this->lastFailureTime = time();
if ($this->failures >= $this->threshold) {
$this->state = 'OPEN'; // Cambio a OPEN al alcanzar el umbral
}
}
private function reset(): void
{
$this->failures = 0;
$this->lastFailureTime = 0;
$this->state = 'CLOSED'; // Cambio a CLOSED en éxito
}
}
// Uso
$breaker = new CircuitBreaker(3, 60); // Umbral 3 fallos, timeout 60 segundos
try {
$data = $breaker->execute(function() {
// Código para llamar a un servicio externo
if (rand(0, 1) == 0) { // Simulación de fallo
throw new \Exception("Service unavailable");
}
return ['status' => 'ok'];
});
echo "Success: " . json_encode($data) . "\n";
} catch (\Exception $e) {
echo "Failure: " . $e->getMessage() . "\n";
}