grpc-源码-网络模型

cc180912 · · 1016 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang 的grpc库是 https://github.com/grpc/grpc-go

grpc server端和服务端网络协议是在tcp基础上的 http2协议,http2协议负责grpc基础的数据传输、连接管理、流控等, 具体的业务层service 定义是基于 protobuf的

整个的网络过程和关键点如下图


grpc网络流程.png

说明:

  1. http2协议是支持在一个tcp连接上, client端同时发送多个request (不同request, streamid不同),不必等待server端响应第一个request后再发送第一个, 这是http2协议的应用层多路复用,这个特点,可以大大提高单个tcp连接的使用效率。 更多http2协议的细节参考https://www.jianshu.com/p/e57ca4fec26f

  2. 在http2协议的支持下, client端可以多个协程同时发送request , 而server端收到请求后,首先会在单个协程内完成 http2 frame数据帧的解码工作, 如果是个业务请求(DataFrame), 会启动一个新的协程来处理单个请求(这样保证一个tcp连接处理请求的并发能力)。grpc下每个request开一个协程的关键代码如下

//google.golang.org/grpc/server.go 
func (s *Server) serveStreams(st transport.ServerTransport) {
    defer st.Close()
    var wg sync.WaitGroup
    // HandleStreams 是注册 grpc server处理 http2 stream 数据的处理函数
    st.HandleStreams(func(stream *transport.Stream) { 
        wg.Add(1)
        //每次有新request时会调用这个方法, 这个方法就是开新的协程处理请求
        go func() {
            defer wg.Done()
            s.handleStream(st, stream, s.traceInfo(st, stream))
        }()  
    }, func(ctx context.Context, method string) context.Context {
        if !EnableTracing {
            return ctx
        }    
        tr := trace.New("grpc.Recv."+methodFamily(method), method)
        return trace.NewContext(ctx, tr)
    })   
    wg.Wait()
}

  1. grpc连接池。 如果单个连接的http2 编解码能力(这个是单协程内完成)成为你的瓶颈,可以考虑连接池功能。 可以参考
    https://github.com/processout/grpc-go-pool
    https://github.com/rfyiamcool/grpc-client-pool/blob/master/client.go

  2. keepalive 特性
    tcp 系统层面可以设置keepalive。 但是这不是grpc的keepalive原理, grpc的keepalive 是通过有规律的 ping pong 包维持的。 详细的client 和server端代码参考grpc 的feature demo
    https://github.com/grpc/grpc-go/tree/master/examples/features/keepalive

TCP KeepAlive则是为了探测/保鲜(心跳检测,连接错误检测):用于探测对端的状态及网络情况(有可能客户端崩溃、强制关闭了应用、主机不可达等等),也有保鲜功能。比如如防止nat超时。TCP keepalive则是通过发送发送侦测包实现。在Linux中通过net.ipv4.tcp_keepalive_intvl,net.ipv4.tcp_keepalive_probes,net.ipv4.tcp_keepalive_time配置。比如gnet 网络框架中的实现https://github.com/panjf2000/gnet/blob/master/netpoll/netpoll_unix.go

  1. grpc 下http2 数据包查看
    运行client的时候加入 GODEBUG=http2debug=2 环境变量可以看到 http2数据frame的发送细节
    export GODEBUG=http2debug=2 && go run grpc_temp.go
godebug_http2.png

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:cc180912

查看原文:grpc-源码-网络模型

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1016 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传