在使用gRpc流模式的过程中会发现,官方API只提供了客户端关闭stream的方法。
1 | // CloseSend closes the send direction of the stream. It closes the stream |
那么在开发过程中我们是不是需要从服务端主动断开stream,如果需要,该怎么断开?
如果你知道gRpc的底层原理,其实很好理解为什么官方不提供服务端断开的API。因为gRpc底层是通过TCP实现的 [事实上,基本上所有RPC框架默认都是使用TCP,因为RPC常用在业务系统之间进行数据交换,需要保证可靠性] ,TCP的连接建立 [三次握手] 与释放 [四次挥手] 都是由客户端发起的,所以这就是为什么服务端不支持主动断开API的原因。
但是在实际开发过程中,我们经常会遇到需要服务端主动断开的策略,如果客户端出现连接泄漏的问题,通过TCP一直连接服务端,那么势必会造成服务端的连接过多无法释放,内存上升甚至出现服务宕机的危险。
那么在开发过程中就要考虑到避免因为客户端的bug导致服务器不可用,服务端就需要有保护机制。
设计
服务端流式的设计,需要在发送给客户端响应时告知客户端,服务端已经处理完了,就是最后一帧的概念,多久以后服务端还没有收到客户端断开的标志,那么服务断就主动发起断开。所以一般服务端流式要做到以下两点:
- 流结束标志
- 定时器(最重要)
实现
Talk is cheap, Show me the code.
proto协议设计
1 | syntax = "proto3"; |
双向流
1 |