Kubernetes удачно завершает работу с TCP-соединениями (Spring boot) - PullRequest
1 голос
/ 18 февраля 2020

Я размещаю свои сервисы в облаке azure, иногда я получаю «BackendConnectionFailure» без какой-либо видимой причины, после исследования я обнаружил, что в большинстве случаев корреляция между этим исключением и автомасштабированием (уменьшением масштаба) почти в одну секунду почти одинакова .

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

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

Редактировать 1:

Архитектура просто такая:

Клиент -> Брандмауэр (azure) -> API (azure APIM) -> Микросервисы (весенняя загрузка) -> Бэкэнд (сторонний) или azure RDB в зависимости от службы

I думаю, что исключение исходит от APIM, я нашел два шаблона для этого исключения:

  1. Message The underlying connection was closed: The connection was closed unexpectedly. Exception type BackendConnectionFailure Failed method forward-request

Response time 10.0 s

Message The underlying connection was closed: A connection that was expected to be kept alive was closed by the server. Exception type BackendConnectionFailure Failed method forward-request

Response time 3.6 ms

Ответы [ 3 ]

0 голосов
/ 18 февраля 2020

Когда ваши приложения получают SIGTERM (от завершения Pod), они должны сначала прекратить сообщать, что они готовы (ошибка readinessProbe), но по-прежнему обслуживать запросы, поступающие от клиентов. Через некоторое время (в зависимости от настроек readinessProbe) вы можете закрыть приложение.

Для Spring Boot есть небольшая библиотека, которая делает именно это: springboot-graceful-shutdown

0 голосов
/ 19 февраля 2020

Spring Boot не выполняет корректное завершение по умолчанию.

Приложение Spring Boot и его контейнер приложения (не контейнер linux) контролируют то, что происходит с существующими соединениями в течение льготного периода завершения. Используемые протоколы и то, как клиент реагирует на «закрытие», также должны сыграть свою роль.

Если вы дойдете до конца льготного периода, тогда все будет полностью сброшено.

Kubernetes

Когда модуль удаляется в k8s , удаление конечной точки модуля из служб запускается одновременно с сигналом SIGTERM для контейнера (ов). ).

На этом этапе узлы кластера будут перенастроены для удаления любых правил, направляющих new traffi c к модулю Pod. Все существующие TCP-соединения с Pod / контейнерами будут отслеживаться до тех пор, пока они не будут закрыты (клиентом, сервером или сетевым стеком).

Для служб HTTP Keep Alive или HTTP / 2 клиент продолжит работу одна и та же конечная точка Pod, пока не будет сказано закрыть соединение (или оно принудительно сброшено)

App

Основные правила c: на SIGTERM приложение должно:

  • Разрешить выполнение транзакций для завершения
  • Требуется ли очистка любого приложения
  • Прекратить прием новых подключений, на случай, если
  • Закройте все неактивные подключения, которые могут (сохранить в силе запросы, веб-сокеты)

Некоторые обстоятельства, которые вы, возможно, не сможете обработать (зависит от клиента)

  • Поддержание соединения, которое не завершает запрос в льготный период, не может получить заголовок Connection: close. Для этого потребуется закрыть уровень TCP FIN.
  • Медленный клиент с длительной передачей, с односторонней передачей HTTP, их придется ждать или принудительно закрывать.

Хотя клиенты keepalive должны соблюдать закрытие TCP FIN, каждый клиент реагирует по-своему. Microsoft APIM может быть чувствительным и приводить к ошибке, даже при том, что не было никакого реального воздействия на мир. Лучше всего загрузить свои настройки во время масштабирования, чтобы увидеть, есть ли реальный эффект.

Для получения дополнительной информации о пружинной загрузке см .:

https://github.com/spring-projects/spring-boot/issues/4657 https://github.com/corentin59/spring-boot-graceful-shutdown https://github.com/SchweizerischeBundesbahnen/springboot-graceful-shutdown

0 голосов
/ 18 февраля 2020

При необходимости вы можете использовать сон до остановки. Несмотря на то, что модуль удален из конечных точек службы немедленно, все еще требуется время (10-100 мс) для отправки обновления конечной точки на каждый узел и для них, чтобы обновить iptables.

...