持续接收 14 不可用:流被服务器拒绝。按请求创建 BigTable 客户端?

Posted

技术标签:

【中文标题】持续接收 14 不可用:流被服务器拒绝。按请求创建 BigTable 客户端?【英文标题】:Persistently receiving 14 UNAVAILABLE: Stream refused by server. Create BigTable client per-request? 【发布时间】:2021-05-03 17:50:34 【问题描述】:

仅在我们的保存操作中每天都会发生:

// the record is this small and `myValue` is a sting < 32 characters in length.

const rowToInsert = 
  data: 
    myKey:  value: `$params.myValue` ,
  ,
;

await table.row(rowId).save(rowToInsert, gaxOptions);

这让我相信很明显有些地方出了问题,而且可能不是 BigTable 的问题。使用 nodejs,通过@google-cloud/bigtable 提供的客户端,使用以下 GAX 选项调用操作:

import  status  from '@grpc/grpc-js';
import  CallOptions, createRetryOptions, createBackoffSettings  from 'google-gax';

// https://cloud.google.com/bigtable/docs/status-codes
  const retries = 4;
  const timeout = 1000;
  const retryCodes = [
    status.CANCELLED,
    status.UNKNOWN,
    status.DEADLINE_EXCEEDED,
    status.FAILED_PRECONDITION,
    status.ABORTED,
    status.INTERNAL,
    status.UNAVAILABLE,
    status.DATA_LOSS,
  ];

const initialRetryDelayMillis = 100;
const retryDelayMultiplier = 1.3;
const maxRetryDelayMillis = 1000;
const initialRpcTimeoutMillis = null;
const rpcTimeoutMultiplier = null;
const maxRpcTimeoutMillis = null;
const totalTimeoutMillis = timeout;

const backoffSettings = createBackoffSettings(
    initialRetryDelayMillis,
    retryDelayMultiplier,
    maxRetryDelayMillis,
    initialRpcTimeoutMillis,
    rpcTimeoutMultiplier,
    maxRpcTimeoutMillis,
    totalTimeoutMillis,
  );

  const options: CallOptions = 
    // https://github.com/googleapis/gax-nodejs/blob/889730c1548a6dcc0b082a24c59a9278dd2296f6/src/gax.ts#L158-L159
    // ignored when using retry
    // timeout: ###
    maxRetries: retries,
    // https://github.com/googleapis/gax-nodejs/blob/889730c1548a6dcc0b082a24c59a9278dd2296f6/src/gax.ts#L349-L351
    retry: createRetryOptions(safeRetryCodes, backoffSettings),
  ;

我认为 4 次重试应该足以应对任何不稳定性,尤其是在退避的情况下。查看对我的 BigTable 实例的监控,它没有受到任何剧烈的负载。

这让我想到也许是因为我将我的客户初始化为单例?也许我应该按请求初始化客户端?也许客户端正在连接,然后出现超时,下一个请求失败?

那么是否应该根据请求创建 BigTable 客户端?上面的 GAX 选项中是否还有其他可疑之处?

例子: https://github.com/googleapis/nodejs-bigtable/blob/master/samples/tableadmin.js

似乎表明每次操作都会创建一个新客户端,但我不知道这是否只是为了举例。与 npm 页面上的示例相同:

https://www.npmjs.com/package/@google-cloud/bigtable/v/0.16.0#using-the-client-library

【问题讨论】:

【参考方案1】:

我在这个GitHub Issue 上发现了同样的错误。报告的问题是针对 Firestore API,但如果您继续阅读;他们说主要问题在于 @grpc/grpc-js 库。

proposed workaround 是更新库并重试,请记住问题仍然存在,GCP 工程师仍在处理它。

此外,您可以尝试在 BigTable API GitHub Issue Page 中打开类似的问题

就像快速刷新一样,你可以用命令更新它

npm update -g @grpc/grpc-js

【讨论】:

以上是关于持续接收 14 不可用:流被服务器拒绝。按请求创建 BigTable 客户端?的主要内容,如果未能解决你的问题,请参考以下文章

用Hystrix保护自己

tomcat拒绝接收请求记录

聊一聊高并发高可用那些事 - Kafka篇

聊一聊高并发高可用那些事 - Kafka篇

http 状态码

HTTP状态码