miller
发布于

grpc stream 单向stream 双向stream

前言

gRPC Streaming 是基于 HTTP/2 的
本章节将介绍 gRPC 的流式,分为三种类型:

Server-side streaming RPC:服务器端流式 RPC
Client-side streaming RPC:客户端流式 RPC
Bidirectional streaming RPC:双向流式 RPC

为什么不用 Simple RPC

流式为什么要存在呢,是 Simple RPC 有什么问题吗?通过模拟业务场景,可得知在使用 Simple RPC 时,有如下问题:

数据包过大造成的瞬时压力
接收数据包时,需要所有数据包都接受成功且正确后,才能够回调响应,进行业务处理(无法客户端边发送,服务端边处理)

为什么用 Streaming RPC

大规模数据包
实时场景
模拟场景
每天早上 6 点,都有一批百万级别的数据集要同从 A 同步到 B,在同步的时候,会做一系列操作(归档、数据分析、画像、日志等)。这一次性涉及的数据量确实大

在同步完成后,也有人马上会去查阅数据,为了新的一天筹备。也符合实时性。

两者相较下,这个场景下更适合使用 Streaming RPC

syntax = "proto3";

package proto;

service StreamService {
    rpc List(StreamRequest) returns (stream StreamResponse) {};

    rpc Record(stream StreamRequest) returns (StreamResponse) {};

    rpc Route(stream StreamRequest) returns (stream StreamResponse) {};
}


message StreamPoint {
  string name = 1;
  int32 value = 2;
}

message StreamRequest {
  StreamPoint pt = 1;
}

message StreamResponse {
  StreamPoint pt = 1;
}

注意关键字 stream,声明其为一个流方法。这里共涉及三个方法,对应关系为

List:服务器端流式 RPC
Record:客户端流式 RPC
Route:双向流式 RPC


关键函数 :
server stream : 

server: stream.Send(&pb.StreamResponse
client:
for {
resp, err := stream.Recv()
if err == io.EOF {
break
}
if err != nil {
return err
}

	log.Printf("resp: pj.name: %s, pt.value: %d", resp.Pt.Name, resp.Pt.Value)
}
### client stream:
![ ](https://nercis-1254047136.cos.ap-beijing.myqcloud.com/images/2023/03/10/9eb52bc356148348a5a48d8659a5179c.png)

server:
func (s *StreamService) Record(stream pb.StreamService_RecordServer) error {
for {
r, err := stream.Recv()
if err == io.EOF {
return stream.SendAndClose(&pb.StreamResponse{Pt: &pb.StreamPoint{Name: "gRPC Stream Server: Record", Value: 1}})
}
if err != nil {
return err
}

	log.Printf("stream.Recv pt.name: %s, pt.value: %d", r.Pt.Name, r.Pt.Value)
}

return nil

}

client:

stream, err := client.Record(context.Background())
if err != nil {
return err
}

for n := 0; n < 6; n++ {
	err := stream.Send(r)
	if err != nil {
		return err
	}
}

resp, err := stream.CloseAndRecv()
if err != nil {
	return err
}

双向流式 RPC: 参见下边原文

流stream 的grpc 例子 :https://eddycjy.com/posts/go/grpc/2018-09-24-stream-client-server/


简单 grpc  https://eddycjy.com/posts/go/grpc/2018-09-23-client-and-server/
浏览 (629)
点赞
收藏
评论