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 serverbool grpc::ClientReaderWriter<W, R>::Read(R* msg)// send data to serverbool grpc::ClientReaderWriter<W, R>::Write(const W& msg)// send data to server finishedbool grpc::ClientReaderWriter<W, R>::WritesDone()// wait read over and write overStatus grpc::ClientReaderWriter<W, R>::Finish()  
class grpc::ClientContext// cancel client immediatelyvoid grpc::ClientContext::TryCancel()  

      

以上是关于GRPC client阻塞导致无法及时关闭连接的解决方案的主要内容,如果未能解决你的问题,请参考以下文章

Golang gRPC实现内网穿透

使用gRPC的stream向客户端实时传送信息的坑

使用 SSH.NET 执行命令而不阻塞,并在关闭连接后保持运行

如何关闭服务器的grpc流

连接池(理论上应该是任意连接池) spring方法切入 mybatis redis等待请求 用了mysql连接的方法阻塞超过8小时导致mysql关闭连接 应用复活后用了已关闭连接而异常

c#socket编程关于阻塞侦听的问题