从pubsub开始。在阅读Google Cloud文档时,我遇到了一段代码,并且我认为示例存在缺陷。
这是我正在谈论的代码。它使用异步订阅者。
public class SubscriberExample {
private static final String PROJECT_ID = ServiceOptions.getDefaultProjectId();
private static final BlockingQueue<PubsubMessage> messages = new LinkedBlockingDeque<>();
static class MessageReceiverExample implements MessageReceiver {
@Override
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
messages.offer(message);
consumer.ack();
}
}
public static void main(String... args) throws Exception {
String subscriptionId = args[0];
ProjectSubscriptionName subscriptionName = ProjectSubscriptionName.of(
PROJECT_ID, subscriptionId);
Subscriber subscriber = null;
try {
subscriber =
Subscriber.newBuilder(subscriptionName, new MessageReceiverExample()).build();
subscriber.startAsync().awaitRunning();
while (true) {
PubsubMessage message = messages.take();
processMessage(message);
}
} finally {
if (subscriber != null) {
subscriber.stopAsync();
}
}
}
我的问题是,如果一堆消息已经被确认,并且BlockingQueue不为空,并且服务器崩溃,该怎么办?那我会丢失一些消息吧? (已在PubSub中确认,但未实际处理。)
最好的实现方法是只在处理完消息后才确认消息吗?而不是确认它并将其留在队列中,并假定将对其进行处理。我知道这将使消息的接收与消息的处理脱钩,并可能提高吞吐量,但仍然有丢失消息的风险,对吗?
答案 0 :(得分:0)
是的,只有在消息完全处理后,您才应该确认消息。否则,可能永远无法处理该消息,因为如果发生确认,它不会在崩溃或重新启动时重新传递。我有entered an issue来更新示例。