尝试使用 GCP 模拟器发布到主题时出错

Posted

技术标签:

【中文标题】尝试使用 GCP 模拟器发布到主题时出错【英文标题】:Error while trying to publish to a topic using GCP Emulator 【发布时间】:2021-02-19 10:25:34 【问题描述】:

我正在尝试使用 GCP Pub/Sub 模拟器。我创建了主题和订阅,设置了 PROJECT_ID 变量,但是当我尝试发布消息时,我收到了这个异常:

java.util.concurrent.ExecutionException: org.springframework.cloud.gcp.pubsub.core.PubSubDeliveryException: 
Publishing to fake_facl_sellerorder_topic topic failed.; 
nested exception is com.google.api.gax.rpc.NotFoundException: 
io.grpc.StatusRuntimeException:
NOT_FOUND: Requested project not found or user does not have access to it (project=project-emulator-123). 
Make sure to specify the unique project identifier and not the Google Cloud Console display name.

由于它仅在我的本地运行,我不明白为什么它说找不到 PROJECT_ID 或我无权访问它。

【问题讨论】:

您可能使用了项目名称而不是项目 ID。您可以在 Google Cloud Console 主页的“项目信息”部分找到项目 ID @Christopher,但我的问题是,即使我使用的是模拟器,我应该使用来自 GCP 的真实项目 ID 名称吗? 不确定您指的是哪个模拟器,但我相信是的。我认为模拟器模拟了发布者和订阅者部分,在这种情况下,您仍然需要一个实际的 GCP 项目,您可以在其中创建实际的 Pub/Sub 主题和订阅。 目前不支持 IAM 操作。您可以从 Testing apps locally with the emulator 文档页面上阅读和遵循示例中受益。 【参考方案1】:

这个问题已经有点老了,但对于以后来这里的人来说。这是我必须做的:

您必须确保在所有构建器中分别指向模拟器。下面是简单的 Spring Bean 版本:

@Bean
public ManagedChannel managedChannel(IntegrationServiceLibraryProperties properties) 
    return ManagedChannelBuilder.forTarget("localhost:8085").usePlaintext().build();


@Bean
public TransportChannelProvider transportChannelProvider(ManagedChannel managedChannel) 
    return FixedTransportChannelProvider.create(
            GrpcTransportChannel.create(managedChannel));


@Bean
public CredentialsProvider credentialsProvider() 
    return NoCredentialsProvider.create();

TransportChannelProvider 需要 ManagedChannel,NoCredentialsProvider 允许我们在没有凭据的情况下与本地模拟器对话。下一步是确保所有构建器都使用这些 bean:TopicAdminClient、SubscriptionAdminClient、Publisher 和 Subscriber。

@Bean
public TopicAdminClient topicAdminClient(
    CredentialsProvider credentialsProvider,
    TransportChannelProvider transportChannelProvider) throws IOException 
    return TopicAdminClient.create(
        TopicAdminSettings.newBuilder()
            .setTransportChannelProvider(transportChannelProvider)
            .setCredentialsProvider(credentialsProvider)
            .build());


@Bean
public SubscriptionAdminClient subscriptionAdminClient(
      CredentialsProvider credentialsProvider,
      TransportChannelProvider transportChannelProvider) throws IOException 
    return SubscriptionAdminClient.create(
        SubscriptionAdminSettings.newBuilder()
            .setTransportChannelProvider(transportChannelProvider)
            .setCredentialsProvider(credentialsProvider)
            .build());


public Publisher createPublisher(
      String topicName,
      CredentialsProvider credentialsProvider,
      TransportChannelProvider transportChannelProvider) throws IOException 
    return Publisher.newBuilder(topicName)
        .setCredentialsProvider(credentialsProvider)
        .setChannelProvider(transportChannelProvider)
    .build();
 

public Subscriber createSubscriber(
      String subscriptionName,
      CredentialsProvider credentialsProvider,
      TransportChannelProvider transportChannelProvider) 
    return Subscriber
        .newBuilder(subscriptionName, (PubsubMessage message, AckReplyConsumer consumer) ->  
      // handle message
    )
    .setChannelProvider(transportChannelProvider)
    .setCredentialsProvider(credentialsProvider)
    .build();

例如,我在订阅者中忘记了它,因此循环失败。

【讨论】:

以上是关于尝试使用 GCP 模拟器发布到主题时出错的主要内容,如果未能解决你的问题,请参考以下文章

Azure 存储模拟器访问 Blob 时出错

尝试在本地运行 PubSub 模拟器时出错

将来自网络服务器的打印队列列为模拟用户时出错

数据存储模拟器查询/问题

尝试在 Android Studio 中运行模拟器时出错

将消息发布到 GCP pubSub 主题失败