【问题标题】:Job Queue using Google PubSub使用 Google PubSub 的作业队列
【发布时间】:2017-03-24 17:35:14
【问题描述】:

我想要一个简单的任务队列。会有多个消费者在不同的机器上运行,但我只希望每个任务被消费一次。

如果我有多个订阅者使用相同的订阅 ID 从一个主题接收消息,那么该消息是否有可能被读取两次? 我已经成功地测试了这些方面的东西,但我担心可能存在同步问题。

client = SubscriberClient.create(SubscriberSettings.defaultBuilder().build());
subName = SubscriptionName.create(projectId, "Queue");
client.createSubscription(subName, topicName, PushConfig.getDefaultInstance(), 0);

Thread subscriber = new Thread() { 
  public void run() {
    while (!interrupted()) {
      PullResponse response = subscriberClient.pull(subscriptionName, false, 1);
      List<ReceivedMessage> messages = response.getReceivedMessagesList();
      mess = messasges.get(0);
      client.acknowledge(subscriptionName, ImmutableList.of(mess.getAckId()));
      doSomethingWith(mess.getMessage().getData().toStringUtf8());
    }
  }
};
subscriber.start();

【问题讨论】:

    标签: google-cloud-pubsub


    【解决方案1】:

    简而言之,是的,有些消息可能会重复:GCP 承诺至少一次传递。 Exactly-once-delivery 理论上在任何分布式系统中都是不可能的。如果可能,您应该将doSomethingWith 代码设计为幂等的,这样重复消息就不是问题了。

    您还应该只在完成处理后才确认消息:如果您的机器在acknowledge 之后但在doSomethingWith 返回之前就死机了,会发生什么?您的消息将丢失! (这个基本思想就是为什么不可能一次性交付)。

    如果丢失消息比双重处理更可取,您可以添加一个锁定过程(将“已处理”令牌写入一致的数据库),但如果在处理消息之前处理写入,这可能会失败。但此时,您或许能够找到一种为最多一次而设计的消息传递技术,而不是针对可靠性进行优化的消息传递技术。

    【讨论】:

      猜你喜欢
      • 2017-12-06
      • 2023-03-29
      • 2016-11-26
      • 2011-10-25
      • 1970-01-01
      • 2012-03-15
      • 1970-01-01
      • 2010-11-04
      • 1970-01-01
      相关资源
      最近更新 更多