GRPC源码解读
GRPC源码解读
漂泊尘埃 发表于9个月前
GRPC源码解读
  • 发表于 9个月前
  • 阅读 62
  • 收藏 0
  • 点赞 0
  • 评论 0

GRPC源码解读

使用的protobuf文件

syntax = "proto3";

package servers;

// The greeter service definition.
service Greeter {
    // Sends a greeting
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
    string name = 1;
}

// The response message containing the greetings
message HelloReply {
    string message = 1;
}

Client

连接

conn, err := grpc.Dial("localhost:8080", grpc.WithInsecure())

创建一个 ClientConn 并将传入的 DialOption 应用到 ClientConndopts (dialOptions) 字段上。 设置默认的编解码类 protoCodec, backoff配置,负载均衡策略(roundRobin)。

从负载均衡器中拿到地址列表,启动goroutine连接各个地址(看下面的<连接address>),主协程设置超时时间(根据 dopts.timeout)),在超时时间内等待连接完成。

如果有地址列表监控Watcher(当负载均衡设置了naming.Resolver时会有),异步监控地址列表的变动(变动时更新 ClientConn的连接列表 conns)。

连接address

如果 dopts.insecure 为false,检查证书相关信息。

将创建的 addrConn 放入到 ClientConnconns map中,并销毁被替换的 addrConn

重置 Transport:

连接地址,一旦出错,重试,重试间隔时间由 dopts.bs 指定。

如果没出错则调用负载均衡的Up方法(标记一下这个地址已经连接了而已)。

监控 Transport: 如果有错误发生就重置 Transport(关闭之前的,重新连接一个)。

调用方法

c := servers.NewGreeterClient(conn)
reply, err := c.SayHello(context.Background(), &servers.HelloRequest{"person"})

创建Client没有什么东西。

调用 SayHello 时主要代码就下面这句:

grpc.Invoke(ctx, "/servers.Greeter/SayHello", in, out, c.cc, opts...)

ClientConn 中获取 Transport

利用获取到的transport 创建一个 Stream, Stream的id每次递增2,将 Stream 保存在transport的activeStreams中。设置各种 header 字段。将 header 按照 frame 发送给服务端以开启一个stream,frame最大16KB。

HelloRequest 编码写到 stream 中。

等待读取服务器的相应到 HelloReply

最后关闭 stream

roundRobin

Start

默认是没有指定 naming.Resolver 的,所以 Start 只是将地址放入到 addrs 字段中。

如果指定了 naming.Resolver, 会调用它返回一个 Watcher,然后启动 goroutine,循环从 Watcher 中获取地址变动的信息(增加或删除地址),一旦地址列表变动了,就将新的地址列表发给 addrCh 这个channel。

Up

标记地址是已经连接的了。

Get

获取上一次调用时拿到的地址的下一个地址。

如果获取不到地址,就创建 waitCh 然后等待有人关闭这个 waitChUpClose 方法都会检测并关闭 waitCh

标签: GRPC Go
共有 人打赏支持
漂泊尘埃
粉丝 4
博文 35
码字总数 70992
×
漂泊尘埃
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: