Вопрос 18 · Раздел 17

Что такое паттерн Bulkhead

Structured Java interview answer with junior, middle, and senior-level explanation.

Версии по языкам: English Russian Ukrainian

🟢 Junior Level

Bulkhead (переборка) — паттерн, который изолирует ресурсы для разных операций, чтобы сбой в одной не влиял на другие.

Аналогия из жизни: корабль разделён на отсеки (bulkheads). Если один отсек затонет — корабль не утонет целиком.

Без Bulkhead:
Thread Pool [====================]
Все вызовы делят один пул → один медленный сервис занимает все потоки

С Bulkhead:
Thread Pool A [========] → Сервис A
Thread Pool B [========] → Сервис B
Thread Pool C [========] → Сервис C
Сервис A медленный → влияет только на Pool A

Когда НЕ использовать Bulkhead

  • Один вызов ко всему сервису — если сервис атомарный, разделение потоков бессмысленно
  • Мало потоков — overhead на управление пулами больше выгоды
  • Полностью асинхронная система — backpressure решает проблему иначе

🟡 Middle Level

Реализация с Resilience4j

BulkheadConfig config = BulkheadConfig.custom()
    .maxConcurrentCalls(10)  // максимум 10 одновременных вызовов
    .maxWaitDuration(Duration.ofSeconds(1))  // ждать 1 сек если full
    .build();

// maxWaitDuration — сколько поток ждёт, если bulkhead полон.
// По истечении — BulkheadFullException (не timeout!).
// ThreadPool bulkhead ставит в очередь, Semaphore — блокирует или бросает.

Bulkhead bulkhead = Bulkhead.of("backend", config);

Supplier<String> decorated = Bulkhead.decorateSupplier(bulkhead, 
    () -> backendService.call());

Типы Bulkhead

1. Semaphore:

Лимит одновременных вызовов
Лёгкий, no thread overhead

2. Thread Pool:

Отдельный пул потоков для каждого сервиса
Изоляция на уровне потоков

Типичные ошибки

  1. Слишком маленький лимит:
    maxConcurrentCalls = 2 → большинство запросов rejected
    Нужно настроить по метрикам
    

🔴 Senior Level

Архитектурные Trade-offs

Thread Pool Semaphore
Полная изоляция (свои потоки), но overhead на каждый поток Легче (меньше памяти), но нет изоляции потоков — все в одном thread pool
Thread isolation Нет thread isolation
Больше ресурсов Меньше overhead

Production Experience

resilience4j:
  bulkhead:
    instances:
      userService:
        maxConcurrentCalls: 20
      paymentService:
        maxConcurrentCalls: 10
      searchService:
        maxConcurrentCalls: 30

Best Practices

✅ Отдельный bulkhead на каждый внешний сервис
✅ Лимиты по метрикам
✅ Мониторьте rejection rate
✅ Комбинируйте с Circuit Breaker

❌ Один bulkhead на всё
❌ Слишком маленькие лимиты
❌ Без мониторинга

🎯 Шпаргалка для интервью

Обязательно знать:

  • Bulkhead изолирует ресурсы (thread pool) для разных операций
  • Аналогия: отсеки корабля — один затонул, корабль не утонул
  • Два типа: Thread Pool (полная изоляция, overhead) и Semaphore (легче, нет thread isolation)
  • Без Bulkhead один медленный сервис забирает все потоки общего пула
  • maxConcurrentCalls настраивается по метрикам для каждого сервиса отдельно
  • Комбинируйте с Circuit Breaker для максимальной защиты
  • НЕ нужен для одного атомарного вызова, малого числа потоков, полностью асинхронных систем

Частые уточняющие вопросы:

  • Thread Pool vs Semaphore? Thread Pool = свои потоки, полная изоляция, больше overhead. Semaphore = блокирует или бросает, легче.
  • Как настроить maxConcurrentCalls? По метрикам: наблюдайте нормальную нагрузку, поставьте с запасом.
  • Что будет при слишком маленьком лимите? Большинство запросов rejected — BulkheadFullException.
  • Зачем отдельный bulkhead на каждый сервис? Чтобы медленный Payment Service не влиял на User Service.

Красные флаги (НЕ говорить):

  • “Bulkhead = Circuit Breaker” — нет, Bulkhead изолирует ресурсы, CB блокирует вызовы
  • “Один bulkhead на всё достаточно” — нет, тогда нет изоляции
  • “maxConcurrentCalls = 2 — хорошая защита” — нет, большинство запросов будут rejected
  • “Semaphore не нужен, только Thread Pool” — Semaphore легче, подходит для многих случаев

Связанные темы:

  • [[17. Как обеспечить отказоустойчивость микросервисов]]
  • [[5. Что такое паттерн Circuit Breaker]]
  • [[6. Как работает Circuit Breaker и какие у него состояния]]
  • [[19. Что такое паттерн Retry и как его правильно использовать]]
  • [[15. Как организовать коммуникацию между микросервисами]]