当前位置: 首页 > news >正文

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

        最近在学习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 greetingrpc 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

相关文章:

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

最近在学习gRPC相关的知识,为啥要学呢?因为一直在用,古人云,“工欲善其事,必先利其器”。为此,花了不少时间阅读gRPC-Go的源码,收货甚多,比如透过服务发现和负载均衡这俩组件来学习复…...

Word控件Spire.Doc for .net 功能详解

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下,轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具,专注于创建、编辑、转…...

联想服务器配置RAID

一、背景描述 目前有台联想服务器,配置如下: CPU:2颗处理器,40核 内存:512GB 磁盘:2*960GB SATA 4*2.4TB SAS 计划在联想物理机上安装 Vmware 的 ESXi 6.7 虚拟化管理软件,作为虚拟化服务器。…...

C++ 虚函数表

在 C 中,虚函数表(Virtual Function Table,简称 vtable)是一种用于实现多态性(Polymorphism)的机制。它是一种编译器和链接器生成的数据结构,用于处理虚函数调用。 虚函数是在基类中声明的&…...

rancher2.7丢失集群信息

使用Docker 单节点安装rancher,然后在rancher中创建了一个k8s的集群。重启rancher所在的虚拟机后,登录rancher发现这是新的实例,集群信息丢失了。但是k8s集群还是好好的。 检查k8s的日志,api server日志会报错 time"2023-0…...

数据库管理-第六十八期 Oracle 23c的其他(20230417)

数据库管理 2023-04-17第六十八期 Oracle 23c的其他1 DGPDB2 无锁并发总结第六十八期 Oracle 23c的其他 由于Oracle 23c的文档相对较少,一是当前文档主要面向开发人员,二是感觉实际内容还在不断增加,主要还有一点就是各种新特性的在官方文档…...

精准关键词获取-行业搜索词分析

SEO关键词的收集通常可以通过以下几种方法: 根据市场价值、搜索词竞争性和企业实际产品特征进行筛选:确定您的关键词列表之前,建议先进行市场分析,了解您的竞争对手、行业状况和目标受众等信息,以更好的了解所需的特定…...

c++学习之c++对c的扩展1

目录 1.面向过程与面向对象的编程 2.面向对象编程的三大特点 3.c对c的扩展: 1.作用域运算符:: 2.命名空间 1.c命名空间(namespace) 2.命名空间的使用 1.在不同命名空间内可以创建相同的名称 2.命名空间只能在全…...

Redis锁的租约问题

目录Redis的租约问题Redis租约问题的想法Redis租约问题的解决方案Redis的租约问题 首先我们先来说一说什么是Redis的租约问题。   在我们实现Redis分布式锁的时候&#xff0c;我们会出现Redis锁的时间<业务执行执行时间&#xff0c;这其实就是一个典型的租约问题&#xf…...

2023年全国最新高校辅导员精选真题及答案50

百分百题库提供高校辅导员考试试题、辅导员考试预测题、高校辅导员考试真题、辅导员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 94.一般认为&#xff0c;在具有了道德认知和道德情感的情况下&#xff0c;道德行为的产生…...

mall商城之k8s部署-4

文章目录 一、k8s部署应用服务1)master拷贝yaml2)批量修改镜像地址3)批量修改nacos地址3)创建命名空间4)创建取sercet5)配置yaml6)对象存储oss7)查看nacos1、导入配置文件2、修改配置文件8)部署到ms命名空间一、k8s部署应用服务 1)master拷贝yaml #将源码文件 mkdi…...

使用Go语言打造轻量级Web框架

前言 Web框架是Web开发中不可或缺的组件。它们的主要目标是抽象出HTTP请求和响应的细节&#xff0c;使开发人员可以更专注于业务逻辑的实现。在本篇文章中&#xff0c;我们将使用Go语言实现一个简单的Web框架&#xff0c;类似于Gin框架。 功能 我们的Web框架需要实现以下功能…...

【开源项目】BallCat 项目脚手架

简介 &#x1f389;&#x1f389;&#x1f389; 基于 React 和 Ant Design 版本的前端 ballcat-ui-react 已发布&#xff0c;欢迎大家尝鲜使用 BallCat 组织旨在为项目快速开发提供一系列的基础能力&#xff0c;方便使用者根据项目需求快速进行功能拓展。 在以前使用其他后台管…...

KlayGE-004-InputCaps 例子分析

InputCaps处理外部输入的事件 该例子主要由两部分内容&#xff1a; 外部输入事件获取 ​ 可以处理keyboard、mouse、joystick、touch、sensor的输入事件 显示一个ui图标按钮 Input 定义监听事件类型&#xff1a; KlayGE::InputActionDefine actions[] {InputActionDefin…...

组装机经验、软硬件故障排除、网络问题

目录 主板 CPU 内存 显卡 判断显卡好坏的步骤 新买的显卡安装后显示器不亮 电源 其他 网络问题 主板 1.不同主板对于不同数量的内存条安装的位置有要求&#xff0c;要按照主板规定的位置安装不同数量的内存条&#xff0c;特别是服务器主板&#xff0c;否则系统可能起…...

【行为型模式】责任链模式

文章目录1、简介2、结构3、实现方式3.1、案例引入3.2、结构分析3.3、具体实现4、责任链优缺点5、应用场景1、简介 责任链模式(Chain of Responsibility)是一种行为型设计模式&#xff0c;它允许对象在链上依次处理请求&#xff0c;用户只需要将请求发送到责任链上即可&#xf…...

C++命令模式 指挥家:掌控命令模式之美

C指挥家&#xff1a;掌控命令模式之美 (C Conductor: Master the Beauty of Command Pattern一、引言 (Introduction)1.1 命令模式概述 (Overview of Command Pattern)1.2 命令模式的应用场景 (Application Scenarios of Command Pattern)二、命令模式的基本概念 (Basic Concep…...

学会 制作极简搜索浏览器 —— 并将 ChatGPT 接入浏览器

前期回顾 Vue3 Ts Vite pnpm 项目中集成 —— eslint 、prettier、stylelint、husky、commitizen_0.活在风浪里的博客-CSDN博客搭建VIte Ts Vue3项目并集成eslint 、prettier、stylelint、huskyhttps://blog.csdn.net/m0_57904695/article/details/129950163?spm1001.2…...

NumPy 秘籍中文第二版:六、特殊数组和通用函数

原文&#xff1a;NumPy Cookbook - Second Edition 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 在本章中&#xff0c;我们将介绍以下秘籍&#xff1a; 创建通用函数查找勾股三元组用chararray执行字符串操作创建一个遮罩数组忽略负值和极值使用recarray函数创建一…...

各种交叉编译工具链的区别

目录 1 命名规则 2 实例 2.1 arm-none-eabi-gcc 2.2 arm-none-linux-gnueabi-gcc 2.3 arm-eabi-gcc 2.4 armcc 2.5 arm-none-uclinuxeabi-gcc 和 arm-none-symbianelf-gcc 3 gnueabi和gnueabihf的区别(硬浮点、软浮点) 4 Linaro公司出品的交叉编译工具链 5 ARM公司出…...

MQTT安全连接不止一种:用MQTTnet库玩转C#客户端单向与双向认证

MQTT安全连接实战&#xff1a;从单向认证到双向认证的C#实现精要 物联网设备间的数据传输安全一直是开发者关注的核心问题。MQTT协议作为轻量级的消息传输协议&#xff0c;在工业自动化、智能家居等领域广泛应用&#xff0c;但其默认的1883端口通信并不加密。本文将深入探讨如何…...

【HFP】规范精讲[15]: HFP蓝牙特有AT命令:免提场景专属功能的控制语言

在蓝牙HFP的命令体系中&#xff0c;除了复用自传统移动通信标准的AT命令&#xff0c;还有一类专门为蓝牙免提场景设计的专属AT命令。这些命令就像为蓝牙免提设备量身定制的方言&#xff0c;针对无线音频传输、设备间状态同步、蓝牙特有功能等场景进行了精准优化&#xff0c;是实…...

快速掌握Clarke与Park变换的几何本质

1. 从三相坐标系到静止两相系的几何之旅 想象一下你站在一个布满彩色灯带的游乐场中央&#xff0c;头顶有三盏呈120度分布的聚光灯&#xff08;A、B、C相&#xff09;&#xff0c;它们交替明暗形成旋转的光影。Clarke变换就像给你戴上一副特殊眼镜&#xff0c;能将三盏灯的光影…...

Beyond Compare 5专业授权生成器:3种高效授权方案完整指南

Beyond Compare 5专业授权生成器&#xff1a;3种高效授权方案完整指南 【免费下载链接】BCompare_Keygen Keygen for BCompare 5 项目地址: https://gitcode.com/gh_mirrors/bc/BCompare_Keygen Beyond Compare作为业界领先的文件对比工具&#xff0c;其强大的功能在软件…...

OpenClaw多任务队列:GLM-4.7-Flash并行处理邮件整理与文档生成

OpenClaw多任务队列&#xff1a;GLM-4.7-Flash并行处理邮件整理与文档生成 1. 为什么需要多任务队列 上周五下午&#xff0c;我同时面临三个紧急任务&#xff1a;整理客户邮件、生成季度报告草稿、汇总项目会议纪要。手动切换不同工具时&#xff0c;不仅效率低下&#xff0c;…...

数字电路实战:基于Multisim的74LS161计数器设计与应用

1. 从零认识74LS161计数器 第一次接触数字电路时&#xff0c;看到74LS161这个编号可能会觉得头大。其实它就是个非常实用的4位二进制同步计数器芯片&#xff0c;就像我们生活中常见的里程表一样&#xff0c;能够按照固定规律进行计数。我在实验室里第一次用它做实验时&#xff…...

Iono系列工业PLC模块:Arduino生态的工业级演进

1. Iono Uno/MKR/RP 系统概述Iono 系列&#xff08;Iono Uno、Iono MKR、Iono RP&#xff09;并非传统意义的开发板&#xff0c;而是一套面向工业现场的可编程逻辑控制器&#xff08;PLC&#xff09;级输入/输出模块。其核心设计哲学是将 Arduino 生态的易用性、丰富库资源与工…...

阿里开源MGeo地址匹配:零基础3步搭建,开箱即用

阿里开源MGeo地址匹配&#xff1a;零基础3步搭建&#xff0c;开箱即用 1. 为什么你需要MGeo地址匹配&#xff1f; 地址数据混乱是每个数据工程师的噩梦。同一地点在不同系统中可能有十几种写法&#xff1a;"北京市海淀区中关村大街1号"、"北京海淀中关村1号&q…...

FPGA新手别怕!Vivado 2023.1里用DDS IP核生成1MHz正弦波,保姆级图文配置+仿真

FPGA实战&#xff1a;从零开始用Vivado配置DDS IP核生成精准波形 第一次打开Vivado的IP Catalog界面时&#xff0c;满屏的参数选项确实容易让人望而生畏。但别担心&#xff0c;DDS&#xff08;直接数字频率合成&#xff09;IP核其实比你想象的要友好得多。作为FPGA数字信号处理…...

浪潮 NF5270M4 装 ESXi 8.0 识别不到 RAID1?这样设置一次搞定

最近很多机友遇到了核心问题&#xff1a;RAID1 已创建&#xff0c;但 ESXi 8.0U3i 只看到两块独立 SATA 盘&#xff0c;没识别出 RAID 逻辑盘。这是浪潮 NF5270M4 ESXi 8.0 的典型兼容性 / 驱动 / 配置问题&#xff0c;按下面步骤排查即可解决。一、先确认核心前提(必做)1、你…...