gRPC-Go源码解读一 客户端请求链路分析

news2024/12/28 18:02:30

        最近在学习gRPC相关的知识,为啥要学呢?因为一直在用,古人云,“工欲善其事,必先利其器”。为此,花了不少时间阅读gRPC-Go的源码,收货甚多,比如透过服务发现和负载均衡这俩组件来学习复杂模块之间低耦合高内聚的设计方法,透过bdp采样与http2流量窗口自动伸缩学习网络性能优化等等。

        RPC是Remote Procedure Call的缩写,中文直译为远程过程调用,与之相对的则是本地过程调用,即本地的函数调用。我们日常在同一个服务下相互调用的函数即为本地的函数调用。与本地函数调用相比,RPC的接口提供方与请求方往往不在同一台机器上或者不在同一个进程,因此双方需要通过网络传输来通信。而网络的不可靠又带来了一定的复杂性。

        如果让我们自己来设计RPC,需要怎么做呢?先来看一个简单请求的整个过程。假设Client通过网络将请求发送到Server端,Server接收并处理完成之后,通过网络再将响应发送回来,Client接收响应则整个流程结束。在此过程中,需要完成哪些操作呢?

        首先,网络传输的是比特流,对于结构化的请求和响应数据,需要一个模块来完成序列化和反序列化的功能。

        其次,需要建立一个可靠的传输链接来通信,比如说TCP连接,为了提升性能,我们还需要对链路进行管理,如建立连接池、链接复用等等,因此还需要构建一个传输层组件。

        在微服务的背景下,应用程序往往由很多功能不同的服务组成,比如说一个购物程序,可能包括搜索、推荐、订单管理服务等等。在这种情况下,Client如何知道每个服务的具体地址呢?总不能直接写死对应服务端口吧?为此,我们需要一个新的组件来提供服务发现功能,告知我们服务的地址。现在假定我们知道了服务端地址,还有一个问题。为了服务海量用户,一般的服务都会分布式部署多个节点,为了避免单一节点负载过高,我们还需要一个组件来提供负载均衡功能,策略可以是轮询、也可以是随机、也可以是一致性哈希等等。

        通过上述讨论我们知道,一个完善的RPC框架需要包含多个组件,分别负责不同的功能。如果全部自己开发,耗时费力不说且性能如何也无定论。可喜的是gRPC提供了上述所有功能。它由Google开发,目前已开源。它默认使用protobuf序列化数据,基于http2传输。另外通过插件式的设计支持多种不同的服务发现机制和负载均衡机制。

        下文的分析基于gRPC-Go 1.54.0-dev 版本grpc-go/examples/helloworld/greeter_client/main.go

        先来看下helloworld目录下的helloworld.proto协议定义:

package helloworld;

// The greeting 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;
}

该文件定义了Greeter服务,对外提供一个方法SayHello,请求和响应中都只包含了一个字符串。

下面贴出Client的关键代码:

var (
	addr = flag.String("addr", "localhost:50051", "the address to connect to")
	name = flag.String("name", defaultName, "Name to greet")
)

func main() {
    // 解析参数
	flag.Parse()

	// 创建链接
	conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
    // 退出前关闭链接
	defer conn.Close()

	// 创建客户端
	c := pb.NewGreeterClient(conn)
	ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
	defer cancel()

	// 发送请求
	_, err := c.SayHello(ctx, &pb.HelloRequest{Name: strconv.Itoa(i)})
	if err != nil {
		log.Fatalf("could not greet: %v", err)
	}
}

        代码很简单,就是创建链接、构造Client、发送请求。这几行代码究竟做了啥呢,下面给出的流程图详细的画出了整个过程:

图1 Client请求调用流程

 

        图中红色的部分表示主流程,即上述的那几行代码。橙色部分表示负载均衡组件处理流程,绿色表示服务发现组件处理流程。默认情况下,gRPC的服务发现插件使用的是passthrough,这个插件基本上啥都没做,传进来的地址是啥结果就是啥,默认的负载均衡插件是pickfirst,即使用第一个可用的地址。除此之外,gRPC还提供了其它的负载均衡插件,如round_robin、weighted_target_experimental等等,具体选择哪一个可以在Dial的时候通过参数传递进去。

        主程序启动后,先后初始化负载均衡、服务发现组件。服务发现解析地址后则将地址传递给负载均衡组件,负载均衡组件则通知具体的负载均衡插件来建立连接,此外负载均衡组件还负责连接的维护与管理工作。

        底层链接即基于TCP的http2连接,限于篇幅,这里仅简单描述了下http2Client的功能,详情可以参考之前一篇描述传输层的博客。链接建立OK后,Client就可以通过负载均衡插件选择一个建立好的传输层开始收发信息。流程图看着很复杂,主要模块就3个:服务发现、负载均衡、网络传输层。具体的代码就不贴了,流程图中已经给出了关键节点的函数。不过还是建议下载源码深入学习下。

参考资料:

1. 深入理解grpc(二):grpc原理-CSDN博客

2.grpc/doc at master · grpc/grpc · GitHub

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/439808.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

腾讯地图获得地图经纬度数据进行描边

场景:地图展示城市或区的描边 方案: 登录腾讯地图 微信小程序JavaScript SDK | 腾讯位置服务 申请密钥 按照步骤获得密钥后 阅读api文档,有各种api获得各类数据 示例:以获得地图区域描边经纬度为例 接口调用:直接浏…

OpenAI最新官方ChatGPT聊天插件接口《插件身份验证》全网最详细中英文实用指南和教程,助你零基础快速轻松掌握全新技术(三)(附源码)

Plugin authentication 插件身份验证 前言Plugin authentication 插件身份验证No authentication 无认证Service level 服务级别User level 用户级别OAuth其它资料下载 前言 “如果你不能信任插件,那么你就不能信任整个应用程序。”正因为如此,ChatGPT始…

机器人中的数值优化(二)—— 凸函数的性质

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考,主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等,本系列文章篇数较多,不定期更新,上半部分介绍无约束优化,…

CentOS7(二)Go、Java、Python、Node开发环境配置

文章目录 Go环境配置Java环境配置Python环境配置Node 环境配置 CentOS7(一)安装和基础配置 CentOS7(二)Go、Java、Python、Node开发环境配置 根据前文,我们将所有的自定义环境变量,都收拢在了 /root/.bash_…

如何选一款适合企业的进销存软件?这款软件推荐给你

我们先来聊一聊,什么是进销存? 进销存是指企业管理过程中采购(进)—>入库(存)—>销售(销)的动态管理过程。 再来详细拆解下—— 进:指询价、采购到入库与付款的…

Jmeter实验笔记

Jmeter实验 一、基础操作 启动Jmeter 点击bin目录下的,jmeter进行启动 修改界面语言为中文 发起一个最基本的请求 GET请求 线程组,Http请求,察看结果树 提示:参数、消息体数据这两个按钮是互斥的、只要其中一个有数据&#xff…

【配电网重构】【SOE】随机配电网重构中的开关开换方法研究(Matlab代码实现)

💥 💥 💞 💞 欢迎来到本博客 ❤️ ❤️ 💥 💥 🏆 博主优势: 🌞 🌞 🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 …

数组index相同的数组进行合并

index相等的数据进行合并 let formJson [{remind: "请输入电话",sort: 0,title: "电话",type: 1,uuid: "15e343c1-060d-TL51f-8ace-23a968e9e2b9"},{remind: "请输入姓名",sort: 0,title: "姓名",type: 1,uuid: "15e…

文件,IO流,FileInputStream,FileOutputStream,FileReader和FileWriter是字符流

文件就是保存数据的地方文件流&#xff1a;文件在程序中是以流的形式来操作的 java程序&#xff08;内存&#xff09;<-----输入流-----文件&#xff08;磁盘&#xff0c;光盘等&#xff09;java程序&#xff08;内存&#xff09;------输出流----->文件&#xff08;磁盘…

用栈的思想实现将一个十进制数字转换为八进制--数据结构

魔王的介绍&#xff1a;&#x1f636;‍&#x1f32b;️一名双非本科大一小白。魔王的目标&#xff1a;&#x1f92f;努力赶上周围卷王的脚步。魔王的主页&#xff1a;&#x1f525;&#x1f525;&#x1f525;大魔王.&#x1f525;&#x1f525;&#x1f525; ❤️‍&#x1f…

单点定位2米精度?这张卡差点干掉了RTK(内有轨迹对比图)

单点定位2米精度&#xff1f;现在的定位芯片卷成这样了&#xff1f;上面两张卡一款是主打高性能融合定位的星斗3&#xff0c;另一款是主打高性价比高精度低功耗的DNA-1&#xff0c;今天小编给两张定位卡做评测。 话不多说先上轨迹图&#xff1a; 这张图是我们拿着星斗3号RTK定…

小程序封装拖拽菜单组件(uniapp拖拽排序,自定义菜单)

效果展示 思路 使用movable-area作为可移动区域,并在内部循环渲染列表项view,绑定touch事件。在mounted生命周期函数内获取区域movable-area的dom信息,记录列表项的坐标信息。在methods中定义了列表项的touchstart、touchmove和touchend事件的方法,用于实现列表项的拖拽移动和…

偶数社区投稿丨OushuDB学习实践系列(一):开一家超市

大家好&#xff0c;我是镜镜呀&#xff0c;也是一名技术开发人员。本系列内容&#xff0c;也将由技术点出发&#xff0c;从数据库的使用、实践开始&#xff0c;逐步增加对整体的认知&#xff0c;由点及面&#xff0c;真正理解 OushuDB、数据湖仓一体在技术上的变革&#xff0c;…

@Configuration 和 @Component 注解的区别

一句话概括就是 Configuration 中所有带 Bean 注解的方法都会被动态代理&#xff0c;因此调用该方法返回的都是同一个实例。 理解&#xff1a;调用Configuration类中的Bean注解的方法&#xff0c;返回的是同一个示例&#xff1b; 而调用Component类中的Bean注解的方法&#x…

【社区图书馆】携程架构与实践图书

发这篇博文主要是想学习一下携程的架构。携程出了一本《携程架构实践》&#xff0c;无奈现在还没开源。看京东价大概109元人民币。如果看到次博文的网友能发我一本《携程架构实践》pdf。不胜感谢。或者实体书籍也行。其实我不怎么需要实体书籍&#xff0c;因为技术的东西很快会…

使用 IDEA 远程 Debug 调试

背景 有时候我们需要进行远程的debug&#xff0c;本文研究如何进行远程debug&#xff0c;以及使用 IDEA 远程debug的过程中的细节。看完可以解决你的一些疑惑。 配置 远程debug的服务&#xff0c;以springboot微服务为例。首先&#xff0c;启动springboot需要加上特定的参数。…

小白下载以后打不开怎么解决

我们重装系统时&#xff0c;大家会遇到各种各样的问题&#xff0c;现在有一些想用小白一键重装系统工具来帮助自己完成系统重装时&#xff0c;却发现我们打不开这个工具&#xff0c;现在不知道其原因有哪些&#xff0c;那么大家今天就来告诉小伙伴们小白一键重装官网下载以后打…

计算机概述

计算机&#xff1a; 硬件&#xff1a; CPU&#xff08;Central Processing Unit&#xff0c;中央处理器&#xff09;靠大脑思考&#xff0c;电脑靠CPU来运算、控制。硬盘&#xff08;Hard Disk Drive&#xff09; 计算机最主要的存储设备&#xff0c;容量大&#xff0c;断电数…

创新,阿里首发微服务实施手册我粉了,原来微服务还可以这样玩

微服务 相信大家在网上会看到很多帖子把分布式跟微服务放在一起讨论。确实&#xff0c;微服务就是一种分布式架构的设计方法。但是&#xff0c;在微服务概念还没有出现之前&#xff0c;分布式这个概念并不能引起人们的强烈关注&#xff0c;如果说自己擅长分布式架构设计&#…

TCP,TCP 连接建立,TCP 连接断开,Socket 编程

目录 TCP基本认识 TCP 头格式有哪些&#xff1f; 为什么需要 TCP 协议&#xff1f; TCP 工作在哪一层&#xff1f; 什么是 TCP &#xff1f; 什么是 TCP 连接&#xff1f; #如何唯一确定一个 TCP 连接呢&#xff1f; UDP 和 TCP 有什么区别呢&#xff1f;分别的应用场景是…