Получить доступ

Внешний платёжный провайдер начал отвечать за 30 секунд вместо 200 миллисекунд. Через минуту сервис перестал отвечать вообще, включая страницы, не связанные с оплатой. Что произошло?

MiddleНадёжность и идемпотентность
Ещё спрашивают так:
  • Что такое каскадный отказ?
  • Как медленная зависимость роняет весь сервис?
Коротко

Медленная зависимость выедает общий пул потоков и соединений: каждый запрос держит поток в 150 раз дольше, и сервис перестаёт обслуживать даже страницы без оплаты.

  • Таймаут на внешний вызов по наблюдаемому верхнему перцентилю
  • Bulkhead — отдельный пул для каждой внешней зависимости
  • Circuit breaker — перестать звать упавшую зависимость

А ещё Закон Литтла: время ×150 при том же потоке — потоков нужно ×150

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Это классическое начало каскадного отказа. Пока провайдер отвечал за двести миллисекунд, каждый поток освобождался быстро и пула хватало; при тридцати секундах каждый запрос удерживает поток в полтораста раз дольше, поэтому пул исчерпывается за считанные секунды. Дальше запросы, не имеющие к оплате никакого отношения, встают в очередь за свободным потоком — и сервис выглядит полностью недоступным. Правильный набор мер известен: таймаут на каждый внешний вызов, выставленный по наблюдаемому верхнему перцентилю с запасом, а не в тридцать секунд; изоляция ресурсов, то есть отдельный пул или ограничение числа одновременных вызовов именно к этой зависимости, чтобы её деградация не касалась остального; предохранитель, который после порога ошибок начинает отклонять вызовы мгновенно и даёт провайдеру восстановиться; и продуманная деградация — принять заказ и подтвердить оплату позже вместо ожидания. Ответ про нехватку памяти неверен, а тезис «сервис не может быть быстрее зависимости» верен лишь для операций, которые эту зависимость используют, — и именно чтобы он не распространялся на всё остальное, применяют изоляцию.

Что хотят услышать

  • Механизм исчерпания общего пула.
  • Таймаут, изоляция ресурсов, предохранитель.
  • Почему страдают несвязанные запросы.

Частые ошибки

  • Ставить один общий пул на все внешние вызовы.
  • Задавать таймаут «с запасом» в десятки секунд, что равносильно его отсутствию.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Потоки и соединения общего пула заняты ожиданием ответа провайдера, поэтому свободных для остальных запросов не осталось: нужны таймаут по верхнему перцентилю, отдельный пул для этой зависимости и предохранитель
  • ✗Провайдер начал возвращать ошибки, и сервис перегрузился их обработкой
  • ✗Не хватило памяти под ответы провайдера — нужно увеличить heap
  • ✗Так и должно быть: сервис не может работать быстрее самой медленной зависимости

Что спросят дальше

  • Как выбрать значение таймаута для конкретной зависимости?
  • Чем ограничение конкурентности лучше выделенного пула потоков?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем