Назад к вопросам
Middle+
143
questionbank
Какие микросервисные паттерны вы знаете?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
- Service Discovery: Позволяет сервисам находить друг друга. Реализуется через централизованный реестр (например, ZooKeeper, Consul, etcd).
- API Gateway: Единая точка входа для клиентов, маршрутизирующая запросы к соответствующим сервисам. Обеспечивает аутентификацию, авторизацию, балансировку нагрузки.
- Circuit Breaker (Автоматический выключатель): Предотвращает каскадные сбои, временно отключая вызовы к неисправным сервисам.
- Bulkhead: Изолирует ресурсы разных сервисов, предотвращая их взаимное влияние при сбоях.
- Saga: Управляет распределенными транзакциями, обеспечивая согласованность данных между несколькими сервисами с помощью последовательности локальных транзакций и компенсирующих действий.
- Event Sourcing (Событийно-ориентированное хранилище): Хранит все изменения данных в виде последовательности событий, обеспечивая полную историю состояний.
- CQRS (Command Query Responsibility Segregation): Разделяет логику чтения и записи данных на разные модели, оптимизируя производительность для каждого типа операций.
- Database per Service (База данных на сервис): Каждому сервису выделяется собственная база данных для обеспечения независимости и децентрализации.
- Strangler Fig: Постепенное замещение монолитного приложения микросервисами, перенаправляя части трафика.
Пример реализации Circuit Breaker в PHP (псевдокод):
<?php
// Класс Circuit Breaker
class CircuitBreaker
{
private $threshold; // Порог количества сбоев
private $timeout; // Время, в течение которого выключатель остается открытым
private $failures = 0; // Текущее количество сбоев
private $lastFailureTime = 0; // Время последнего сбоя
private $state = 'CLOSED'; // Текущее состояние: 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';
// Попытка выполнить операцию в HALF-OPEN состоянии
try {
$result = $operation();
$this->reset(); // Успех, сброс
return $result;
} catch (\Exception $e) {
$this->recordFailure(); // Сбой в HALF-OPEN, возврат в OPEN
throw $e;
}
} else {
throw new \Exception("Circuit breaker is open"); // Выключатель открыт
}
break;
case 'HALF_OPEN':
// Логика обработки в HALF_OPEN уже есть выше
break;
case 'CLOSED':
default:
try {
$result = $operation();
$this->reset(); // Успех, сброс
return $result;
} catch (\Exception $e) {
$this->recordFailure(); // Сбой, увеличение счетчика
throw $e;
}
break;
}
}
private function recordFailure(): void
{
$this->failures++;
$this->lastFailureTime = time();
if ($this->failures >= $this->threshold) {
$this->state = 'OPEN'; // Переход в OPEN при достижении порога
}
}
private function reset(): void
{
$this->failures = 0;
$this->lastFailureTime = 0;
$this->state = 'CLOSED'; // Переход в CLOSED при успехе
}
}
// Использование
$breaker = new CircuitBreaker(3, 60); // Порог 3 сбоя, таймаут 60 секунд
try {
$data = $breaker->execute(function() {
// Код вызова внешнего сервиса
if (rand(0, 1) == 0) { // Имитация сбоя
throw new \Exception("Service unavailable");
}
return ['status' => 'ok'];
});
echo "Success: " . json_encode($data) . "\n";
} catch (\Exception $e) {
echo "Failure: " . $e->getMessage() . "\n";
}