Восстановление / повторная попытка в случае неудачных или застрявших HTTP-запросов

#java #jakarta-ee #server #kubernetes #grizzly

#java #джакарта-ee #сервер #kubernetes #grizzly

Вопрос:

У меня есть сервер на базе Java, управляемый кластером kubernetes. Это распределенная среда, в которой номер экземпляра установлен равным 4 для обработки миллионов запросов в минуту.

Проблема, с которой я сталкиваюсь, заключается в том, что kubernetes пытается сбалансировать кластер и в процессе убивает модуль и переносит его на другой узел, но есть ожидающие HTTP-запросы GET и POST, которые теряются.

Какое решение от kubernetes или архитектурное решение, которое позволило бы мне повторить попытку, если запрос застрял / не удался?

Обновить:

У меня есть две конфигурации для службы kubernetes:

  1. LoadBalancer (поставляется с AWS ELB): для внешнего использования
  2. ClusterIP: для внутренней архитектуры на основе микросервисов

Комментарии:

1. запросы не повторяются клиентом?

2. нет, это специально.

Ответ №1:

Kubernetes предоставляет вам средства для изящной обработки завершений pod с помощью перехватчиков SIGTERM и предварительной остановки. Об этом есть несколько статей, например, Изящное завершение работы модулей с Kubernetes. В вашем Java-приложении вы должны прослушать SIGTERM и корректно завершить работу сервера (в большинстве http-фреймворков встроена эта функция «завершения работы»).

Проблема, с которой я сталкиваюсь, заключается в том, что kubernetes пытается сбалансировать кластер и в процессе убивает модуль и переносит его на другой узел

Теперь это звучит немного подозрительно — обычно K8s удаляет и перепланирует модули на разных узлах только при определенных обстоятельствах, например, когда у узла заканчиваются ресурсы для обслуживания модуля. Если ваши модули часто переносятся, это обычно признак того, что происходит что-то еще, поэтому вам, вероятно, следует определить основную причину (если в спецификации вашего развертывания установлены ограничения ресурсов, убедитесь, что ваш сервисный контейнер не превышает их — это обычная проблема с контейнерами JVM).

Наконец, повторные попытки HTTP по своей сути небезопасны для неидемпотентных запросов (POST / PUT), поэтому вы не можете просто повторить любой неудачный запрос, не зная логических последствий. В любом случае, повторные попытки обычно происходят на стороне клиента, а не сервера, поэтому это не тот флаг, который вы можете установить в K8s, чтобы включить их.

Ответ №2:

Service mesh решает конкретную проблему, с которой вы столкнулись.

Доступны различные сервисные сетки. Общими особенностями service mesh являются

  • Балансировка нагрузки
  • Детализированные политики трафика
  • Обнаружение службы
  • Мониторинг сервиса
  • Отслеживание
  • Маршрутизация

Сервисная сетка

  • Istio
  • Посланник
  • Linkerd

Ссылка:https://linkerd.io/2/features/retries-and-timeouts