GRPC client阻塞导致无法及时关闭连接的解决方案
Posted AIToolKit
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GRPC client阻塞导致无法及时关闭连接的解决方案相关的知识,希望对你有一定的参考价值。
grpc是有google开发的开源的远程过程调用(RPC)系统,具有低延迟、高扩展性、分布式的特性,基于HTTP/2协议,使用ProtoBuf(google开发的一种数据序列化协议,类似与XML/JSON),并支持C/C++、Node.js、Python、Ruby、php和C#等语言,并支持android开发。
项目中使用了GRPC进行客户端和服务器之间的通信,出现一个很严重的问题,Client在需要及时关闭连接的时候无法及时关闭,导致线程阻塞,引发其他一些问题。花了很长时间排查问题原因,最后定位到ClientReaderWrite的Finish函数无法正常结束,程序假死在Finish函数里。最后可以确定的是Finish和WritesDone函数都是阻塞的,除非server端返回,否则无法正常结束。
查看了grpc官网的api,grpc::ClientReaderWriter是阻塞的:
如何在需要client需要及时关闭的时候强制关闭,grpc的ClientContext提供了一个TryCancel接口,用来强制关闭Client的连接。
这个解决方案可以在grpc的问题讨论区找到,详见:
https://github.com/grpc/grpc/issues/17292
GRPC Client端的api接口主要如下:
template<class W, class R>
class grpc::ClientReaderWriter<W, R>
// receive data from server
bool grpc::ClientReaderWriter<W, R>::Read(R* msg)
// send data to server
bool grpc::ClientReaderWriter<W, R>::Write(const W& msg)
// send data to server finished
bool grpc::ClientReaderWriter<W, R>::WritesDone()
// wait read over and write over
Status grpc::ClientReaderWriter<W, R>::Finish()
class grpc::ClientContext
// cancel client immediately
void grpc::ClientContext::TryCancel()
以上是关于GRPC client阻塞导致无法及时关闭连接的解决方案的主要内容,如果未能解决你的问题,请参考以下文章
使用 SSH.NET 执行命令而不阻塞,并在关闭连接后保持运行
连接池(理论上应该是任意连接池) spring方法切入 mybatis redis等待请求 用了mysql连接的方法阻塞超过8小时导致mysql关闭连接 应用复活后用了已关闭连接而异常