订阅X秒钟的Google发布/订阅主题,如果未收到任何消息,则停止

时间:2020-05-01 16:54:10

标签: java google-cloud-platform google-cloud-pubsub

我正在使用Google Pub/Sub Java SDK订阅主题。我想做的是以下事情:

  • 开始收听主题X秒钟(假设25秒钟)
  • 如果收到一条消息,请停止收听并处理该消息(这可能需要几分钟)
  • 处理完消息后,继续收听主题25秒
  • 如果在25秒钟内未收到任何消息,请停止监听

我似乎只能在文档中找不到任何内容。也许只是不可能?

这是我启动订户的方式:

// Create a subscriber bound to the asynchronous message receiver
subscriber = Subscriber.newBuilder(projectSubscriptionName, new PubSubRoeMessageReceiver()).build();

// Start subscriber
subscriber.startAsync().awaitRunning();

// Allow the subscriber to run indefinitely unless an unrecoverable error occurs.
subscriber.awaitTerminated();

这就是我的消息接收者的样子:

public class PubSubRoeMessageReceiver implements MessageReceiver {
    @Override
    public void receiveMessage(PubsubMessage pubsubMessage, AckReplyConsumer ackReplyConsumer) {
        // Acknowledge message
        System.out.println("Acknowledge message");
        ackReplyConsumer.ack();

        // TODO: stop the subscriber

        // TODO: run task X

        // TODO: start the subscriber
    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

以这种方式使用Cloud Pub / Sub是一种反模式,可能会引起问题。如果您在收到消息后但在处理消息之前立即对其进行确认,如果订户由于某种原因而崩溃,该怎么办?发布/订阅不会重新传递该消息,因此可能永远不会对其进行处理。

因此,您可能要等到确认后再处理邮件。但是,您将无法关闭订阅者,因为该消息尚未发送的事实将丢失,因此,确认截止日期将到期,并且该消息将被重新发送。

如果要确保客户端一次只收到一封邮件,可以在客户端上使用FlowControlSettings。如果将MaxOutstandingElementCount设置为1,则一次只会向receiveMessage发送一封邮件:

subscriber = Subscriber.newBuilder(projectSubscriptionName, new PubSubRoeMessageReceiver())
    .setFlowControlSettings(FlowControlSettings.newBuilder()
        .setMaxOutstandingRequestBytes(10L * 1024L * 1024L) // 10MB messages allowed.
        .setMaxOutstandingElementCount(1L) // Only 1 outstanding message at a time.
        .build())
    .build();

请记住,如果在启动订阅服务器时积压了大量小消息,并且打算启动多个订阅服务器,则可能会遇到documentation中所述的低负载均衡。