grpc的dial正常执行流程
来源:互联网 发布:青岛淘宝供应商 编辑:程序博客网 时间:2024/04/28 17:16
请先阅读 grpc源码注解(golang)
以下基于默认配置情况下(还有其它没有提到的配置都取默认值):
- 设置了balancer(etcd等)
- 没有设置WithBlock,即dialOptions.block = false
- 没有设置FailOnNonTempDialError,即dialOptions.copts.FailOnNonTempDialError = false
grpc.Dial 正常的执行流程,第一次进入的时候的有些逻辑是走不到或者不太重要的都舍去不表
A. grpc.Dial() 返回一个*ClientConn
从balancer(etcd等)返回一批地址,但是这批地址暂时还是不能用的,需要等待A225
- A2,对于每一个地址依次建立连接,循环调用cc.resetAddrConn, 即
- A3,单独goroutine监控balancer(etcd等)的变化(cc.lbWatcher()),实时更新服务集群地址,即
- 单独goroutine监控监控ServiceConfig的变化(cc.scWatcher),可以在服务启动后动态更新调用服务的配置
A2,cc.resetAddrConn针对一个地址建立连接,创建一个addrConn加入到ClientConn.conns中去,主流程分为:
- 如果这个地址已经存在连接了,先关闭掉ac.teardown
- A22,ac.resetTransport,建立一个底层连接(http2),这一步默认是goroutine出去的,不会阻塞,除非调用WithBlock;
A23,单独goroutine监控底层连接的状态变化(ac.transportMonitor),进行重连或者放弃
A22, ac.resetTransport里面是一个大循环,重试建立连接直到成功,除非某些条件下返回(默认情况下只有被ac.teardown了,即在balance中删除),每个循环里面:
- 如果ac.state == Shutdown ,直接返回
将状态改为正在连接中~~ ac.state == Connecting
- 计算sleepTime,这里是根据重试的超时策略,返回两次重试的间隔时间;即如果这次重连还是失败,会等待sleepTime才会进入下一次循环
- A224,建立一个底层的http2连接(transport.NewClientTransport);如果是临时错误, 将状态改为短暂的失败,ac.state = TransientFailure,等待sleepTime;如果是非临时错误,直接返回,默认情况下可以认为都是临时错误;
- 将状态改为readyac.state = Ready ,通知balancer(etcd等)这个地址连接ok了(up);这样下次就能从balancer 中读取到这个地址了
A224, 建立一个底层的http2连接(newHTTP2Client)
- dial一个tcp连接,失败的话,默认返回一个临时错误
- 单独goroutine,循环的读取所有的帧,并且分发到相应的流中去,如果有错误了,会有通知到A233
- 初始化http2 相关的操作(发送setting帧等)
A23,transportMonitor 是一个单独的goroutine,里面是一个循环,会监控这个连接以下几种情况:
- 如果这个连接被ac.teardown了,直接退出,不需要维护了
- 如果收到http2的goaway帧,再重新cc.resetAddrConn,即A2,然后当前直接退出;相当于用一个新的连接来替换
- 如果这个连接出错了,置为临时失败ac.state = TransientFailure ,暂时不让用,然后重试连接ac.resetTransport,即A22
A3,cc.lbWatcher监控balancer(etcd等)的变化 , 实时更新集群服务地址
- balancer.Notify() 是一个channel,每当有更新的时候,从这里读取到所有的地址(全量而非增量)
判断有哪些地址是新增的,哪些地址是删除掉的
对于新增的地址执行cc.resetAddrConn,即A2
对于删掉的地址直接ac.tearDown,通知balancer(etcd等)这个地址down了, 这样可能会影响到A231,A221
对于ac.tearDown,里面会关闭底层的连接,修改状态为ac.state == Shutdown,然后通知balancer(etcd等)这个地址down了,在下次轮询的时候,就不会有这个地址了;
如果这个balancer(etcd等)收到这个地址的UP的通知,表示这个地址又OK了
- grpc的dial正常执行流程
- grpc的invoke(一次请求)正常执行流程
- grpc服务异常情况的执行流程
- 开发直播的正常流程
- Cisco dial-peer的匹配
- grpc-gradle与grpc流程完美整合(3)
- gRPC的使用(一)之异步单项RPC的使用流程
- gRPC的使用(二)之异步服务器流RPC的使用流程
- gRPC 的协议分析
- gRPC-java的编译
- gRPC使用的分析
- grpc 的协议分析
- go的grpc实现
- gRPC的使用(cpp)
- golang下的grpc
- PsLookupProcessByProcessId的执行流程
- struts2的执行流程
- struts2的执行流程
- CSS初体验
- HDU3829-Cat VS Dog
- 牛客模拟一:DNA合成
- 博客资源收集(持续更新)
- 解决“unable to connect to your virtual device” 错误
- grpc的dial正常执行流程
- 我对内核对象的理解
- 【linux】cut命令
- c++第二次试验-定期存款利息计算器(试验)
- 关于scrapy NameError: global name 'DmozItem' is not defined的解决方法
- Nodejs里面关于this指向的理解
- linux下内网端口转发工具:linux版lcx 使用方法
- 继承的基础知识
- Java NIO