linux 为什么长寿命grpc流在循环中重新启动缓慢

x8diyxa7  于 2023-10-16  发布在  Linux
关注(0)|答案(2)|浏览(101)

我正在尝试实现这个blog post中描述的一个想法。
我使用的是长期grpc流从后端(服务器)发送通知到应用程序。客户端订阅特定的通知,然后服务器将它们发送回客户端。当某些后端事件发生时,客户端会立即收到有关该事件的通知。这个rpc在客户端运行时是活动的,因为Finish()永远不会在后端调用。后端和所有客户端都在同一台机器上运行,因此网络延迟不是问题。
为了实现在后端尚未运行时运行客户端的功能,我尝试在循环中每隔0.5秒订阅一次客户端:

std::string server_addr = "unix-abstract:test";
auto client = MakeClient(server_addr);

while (!TryToSubscribeNotifications(client));

如果订阅成功,则中断;如果没有,请重试。

bool
TryToSubscribeNotifications(Client &client)
{
using std::chrono_literals::operator""ms;

std::thread(&Client::SubscribeNotifications, &client).detach();
std::this_thread::sleep_for(500ms);

return client.IsSubscribed();
}

Client中,我使用atomic_bool来设置和检查订阅状态。IsSubscribed()返回此状态。

问题是:

为什么客户端在后端启动时不立即订阅通知,而只是在客户端启动前一分钟左右的随机时间(通常长达30秒)后才订阅通知?
复制步骤:
1.只运行客户端,不运行后端;
1.请等一分钟。客户端应重复打印“通知rpc失败。每隔0.5秒尝试#”;

  1. run backend;
    1.客户端在某个随机时间(通常长达30秒)内仍然不能建立连接。
    我用的是grpc callback-based asynchronous API
    完整的repo代码示例和构建说明:https://github.com/illukin/grpc-longlive-example
    Fedora 36
    gcc 12.2.1
    3.21.6.0
    gRPC 1.49.1
0vvn1miw

0vvn1miw1#

试试这个:

List<ChannelOption> channelOptions = new List<ChannelOption>
{
    new ChannelOption("grpc.initial_reconnect_backoff_ms", 1000),
    new ChannelOption("grpc.max_reconnect_backoff_ms", 1000)
};

channel = new Channel(host, port, ChannelCredentials.Insecure, channelOptions);
client = new Commands.CommandsClient(channel);
pgvzfuti

pgvzfuti2#

@Cerberus,非常感谢,它工作了!
C++解决方案:

Client
MakeClient(std::string &target)
{
  grpc::ChannelArguments chan_args;
  chan_args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, 1000);
  chan_args.SetInt(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, 1000);

  return { grpc::CreateCustomChannel(target, grpc::InsecureChannelCredentials(),
    chan_args)};
}

相关问题