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
下看到这个错误率,并按 instance
、method
、error_code
和 app_profile
分组。这将告诉哪个实例和哪个 RPC 导致了错误。这让您可以 grep 源代码以查找不正确的用法。
一个复杂得多的方法是您可以在 Bigtable 客户端中安装一个拦截器:
- 转储 RPC 的资源名称
- 一旦您确定有问题的 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()
);
我们不久前切换到 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
下看到这个错误率,并按 instance
、method
、error_code
和 app_profile
分组。这将告诉哪个实例和哪个 RPC 导致了错误。这让您可以 grep 源代码以查找不正确的用法。
一个复杂得多的方法是您可以在 Bigtable 客户端中安装一个拦截器:
- 转储 RPC 的资源名称
- 一旦您确定有问题的 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()
);