GCP BigTable 指标 - 404 请求是什么意思?

GCP BigTable Metrics - what do 404 requests mean?

我们不久前切换到 BigTable,从那时起,GCP 指标控制台中出现了很多“404 请求”和大量错误。

我们在日志中没有看到任何错误,甚至数据 storage/retrieval 似乎都按预期工作。 这些错误的原因是什么?如何找出导致这些错误的原因?

Google 云支持,

如果没有更多的洞察力,我将无法提供有关此 404 问题的有效信息。 问题一定是拼写错误或配置问题,但无法通过共享数据确认。

为了提供更有意义的支持,建议您开一个Public Issue Tracker or a Google Cloud Support ticket

如前所述,404 表示未找到资源。此处的相关资源是 Bigtable table(这可能意味着实例 ID 或 table ID 在您的应用程序中配置错误)。

我猜您正在查看 APIs & Services > Cloud Bigtable API 下的指标。这些指标显示来自 Cloud Bigtable 服务的响应代码。您应该能够在 Monitoring > Metrics Explorer > metric:bigtable.googleapis.com/server/error_count 下看到这个错误率,并按 instancemethoderror_codeapp_profile 分组。这将告诉哪个实例和哪个 RPC 导致了错误。这让您可以 grep 源代码以查找不正确的用法。

一个复杂得多的方法是您可以在 Bigtable 客户端中安装一个拦截器:

  1. 转储 RPC 的资源名称
  2. 一旦您确定有问题的 table 名称,记录调用者的堆栈跟踪

大致如下:

BigtableDataSettings.Builder builder = BigtableDataSettings.newBuilder()
        .setProjectId("...")
        .setInstanceId("...");

ConcurrentHashMap<String, Boolean> seenTables = new ConcurrentHashMap<>();

builder.stubSettings().setTransportChannelProvider(
        EnhancedBigtableStubSettings.defaultGrpcTransportProviderBuilder()
            .setInterceptorProvider(() -> ImmutableList.of(new ClientInterceptor() {
              @Override
              public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
                  MethodDescriptor<ReqT, RespT> methodDescriptor, CallOptions callOptions,
                  Channel channel) {
                return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(channel.newCall(methodDescriptor, callOptions)) {
                  @Override
                  public void sendMessage(ReqT message) {
                    Message protoMessage = (Message) message;
                    FieldDescriptor desc = protoMessage.getDescriptorForType()
                        .findFieldByName("table_name");
                    if (desc != null) {
                      String tableName = (String) protoMessage.getField(desc);
                      if (seenTables.putIfAbsent(tableName, true) == null) {
                        System.out.println("Found new tableName: " + tableName);
                      }
                      if ("projects/my-project/instances/my-instance/tables/my-mispelled-table".equals(
                          tableName)) {
                        new RuntimeException(
                            "Fake error to get caller location of mispelled table id").printStackTrace();
                      }
                    }
                    delegate().sendMessage(message);
                  }
                };
              }
            }))
            .build()
    );