Стратегия обновления приложения подписки Pub/Sub

Мне любопытно, как подойти к ситуации обновления/перезагрузки приложения, использующего сообщения из Google Pub/Sub.

Например, меня особенно интересует разработка приложения Golang, которое развертывается в Kubernetes с несколькими модулями и использует сообщения из Google Pub/Sub. Меня беспокоит, как я могу гарантировать, что сообщения не будут пропущены (или обработаны дважды) во время обновления модуля.

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

Я знаю, что сделать что-то подобное можно с заданием потока данных, поскольку вы можете остановить потоковое задание и дать ему сигнал на удаление сообщений.

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


person walshbm15    schedule 16.04.2021    source источник


Ответы (1)


Kubernetes использует SIGTERM, ждет 30 секунд, затем SIGKILL. Это дает вашему приложению соответствующее количество времени, прежде чем полностью его убить, что вы можете настроить, используя поле terminationGracePeriodSeconds: 60, если 30-секундного значения по умолчанию недостаточно (ссылка 1).

Затем вам нужно добавить логику в свой Golang для получения сигнала SIGTERM (ссылка 2).

Наконец, предполагая, что ваша очередь здесь кролика (но другие очереди будут иметь аналогичную функциональность), при получении SIGTERM вы можете написать логику A) Прекратить получение новых сообщений, а затем B) (это необязательно, вы можете просто позволить им закончить ) вернуть сигнал NACK и Requeue для всех сообщений, которые модуль в настоящее время подтвердил, но не завершил, помещая сообщения обратно (ссылки 3 и 4).

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

  1. https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-terminating-with-grace

  2. сигналы перехвата Golang

  3. Подтверждение или отказ в rabbitMQ

  4. https://www.rabbitmq.com/nack.html

** Редактировать **

Для публикации/подписки в облаке Google вы также можете отправить Nack.

https://pkg.go.dev/cloud.google.com/go/pubsub#Message

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

person Olivercodes    schedule 16.04.2021
comment
Очередь будет Google Cloud Pub/Sub. Благодарю вас! Ваше объяснение и ссылки на документацию имеют смысл (мне придется пройти через все это, чтобы полностью понять). Я предполагаю, что для подписки на Google Cloud Pub/Sub применяется тот же общий шаблон. - person walshbm15; 16.04.2021
comment
Нет проблем, пожалуйста, убедитесь, что вы отметили это как ответ, если оно соответствует вашим критериям. И да, google pub/sub поддерживает Nack в типе сообщения pkg.go. dev/cloud.google.com/go/pubsub#Message Подтверждение означает успешную обработку сообщения. Если подтверждение сообщения не удается, сообщение будет доставлено повторно. Nack указывает, что клиент не будет или не сможет обработать сообщение. Nack приведет к тому, что сообщение будет доставлено повторно быстрее, чем если бы срок его действия истек. - person Olivercodes; 16.04.2021