go-zero负载均衡实现原理

1. 什么是负载均衡

关于微服务分布式及集群的概念即定义,在业界中这些往往会同时在同一个项目中,而集群在微服务中主要为服务的运行保障高可用。

比如:在当前的项目情况下,我们可能针对用户服务部署两台服务以保障用户服务的高可用。实践在用户服务的Login方法中我们增加对请求信息的打印输出,即输出监听的配置信息以验证是访问的那个服务。

/apps/user/rpc/logic/loginlogic.go

14a4fdc00cd88d64d56ba2a709189ecd.png

在启动的时候修改/rpc/etc/local/user.yaml的配置

63f507e4f2490e38424619f72748cc0e.png

再通过api服务即可确定go-zero请求的时候会在这两个服务中选择一个来完成请求,这里就用到了负载均衡。

ca02a0990dcc9de6e35752d61fce939e.png

负载均衡:如字面意思即对流量负载的均衡处理,当存在多个服务的时候,通过一个特定的方式将流量均衡的分撒到各个服务上这就是负载均衡。

2. 负载均衡的实现方式

负载均衡从实现上分为两大类无状态的负载均衡与有状态的负载均衡,这里的状态是指服务器的运行状态比如【繁忙、停止、空闲等】。

359e2b32140312740ccde9e61136a467.png

无状态的负载均衡

这种方式几乎是大多数项目采用的方式,对于负载均衡的实现端来说是不关心服务器的状况情况,而是依据自己的算法方式将请求相对均衡的方式发送给对应的服务器。

轮询

算法方式相对简单,只需要根据服务组的顺序按个分配即可,如果分配完了再重头进行分配请求,不用做其他处理。

  • 优点:实现简单、分配公平,适用于服务器性能相近的情况

  • 缺点:无法根据服务器的负载情况进行动态调整,可能导致某些服务器负载过高。

随机

在一组服务列表中,通过随机算法选择一个服务器来处理请求

  • 优点:实现简单、分配公平,适用于服务器性能相近的情况。

  • 缺点:无法根据服务器的负载情况进行动态调整,可能导致某些服务器负载过高。

哈希

哈希的实现方式有多种比如根据ip哈希、url哈希通过哈希算法来确定访问的服务器

  • 优点:可以保证同一请求始终分发给同一台服务器,适用于有状态的应用

  • 缺点:增加或减少服务器时,可能会导致哈希值的变化,导致请求被分发到不同的服务器

权重

权重可以在随机/轮询等机制中应用,会根据权重基于实现算法的基础上优先分配,比如A、B两个服务分别的权重是20、80,则会存在20%的请求走A服务、80%的请求走B服务。

  • 优点:可以根据服务器的性能和负载情况进行动态调整,提高系统的性能和可靠性

  • 缺点:需要手动配置服务器的权重值,不够灵活。

有状态的负载均衡

有状态的负载均衡可以根据服务实例的运行状态、负载均衡情况进行请求的分发,因此与无状态的关键则在于,负载均衡实现机制会需要关注分配处理的服务对象在运行中的状态情况,而状态信息可以是自己记录也可以通过服务器返回来获取。

d62cb5c27577902ca50c09e968e4f525.png

P2C+EWMA

这是go-zero中默认使用的负载均衡算法P2C,算法的特点是先从一组可用的节点中随机选择两个节点,然后依据权重、服务运行情况如cpu、请求成功数、拥塞度等计算出负载率,然后选择负载率较低的一个节点来完成本次请求,为了避免某些节点的分配不均衡,会在超过一定的实际后强制选择执行一次。同时采用了EWMA指数移动加权平均的算法,表示是一段时间内的均值。

  • 优点:可依据服务情况合理分配请求

  • 缺点:在对算法理解不足的情况实现会比较困难

  • 其他:我们也可以依据服务器状态筛选出较低负载的服务器依据【无状态的负载均衡】提到的算法分配。

3. 分析框架对负载均衡加载和使用的过程

在分析框架的负载均衡是如何加载执行前,仍然先做理论分析。

方式1

我们结合服务发现机制,在服务中记录负载的信息而不记录其他内容,需要使用的时候调用即可,视为是一个工具。

2e266ff5acb306d5f760d2291af0016b.png

当发起请求后,程序通过服务发现机制去获取到最新的请求服务列表,每次请求都将服务信息至于负载以获取可用的服务。

方式2

方式1的基础上每次请求都需要去进行服务发现,会多一次网络的调度,因此从性能上还可以再优化。优化的思路就是,对发现的服务异步更新维护,同时在每次存在更新服务后就修改负载均衡机制的缓存。即此时每次请求都通过负载均衡机制去获取服务地址。

719dd0d317f11efa92a02cd858a99300.png

而grpc就是使用的方式2,在异步维护更新服务之后,会同时修改负载均衡的缓存机制。

4. 源码分析

4.1. 自定义注册

在grpc中balancer和resolver同样是可以通过Register方法进行注册的

/grpc/balancer/balancer.go

65e1e885783db9220f8bd7cf52460a6f.png

因此在grpc中的go-zero/zrpc/internal/balancer/p2c/p2c.go:36代码处就在init中完成了负载均衡机制的注册, 需注意go-zero中是直接使用base.baseBuilder进行注册。

cb3f6876c6ed75c8c192a0dcf60b521b.png

4.2. grcp加载自定义负载机制

3f22e7770777efebb4157a192da39e34.png

根据上一节课的分析流程,我们直接从grpc:clientConn.maybeApplyDefaultServiceConfig方法开始进行分析。

9dc173726b8073e878a2093e0b7b811f.png

在这个方法中主要的调度链就是为了创建出负载均衡机制,因为go-zero使用的是系统默认的机制,顾最终创建的则就是balancer/base下的baseBuilder对象。

/grpc/balancer/base/base.go

f1f5eaaa838d60b604b63a1a066f4832.png

在得到了负载均衡的构建机制后,下一步则就是基于负载均衡机制去加载自定义的机制。

ea0a535a574e1448407b95f3862bc0f3.png

通过ccBalancerWrapper.updateClientConnState开始,在调度链的后可以看到在grpc:prickerWrapper中对自定义的picker进行来初始化加载

/grpc/pricker_wrapper.go

fcd07e5c1e9a90560c5899869392f16e.png

4.3. 请求调度

在分析负载均衡机制前,我们可以先看看在请求调度的时候是如何获取服务对象的地址。

2d557d0a1958337cbf645798c0dc8c03.png

根据上一讲的课程中,已经有了解到请求在grpc内部的调度链,因此我们将直接看pick方法。

/grpc/pricker_wrapper.go

64739cd77dad62637c47753f431204a1.png

在代码中可以分析出,先调用p.Pick方法获取pickResult对象即要连接的对象属性。实际上就是调用go-zero中的p2c负载均衡的处理算法获取连接并返回。

/go-zero/zrpc/internal/balancer/p2c/p2c.go

5b4990e2a19335a8007d9bb6f28f1833.png

5. 总结

从目前的代码分析中可以发现grpc在负载均衡和服务发现机制的原理实现上具有相似的特点,而在程序上均采用了装饰模式进行设计。将自己内部实现好的关键服务机制方法通过接口传递给子类,由子类依据自己的业务处理装饰后再调度自己的方法完成后续功能。

ca69cfec3168e64a19fb4fe6bd40e356.png

结合对grpc的服务发现和负载均衡机制的原理分析,可以了看出实际上grpc在对两者的加载设计思路上具有相似之处,在设计的整体结构上grpc是以clientConn作为核心对象,要求自定义的机制在完成机制本身初始化后,再根据结果装饰自己的属性参数值。

1943416bd3cda539b5d70bb810332c00.png


推荐阅读:

基础设施即代码初探-开发Terraform Provider管理私有云MySQL实例

如何使用whisper+ollama+ffmpeg为视频添加中文字幕

 

更多技术和产品文章,请关注👆

如果您对哪个产品感兴趣,欢迎留言给我们,我们会定向邀文~

360智汇云是以"汇聚数据价值,助力智能未来"为目标的企业应用开放服务平台,融合360丰富的产品、技术力量,为客户提供平台服务。
目前,智汇云提供数据库、中间件、存储、大数据、人工智能、计算、网络、视联物联与通信等多种产品服务以及一站式解决方案,助力客户降本增效,累计服务业务1000+。
智汇云致力于为各行各业的业务及应用提供强有力的产品、技术服务,帮助企业和业务实现更大的商业价值。
官网:https://zyun.360.cn 或搜索“360智汇云”
客服电话:4000052360
欢迎使用我们的产品!😊

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Rust自学】4.4. 引用与借用

4.4.0 写在正文之前 这一节的内容其实就相当于C的智能指针移动语义在编译器层面做了一些约束。Rust中引用的写法通过编译器的约束写成了C中最理想、最规范的指针写法。所以学过C的人对这一章肯定会非常熟悉。 喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文…

Apache Solr RCE(CVE-2017-12629)--vulhub

Apache Solr 远程命令执行漏洞(CVE-2017-12629) Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现。原理大致是文档通过Http利用XML加到一个搜索集合中。查询该集合也是通过 http收到一个…

OpenGL ES 01 渲染一个四边形

项目架构 着色器封装 vertex #version 300 es // 接收顶点数据 layout (location 0) in vec3 aPos; // 位置变量的属性位置值为0 layout (location 1) in vec4 aColors; // 位置变量的属性位置值为1 out vec4 vertexColor; // 为片段着色器指定一个颜色输出void main() {gl…

游戏渠道假量解决方案

某推广公司在推广过程中被查出“短期内点击量激增”“存在同一地址多次访问”“已注册用户重复注册”等数据作弊行为,法院判罚退还服务费200余万元,并赔偿违约金约350万元。 某公司为提升其游戏在应用商店榜单排名,委托某网络公司进行下载、注…

物联网:全面概述、架构、应用、仿真工具、挑战和未来方向

中文论文标题:物联网:全面概述、架构、应用、仿真工具、挑战和未来方向 英文论文标题:Internet of Things: a comprehensive overview, architectures, applications, simulation tools, challenges and future directions 作者信息&#x…

29、基于springboot的网上购物商城系统研发

本课题是根据用户的需要以及网络的优势建立的一个基于Spring Boot的网上购物商城系统,来满足用户网络购物的需求。 本网上购物商城系统应用Java技术,MYSQL数据库存储数据,基于Spring Boot框架开发。在网站的整个开发过程中,首先对…

Spring Boot--06--整合Swagger

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 Swagger一、简介官网:https://swagger.io/ Swagger 的优势 二、基本使用1. 导入相关依赖2. 编写配置文件2.1 配置基本信息2.2 配置接口信息2.3 配置分组…

写SQL太麻烦?免费搭建 Text2SQL 应用,智能写 SQL | OceanBase AI 实践

自OceanBase 4.3.3版本推出以来,向量检索的能力受到了很多客户的关注,也纷纷表达希望OB能拓展更多 多模数据库大模型 的AI应用实践。 在上篇文章 👉 OceanBase LLM,免费构建你的专属 AI 助手 ,我们介绍了如何去搭建一…

题海拾贝:力扣 86.分隔链表

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…

sql server索引优化语句

第一步 建一个测试表 --create table TestUsers --( -- Id int primary key identity(1,1), -- Username varchar(30) not null, -- Password varchar(10) not null, -- CreateDateTime datetime not null --)第二步 插入100w数据 大概1分钟执行时间 ----插入数据…

多智能体/多机器人网络中的图论法

一、引言 1、网络科学至今受到广泛关注的原因&#xff1a; &#xff08;1&#xff09;大量的学科&#xff08;尤其生物及材料科学&#xff09;需要对元素间相互作用在多层级系统中所扮演的角色有更深层次的理解&#xff1b; &#xff08;2&#xff09;科技的发展促进了综合网…

VS Code Copilot 与 Cursor 对比

选手简介 VS Code Copilot&#xff1a;算是“老牌”编程助手了&#xff0c;虽然Copilot在别的编辑器上也有扩展&#xff0c;不过体验最好的还是VS Code&#xff0c;毕竟都是微软家的所以功能集成更好一些&#xff1b;主要提供的是Complete和Chat能力&#xff0c;也就是代码补全…

基于层次化设计方法,设计一个16位二进制全加器

设计思路&#xff1a;先一个半加器和一个或门&#xff0c;每两个半加器构成一个全加器&#xff0c;每四个全加器组成一个4位全加器&#xff0c;再将这4个4位全加器依次相连组成一个16位二进制全加器。 半加器的逻辑表达式&#xff1a;sumAB; coutAB; 半加器的真值表 全加器的逻…

ES搜索原理

ES搜索原理 bg: 搜索的时候&#xff0c;使用模糊查询经常出现搜索不到的情况&#xff0c;不如mysql的like有效。 https://www.bilibili.com/video/BV1yb421J7oX/?spm_id_from333.337.search-card.all.click&vd_source3f917722acc36b0fcca7cca2d21394e2 基础概念 索引&a…

轻松上手:使用 Vercel 部署 HTML 页面教程

&#x1f600; 在学习前端的过程中&#xff0c;部署项目往往是一个令人头疼的问题。然而&#xff0c;Vercel 为我们提供了一个便捷且免费的解决方案。 Vercel 是一个强大的云平台&#xff0c;专门用于前端项目的部署和托管。它不仅支持多种前端框架和静态网站生成器&#xff0…

STL 剖析

STL 六大组件 「STL 六大组件的交互关系」 Container 通过 Allocator 取得数据储存空间Algorithm 通过 Iterator 存取 Container 内容Functor 可以协助 Algorithm 完成不同的策略变化Adapter 可以修饰或套接 Functor、Iterator 配置器(allocator) 配置器&#xff1a;负责空间…

HTTP—03

触发 GET 请求 1&#xff09;直接在浏览器 地址栏 输入 URL&#xff0c;此时构成了一个GET请求 2&#xff09;HTML中的一些特殊标签可能会触发 例如 img,a,link,script... 3&#xff09;通过Form表单触发&#xff08;Form本质也是一个HTML标签&#xff09; 4&#xff0…

C 数组:索引魔杖点化的数据星图阵列

一、数组 1.数组的概念 数组是⼀组相同类型元素的集合&#xff1b;从这个概念中我们就可以发现2个有价值的信息&#xff1a; 数组中存放的是1个或者多个数据&#xff0c;但是数组元素个数不能为0。数组中存放的多个数据&#xff0c;类型是相同的。 2.数组的分类 数组主要分为一…

苹果手机怎么清理空间:拯救你的拥挤手机

在数字生活的海洋中&#xff0c;我们的苹果手机就像一艘小船&#xff0c;载满了照片、应用、视频和各种下载的“宝贝”。随着时间的推移&#xff0c;这艘小船开始变得拥挤&#xff0c;航行速度放缓&#xff0c;甚至有时候直接卡壳。苹果手机怎么清理空间&#xff1f;是时候学会…

Ubuntu上如何部署Nginx?

环境&#xff1a; Unbuntu 22.04 问题描述&#xff1a; Ubuntu上如何部署Nginx&#xff1f; 解决方案&#xff1a; 在Ubuntu上部署Nginx是一个相对简单的过程&#xff0c;以下是详细的步骤指南。我们将涵盖安装Nginx、启动服务、配置防火墙以及验证安装是否成功。 1. 更新…