tgoop.com/java_fillthegaps/594
Last Update:
Паттерн Bulkhead
- паттерн для повышения надёжности. Сегодня расскажу несколько способов, как его реализовать и подсвечу неочевидный момент при работе с паттернами в целом.
В чем суть?
Название Bulkhead пришло из кораблестроения. Корабль делится на независимые отсеки. Если в одном отсеке появится дыра, водой заполнится только он. Остальные части будут в порядке, и корабль хоть как-то продолжит плыть.
Главная идея паттерна - разграничить ресурсы, чтобы ошибка в одном компоненте не повлияла на работу других.
Реализовать паттерн можно на трёх уровнях:
▫️ Docker контейнер
▫️ Приложение (jar-файл)
▫️ Внутри сервиса
На каждом уровне свои ресурсы и возможности. Пойдем по порядку:
✨Docker контейнер✨
и остальные инструменты виртуализации дают контроль над главными ресурсами - памятью и потреблением CPU:
docker run -dit --cpus="2" --memory="512m" imagename
Если в одном сервисе произойдет беда, остальные будут работать как ни в чем ни бывало.
✨Приложение✨
Здесь возможности поменьше. JVM не контролирует загруженность процессора, этим занимается ОС. Зато тщательно считает свои обьекты и занятую память, мы можем задать рамки флажками типа -Xmx.
✨Внутри сервиса✨
В java коде нельзя явно ограничить количество памяти и нагрузку на цпу. Но в нашей власти повлиять на количество потоков, как следствие - ограничить число запросов для разных эндпойнтов.
Для этого Spring предлагает аннотацию @Bulkhead:
@GetMapping(value = "/post/{id}")
@Bulkhead(name = "getPost", fallbackMethod = "postFallback")
public Post getPost(@PathVariable int id) {…}
В проперти maxThreadPoolSize настраиваем максимальное число потоков.
Ограничение запросов иногда полезно, но это ненадежная реализация паттерна Bulkhead. Нет нужного уровня изоляции, у приложения все ещё общая память. Тяжёлый SQL запрос из одного потока может выгрузить половину БД и запросто положит сервис с OutOfMemoryError.
И ещё, обратите внимание на важный момент!
Допустим, мы почитали паттерны отказоустойчивости микросервисов, нашли среди них Bulkhead и решили, что нам надо. Гуглим bulkhead example, и вся поисковая выдача будет забита спринговыми аннотациями.
Как мы уже обсудили, это не самый надёжный способ. Самое верное - ограничить память и CPU в настройках Docker/виртуалки/Kubernetes/etc. Беда в том, что слово Bulkhead в этих инструментах не используется, там limits и constraints. Поэтому такое решение может легко пройти мимо.
При работе с паттернами нужно четко понимать, какая проблема решается и за счёт чего. Не хватать первое же решение с нужным словом, смотреть не только на форму, но и на содержание🤌
BY Java: fill the gaps
Share with your friend now:
tgoop.com/java_fillthegaps/594