Жизнеспособность Kubernetes - Резервируйте потоки / память для определенной конечной точки с Spring Boot - PullRequest
0 голосов
/ 24 апреля 2018

Знаете ли вы (если это возможно), как зарезервировать потоки / память для конкретной конечной точки в микросервисе с пружинной загрузкой?

У меня есть один микросервис , который принимает HTTP-запросы через Spring MVC , и эти запросы вызывают HTTP-вызовы 3-й системе , которая иногда частично ухудшается, и он реагирует очень медленно. Я не могу сократить время ожидания, потому что некоторые вызовы очень медленные по своей природе.

У меня активирована конечная точка с пружинным приводом /health, и я использую ее как контейнер livenessProbe в кластере kubernetes . Иногда, когда 3-я система ухудшается, микросервис не отвечает на конечную точку /health, и kubernetes перезапускает мой сервис.

Это потому, что я использую RestTemplate для выполнения HTTP-вызовов , поэтому я постоянно создаю новые потоки, и у JVM возникают проблемы с памятью.

Я думал о некоторых решениях:

  1. Реализация конечной точки высокой доступности «/ health», резервных потоков или чего-то в этом роде.

  2. Использование асинхронного http-клиента.

  3. Реализация автоматического выключателя.

  4. Настройка пользовательских таймаутов для 3-й конечной точки, которую я использую.

  5. Создайте другой небольшой сервис (golang) и разверните его в том же модуле. Эта служба будет обрабатывать датчик живучести.

  6. Миграция / рефакторинг сервисов для небольших сервисов и, возможно, с другими фреймворками / языками, такими как Vert.x, go и т. Д.

Что вы думаете?

Спасибо заранее.

Ответы [ 3 ]

0 голосов
/ 27 января 2019

У меня есть прототип, который просто завершает эту проблему: SpringBoot позволяет заполнять 100% доступных потоков запросами общедоступной сети, оставляя конечную точку / health недоступной для балансировщика нагрузки AWS, который отключает службу в автономном режиме, считая ее вредной для здоровья , Существует различие между нездоровым и занятым ... и здоровье - это больше, чем просто запущенный процесс, прослушивание порта, поверхностная проверка и т. Д. - это должен быть "глубокий пинг", который проверяет, что он и все его зависимости работоспособны, чтобы дать уверенный ответ проверки здоровья.

Мой подход к решению проблемы состоит в том, чтобы создать два новых компонента с автоматической проводной связью: первый для настройки Jetty с фиксированным, настраиваемым максимальным числом потоков (убедитесь, что вашей JVM выделено достаточно памяти для соответствия), а второй для сохраняйте счетчик каждого запроса при его запуске и завершении, создавая исключение, которое сопоставляется с ответом HTTP 429 «СЛИШКОМ МНОГИЕ ЗАПРОСЫ», если число приближается к потолку, который является maxThreads - reserveThreads. Затем я могу установить для параметра ReserveThreads все, что захочу, и конечная точка / health не будет привязана счетчиком запросов, гарантируя, что он всегда сможет войти.

Я просто искал, чтобы выяснить, как другие решают эту проблему, и нашел ваш вопрос с той же проблемой, пока что не видел ничего более твердого.

Чтобы настроить параметры потока Jetty через файл свойств приложения: http://jdpgrailsdev.github.io/blog/2014/10/07/spring_boot_jetty_thread_pool.html

0 голосов
/ 27 января 2019

Конечная точка работоспособности привода очень удобна с пружинной загрузкой - почти слишком удобна в этом контексте, так как она выполняет более глубокие проверки работоспособности, чем вы обязательно хотите в тесте живучести.Для готовности вы хотите сделать более глубокие проверки, но не живость.Идея состоит в том, что, если Pod немного перегружен и не готов, то он будет снят с балансировки нагрузки и получит передышку.Но если он потерпит неудачу, он будет перезапущенТаким образом, вам нужны только минимальные проверки жизнеспособности ( Если Health Checks вызывает другие проверки работоспособности приложения ).Используя оба состояния привода, ваши занятые стручки не смогут получить передышку, когда их убьют первыми.И kubernetes периодически вызывает конечную точку http при выполнении обоих проб, что еще больше усугубляет проблему использования вашего потока (рассмотрите периоды на пробах).

В вашем случае вы можете определить команду живучести, а не зонд http - https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#define-a-liveness-command. Команда может просто проверить, запущен ли Java-процесс (так что это похоже на ваше предложение зондирования на основе go),

Во многих случаях использование исполнительного механизма для жизнеспособности было бы хорошо (подумайте о приложениях, которые сталкиваются с другим ограничением перед потоками, что было бы вашим случаем, если вы использовали асинхронную / неблокирующую работу с реактивным стеком).В вашем случае это может привести к проблемам - проверка привода на наличие зависимостей, таких как брокеры сообщений, может быть другой, когда вы получаете чрезмерный перезапуск (в этом случае при первом развертывании).

0 голосов
/ 24 апреля 2018

Похоже, ваша микросервисная служба все равно должна реагировать на проверки работоспособности /health, в то время как выдает результаты этой третьей службы, которая вызывает ее.

Я бы собрал асинхронный http-сервер с Vert.x-Web и попробовал протестировать, прежде чем изменять ваш хороший код.Создайте две конечные точки.Проверка /health и /slow вызов, который просто спит () около 5 минут, прежде чем ответить «привет».Разверните его в minikube или в вашем кластере и посмотрите, сможет ли он отвечать на проверки работоспособности во время сна другого http-запроса.

...