【问题标题】:Upgrade strategy for Pub/Sub subscription applicationPub/Sub 订阅应用的升级策略
【发布时间】:2021-07-11 02:11:27
【问题描述】:

我很好奇如何使用来自 Google Pub/Sub 的应用程序处理升级/重启情况。

例如,我对开发一个 Golang 应用程序特别感兴趣,该应用程序部署在运行多个 Pod 的 Kubernetes 中并使用来自 Google Pub/Sub 的消息。我关心的是如何确保在升级 pod 时不会丢失任何消息(或处理两次)。

我了解应用程序会从订阅中读取消息,然后必须确认它已收到该消息。我觉得在确认消息和 Pod 关闭升级之间可能存在竞争条件?

我知道使用 Dataflow 作业可以做类似的事情,因为您可以停止流式作业并发出信号以排出消息。

我认为必须有某种方式来优雅地处理这个问题,或者这真的是 Dataflow 更适合的情况吗?

【问题讨论】:

    标签: go kubernetes google-cloud-dataflow google-cloud-pubsub dataflow


    【解决方案1】:

    Kubernetes 使用 SIGTERM,等待 30 秒,然后 SIGKILL。这为您的应用程序在完全杀死它之前提供了适当的时间,如果 30 秒的默认值不够,您可以使用 terminationGracePeriodSeconds: 60 字段进行调整(链接 1)。

    然后您需要在 Golang 中添加逻辑以接收 SIGTERM 信号(链接 2)。

    最后,假设您的队列在这里是兔子(但其他队列将具有类似的功能),在收到 SIGTERM 时,您可以将逻辑写入 A)停止接收新消息,然后 B)(这是可选的,您可以只是让他们完成)为 pod 当前已确认但未完成的所有消息返回 NACK 和重新排队信号,将消息放回(链接 3 和 4)。

    如果您可以避免必须实现 NACK/Requeue,并且只需通过关闭队列侦听器并完成当前保留的剩余消息来处理 SIGTERM(并且说 30 或 60 秒就足够了),那就更简单了推荐。

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

    2. Golang catch signals

    3. Ack or Nack in rabbitMQ

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

    ** 编辑 **

    对于 google cloud pub/sub,您也可以发送 Nack。

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

    "Ack 表示消息处理成功。如果消息确认失败,消息将被重新传递。Nack 表示客户端不会或不能处理消息。Nack 将导致消息被重新传递比之前更快允许过期。”

    【讨论】:

    • 队列将是 Google Cloud Pub/Sub。谢谢!您的解释和文档链接很有意义(我必须完成所有工作才能完全理解)。我假设为 Google Cloud Pub/Sub 提供相同的通用模式适用。
    • 没问题,如果符合您的条件,请确保将其标记为答案。是的 google pub/sub support Nack on it's Message type pkg.go.dev/cloud.google.com/go/pubsub#Message "Ack 表示消息处理成功。如果消息确认失败,消息将被重新传递。Nack 表示客户端不会或不能处理消息。Nack 将导致消息重新传递的速度比允许过期时更快。"
    猜你喜欢
    • 2018-11-13
    • 1970-01-01
    • 2021-01-07
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    相关资源
    最近更新 更多