我们正在与PubSub合作,将多个系统相互集成。一些系统可能将数据作为JSON推送到PubSub,而其他系统则可以提取该数据并使用它。 (注意:由于接收应用程序的其他限制,我们必须从PubSub拉出而不是推送到应用程序。)每个拉取应用程序都会拥有自己的每个主题的订阅者。
我注意到,如果触发过于频繁,则PubSub拉取不会获取当前队列中的所有数据。该问题最初发生在带有相应库的Java Spring App中,但是云控制台中的gcloud命令表现出相同的行为,因此我将仅使用该示例。我删除了ack-id和边框以使其适合此窗口。请注意,我如何不使用'--auto-ack'标志,因此队列应保持不变,没有其他系统从该订户中拉出。
首次拉动(完整内容): max_binnewies @ cloudshell:〜$ gcloud pubsub订阅拉testSubscriber --limit = 100
│ DATA │ MESSAGE_ID │
│ 4 - FOUR │ 189640873208084 │
│ 5 - FIVE │ 189636274179799 │
│ 2 - TWO │ 189638666587304 │
│ 3 - THREE │ 189627470480903 │
│ 1 - ONE │ 189639207684195 │
第二次拉动(仅一次): max_binnewies @ cloudshell:〜$ gcloud pubsub订阅拉testSubscriber --limit = 100
│ DATA │ MESSAGE_ID │
│ 1 - ONE │ 189639207684195 │
三次拉(两个不同): max_binnewies @ cloudshell:〜$ gcloud pubsub订阅拉testSubscriber --limit = 100
│ DATA │ MESSAGE_ID │
│ 4 - FOUR │ 189640873208084 │
│ 5 - FIVE │ 189636274179799 │
第四次拉拔(再次是第一次拉拔): max_binnewies @ cloudshell:〜$ gcloud pubsub订阅拉testSubscriber --limit = 100
│ DATA │ MESSAGE_ID │
│ 1 - ONE │ 189639207684195 │
这种行为使我感到困惑。那是正常的PubSub行为还是我做错了什么?我唯一发现的是此链接,其中说PubSub对pull方法使用了负载平衡: https://cloud.google.com/pubsub/docs/subscriber 因此,我认为订户认为多个客户正在订阅它,并且如果呼叫太快就会散布数据。那是对的吗?这里到底发生了什么? 如果稍等片刻,我将再次获得更多数据,但是即使等待5分钟,我似乎也无法获得所有数据……这非常令人困惑。 这会对使用中的应用程序造成问题吗?我如何确保所有数据都非常频繁地到达接收应用程序?有办法将其关闭吗?
答案 0 :(得分:2)
有几件事导致您每次都没有收到所有消息:
对于请求请求,即使可用消息少于最大消息,也不能保证所有消息都会在特定请求中返回。这是因为发布/订阅试图平衡返回的更多消息与最小化端到端延迟。
消息有一个ack截止期限,该期限在订阅创建时间上指定(默认为10秒)。这就是说,当您拉出消息并且不确认或否定消息时,在确认截止期限内将不会重新传递消息,基本上是将消息拉出的过程交给了他们。如果您希望立即重新发送邮件,则在使用nack
(与Cloud Pub / Sub进行交互的首选方式)时,您需要Java client library,或者您需要发送{{ 3}},ack_deadline_seconds
设置为0。