社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
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()
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!