Google Pub/Sub 重用现有订阅

Google Pub/Sub reuse existing subscription

我已经创建了 java pub/sub 消费者依赖于以下 pub/sub doc.

public static void main(String... args) throws Exception {

        TopicName topic = TopicName.create(pubSubProjectName, pubSubTopic);
        SubscriptionName subscription = SubscriptionName.create(pubSubProjectName, "ssvp-sub");

        SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create();
        subscriptionAdminClient.createSubscription(subscription, topic, PushConfig.getDefaultInstance(), 0);

        MessageReceiver receiver =
                new MessageReceiver() {
                    @Override
                    public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
                        System.out.println("Got message: " + message.getData().toStringUtf8());
                        consumer.ack();
                    }
                };
        Subscriber subscriber = null;
        try {
            subscriber = Subscriber.defaultBuilder(subscription, receiver).build();
            subscriber.addListener(
                    new Subscriber.Listener() {
                        @Override
                        public void failed(Subscriber.State from, Throwable failure) {
                            // Handle failure. This is called when the Subscriber encountered a fatal error and is shutting down.
                            System.err.println(failure);
                        }
                    },
                    MoreExecutors.directExecutor());
            subscriber.startAsync().awaitRunning();

            Thread.sleep(60000);
        } finally {
            if (subscriber != null) {
                subscriber.stopAsync();
            }
        }
    }

它运行良好,但每 运行 它都会通过抛出 StatusRuntimeException 异常来请求新的订阅者名称。

io.grpc.StatusRuntimeException: ALREADY_EXISTS: Resource already exists in the project (resource=ssvp-sub).

(请参阅我的代码片段中的 SubscriptionName.create(pubSubProjectName, "ssvp-sub") 行 )

我发现在 node.js 客户端中我们可以通过 "reuseExisting:true" 选项来重用现有订阅:

topic.subscribe('maybe-subscription-name', { reuseExisting: true }, function(err, subscription) {
  // subscription was "get-or-create"-ed
});

如果使用官方java pubsub 客户端,应该传递什么选项?:

 <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-pubsub</artifactId>
      <version>0.13.0-alpha</version>
    </dependency>

Java 库没有一种方法可以让您使用现有订阅调用 createSubscription 并且不会抛出异常。您有几个选项,这两个选项都涉及使用 try/catch 块。选择取决于您是否希望订阅的存在。

悲观预测:

try {
  subscriptionAdminClient.createSubscription(subscription, 
                                             topic,
                                             PushConfig.getDefaultInstance(),
                                             0);
} catch (ApiException e) {
  if (e.getStatusCode() != Status.Code.ALREADY_EXISTS) {
    throw e;
  }
}

// You know the subscription exists and can create a Subscriber.

乐观呼声:

try {
  subscriptionAdminClient.getSubscripton(subscription);
} catch (ApiException e) {
  if (e.getStatusCode() == Status.Code.NOT_FOUND) {
    // Create the subscription
  } else {
    throw e;
  }
}

// You know the subscription exists and can create a Subscriber.

通常情况下,人们通常会在启动订阅者本身之前创建订阅(通过 Cloud Console 或 gcloud CLI),因此您甚至可能想要执行 getSubscription() 调用无论如何抛出异常。如果订阅被删除,您可能希望引起对这种情况的注意并明确处理它,因为它具有影响(例如不再存储​​消息以传递给订阅的事实)。

但是,如果您正在做一些事情,比如构建一个只需要在它启动时瞬时获取更新的缓存服务器 运行,那么在启动时创建订阅可能是有意义的。