梳理日常开发涉及的负载均衡

负载均衡是当前分布式微服务时代最能提及的词之一,出于对分层、解耦、弱依赖、可配置、可靠性等概念的解读,一对一的模式变得不再可信赖,千变万化的网络环境中,冗余和备份显得格外重要,稍大型的系统就会存在大量微服务、服务器、中间件资源,如何将各个资源进行平衡调度,在不浪费算力的同时保证服务的可靠性、稳定性来提供基础架构。负载均衡是一个绕不开的话题,这里只列举出开发过程中需要了解到的负载均衡框架或技术,底层涉及的算法就不在此详述。

以web服务为例,从用户侧出发到服务端请求的处理,大概要经过以下四层负载均衡,最终实现用户请求与接口处理的对应。

1. DNS解析负载均衡

DNS主要是对域名的解析,正常域名可以添加多条主机记录,例如www二级域名对应记录值的IP地址,同一www二级域名可以添加多条IP地址的记录值,当存在多个IP,可以通过权重配置修改IP的权重,修改完成后,用户发起域名请求时,根据域名应答DNS查询时,所有IP地址按照预先设置的权重进行返回不同的解析结果,将解析流量分配到不同的服务器上,从而达到负载均衡的目的。

实现效果

假设www域名解析地址中添加了三条记录,分别对应3台服务器(IP 地址分别为IP-1、IP-2、IP-3)

记录类型

主机记录

解析线路

记录值

A

www

默认

IP-1

A

www

默认

IP-2

A

www

默认

IP-3

  • 未开启权重配置的效果

当Local DNS访问云解析DNS,云解析DNS将这3个解析记录全部返回给Local DNS,Local DNS再将所有的IP地址返回给网站访问者,网站访问者的浏览器会随机访问其中一个IP。在无DNS负载均衡的权威DNS中,这种方法能够在一定程度上减轻单台服务器的压力,但它不能区分服务器的差异,不能反映服务器的当前运行状态。

默认权重效果

权重配置未开启时默认配置的是1:1:1权重,云解析DNS会根据(默认权重1:1:1),轮询3个A记录,依次返回3个IP地址,以响应网站访问者的请求。DNS解析结果如下所示:

用户1 访问,返回 IP-1
用户2 访问,返回 IP-2
用户3 访问,返回 IP-3
用户4 访问,返回 IP-1
用户5 访问,返回 IP-2
用户6 访问,返回 IP-3
……
  • 权重设置效果

权重配置开启后,进行权重设置,在DNS请求应答中,IP地址按照预先设置的权重进行返回,可以实现将解析流量按照权重进行分配。例如,将上述3条解析记录的权重比设置为2:1:1时,则DNS解析结果如下所示:

用户1 访问,返回 IP-1
用户2 访问,返回 IP-2
用户3 访问,返回 IP-3
用户4 访问,返回 IP-1
用户5 访问,返回 IP-1
用户6 访问,返回 IP-2
……

2. Nginx负载均衡

Nginx是日常开发中使用较多的服务器,可以通过不同的负载均衡算法来解决请求量过大情况下的服务器资源分配问题。较为常见的负载均衡算法有轮询、加权轮询、IP 哈希等等。可以用来处理前端请求,或者是代理后端服务接口,通常来说,一个正常的Nginx Linux 服务器可以达到10w次/秒的请求处理性能。

nginx的负载均衡策略配置很简单,在 nginx.conf 文件中配置好需要轮询的服务器,写在 http 中的 upstream 对象里:

upstream backserver{ ip_hash; server 127.0.0.1:9090 down; (down 表示单前的server暂时不参与负载) server 127.0.0.1:8080 weight=2; (weight 默认为1.weight越大,负载的权重就越大) server 127.0.0.1:6060; server 127.0.0.1:7070 backup; (其它所有的非backup机器down或者忙的时候,请求backup机器) 
} 

3. 微服务网关负载均衡

网关是系统的唯一对外的入口,介于前端端和后端之间的中间层,处理非业务功能,提供路由请求、鉴权、监控、缓存、限流等功能。承接上面的Nginx,正常微服务集群都有多个网关作为入口,这里可以用nginx做请求分发,将前端请求分发到不同的网关接口上,当请求到达网关并处理完成后,此时网关需要将具体的请求转发到具体微服务,以SpringCloud Gateway为例,spring提供了丰富的路由策略,可以解析到 HTTP层的数据。因此它可以根据请求的 Path 或 Domain 甚至是 Header 作为条件,再通过本地自定义的负载均衡策略,将请求转发到不同的微服务实例上。

具体代码实现过程中,可以从注册中心查询当前微服务注册的实例列表,并缓存到redis中间隔几秒进行更新,防止网关流量过大打垮注册中心,网关每次拿到实例列表后根据内部实现的负载均衡策略进行分发。

  	@Autowiredprivate LoadBalanceHandler loadBalance;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpResponse response = exchange.getResponse();//获取原来的请求路径String requestPath = exchange.getAttribute(FilterDict.SYSTEM_REQUEST_PATH);//自实现负载均衡策略String instanceInfo = loadBalance.randomSelectInstance();//如果没有服务,则直接返回报错if (StrUtil.isEmpty(instanceInfo)) {return response.writeWith(Mono.just(GateWayFilterUtils.writeData(exchange, RecoError.GEN_SERVER_BUSY)));}//用于测试负载均衡算法对IP分配是否均衡
//        redisUtil.zIncrementScore("test:gateway:load:ip",instanceInfo,1);//分割地址中IP和端口String[] serviceAddress = instanceInfo.split(StrUtil.COLON);String requestSchema = exchange.getRequest().getURI().getScheme();//拼接URL的数据assert ObjectUtil.isNotNull(requestPath);URI uri = UriComponentsBuilder.newInstance().scheme(requestSchema).host(serviceAddress[0].trim()).port(Integer.parseInt(serviceAddress[1].trim())).path(requestPath).query(exchange.getRequest().getURI().getRawQuery()).build(true).toUri();//将拼接好的URL装入新的exchangeServerWebExchange mutateExchange = exchange.mutate().request(builder -> builder.uri(uri).build()).build();Optional<Route> route = Optional.of(exchange.getAttribute(GATEWAY_ROUTE_ATTR));Route newRoute = Route.async().asyncPredicate(route.get().getPredicate()).filters(route.get().getFilters()).id(route.get().getId()).order(route.get().getOrder()).uri(uri).build();mutateExchange.getAttributes().put(GATEWAY_ROUTE_ATTR, newRoute);mutateExchange.getAttributes().put(FilterDict.SYSTEM_APP_IP_ADDR, serviceAddress[0]);return chain.filter(mutateExchange);}

4. 微服务接口负载均衡

上面提到的网关负载是找到具体微服务来承接,不同于微服务之间接口调用的负载均衡,如SpringCloud feign中对Robbin进行了封装,在使用Feign时提供负载平衡的http客户端,如果需要配置自己的负载算法,可以自定义Ribbon的算法即可。

还有dubbo的接口中也提供了负载均衡功能,类似于官方文档中提供的使用方式,只需要调整 loadbalance 相应取值即可,每种负载均衡策略取值请参见文档负载均衡 | Apache Dubbo。

服务端服务级别
<dubbo:service interface="..." loadbalance="roundrobin" />
客户端服务级别
<dubbo:reference interface="..." loadbalance="roundrobin" />
服务端方法级别
<dubbo:service interface="..."><dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:service>
客户端方法级别
<dubbo:reference interface="..."><dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:reference>

5. 总结

借用dubbo文档中对负载均衡的场景解释,负载均衡的好处有以下方面

  • 高可用性:部署服务的多个实例以确保即使一个或多个实例失败服务保持可用,负载均衡功能可用于在这些实例之间分配传入的请求确保以负载均衡方式使用每个实例的方式,还能最大限度地降低服务停机的风险。
  • 流量管理:限制指向特定服务实例的流量,以防止过载或确保公平的资源分配,负载均衡特性提供了 Round Robin、Weighted Round Robin、Random、Least Active Load Balancing 等多种负载均衡策略,可以用来实现流量控制。
  • 服务划分:将一个服务划分成多个逻辑组件,每个逻辑组件可以部署在不同的实例上,使用负载平衡以确保每个分区平衡的方式在这些实例之间分配请求,同时在实例发生故障的情况下提供故障转移功能。
  • 性能优化:负载平衡可用于优化服务的性能,通过跨多个实例分发请求可以利用可用的计算资源来缩短响应时间并减少延迟。

但有好处就有坏处,比起以往一条龙服务的形式,负载均衡的引入必然会增加系统复杂度,如果说微服务增加系统的宽度,那负载均衡无疑将这种宽度进一步放大,容易造成资源的浪费。


 

SLB负载均衡实践 - 云起实验室-在线实验-上云实践-阿里云开发者社区-阿里云官方实验平台-阿里云

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

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

相关文章

docker小白第一天

docker小白第一天 docker是什么docker理念容器与虚拟机比较docker能干什么docker官网介绍docker的基本组成docker平台架构 docker是什么 系统平滑移植&#xff0c;容器虚拟化技术。即源代码配置环境版本&#xff0c;打个包形成一个镜像文件&#xff0c;即软件带环境一起安装&a…

【果树农药喷洒机器人】Part1:研究现状分析以及技术路线介绍

本专栏介绍&#xff1a;付费专栏&#xff0c;持续更新机器人实战项目&#xff0c;欢迎各位订阅关注。 关注我&#xff0c;带你了解更多关于机器人、嵌入式、人工智能等方面的优质文章&#xff01; 文章目录 一、项目背景二、国内外研究现状2.1 国内研究现状2.2 国外研究现状 三…

RISC-V架构的演变

随着苹果基于ARM的硅和新的RISC-V CPU的推出&#xff0c;对于CPU开发来说&#xff0c;这是一个令人兴奋的时刻&#xff0c;尽管开发人员的旅程目前对后者来说有点坎坷。 我最喜欢的理论是&#xff0c;没有发生是孤独的&#xff0c;而只是重复了以前发生过的事情&#xff0c;也…

Linux 远程登录

Linux 远程登录 Linux 一般作为服务器使用&#xff0c;而服务器一般放在机房&#xff0c;你不可能在机房操作你的 Linux 服务器。 这时我们就需要远程登录到Linux服务器来管理维护系统。 Linux 系统中是通过 ssh 服务实现的远程登录功能&#xff0c;默认 ssh 服务端口号为 2…

C++QT教程1——QT概述(下载与安装)

文章目录 1 Qt概述1.1 什么是Qt1.2 Qt的发展史1.3 Qt版本1.4 Qt的下载与安装下载地址&#xff1a;其实我是有点懵逼的&#xff0c;因为还有个qtcreator&#xff0c;我差点不知道下哪个。。。&#xff08;qt框架比qtcreator功能更多更强大&#xff09; 安装 1.5 Qt的优点1.6 QT成…

SpringBoot + Docker 实现一次构建到处运行~

一、容器化部署的好处 图片 Docker 作为一种新兴的虚拟化方式&#xff0c;它可以更高效的利用系统资源&#xff0c;不需要进行硬件虚拟以及运行完整操作系统等额外开销。 传统的虚拟机技术启动应用服务往往需要数分钟&#xff0c;而 Docker 容器应用&#xff0c;由于直接运行…

[数据分析大全]基于Python的数据分析大全——Numpy基础

目录 一、前言二、NumpyNumpy数组 二、创建数组初始化占位符 三、输入、输出3.1 保存与载入文本文件3.2 保存与载入磁盘上的文件 四、数据类型五、数组信息六、调用帮助七、数组计算7.1 算数运算7.2 比较7.3 聚集函数 八、数组复制九、数组排序十、子集、切片、索引相关实现10.…

深入大B行业,什么是最有力的敲门砖?

引言&#xff1a;2023上半年&#xff0c; 能扛过外部环境各种变化&#xff0c; 这样的科技公司就很不容易了。 【全球云观察 &#xff5c; 热点关注】在当前后疫情时代下&#xff0c;全球经济增长处于的低增长期&#xff0c;这对所有科技企业的发展带来了直接影响。 有业内人…

win10 2022unity设置中文

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言解决方法 前言 在Edit->preferences里找不到language选项。 解决方法 【1】打开下面地址 注意 :把{version}换成你当前安装的版本&#xff0c;比如说如果…

SpringBoot第33讲:SpringBoot集成ShardingJDBC - 基于JPA的读写分离

SpringBoot第33讲&#xff1a;SpringBoot集成ShardingJDBC - 基于JPA的读写分离 本文是SpringBoot第33讲&#xff0c;主要介绍分表分库&#xff0c;以及SpringBoot集成基于 ShardingJDBC 的读写分离实践 文章目录 SpringBoot第33讲&#xff1a;SpringBoot集成ShardingJDBC - 基…

天津最新python培训班就业形势 python能就业吗?

小编认为Python是一门非常适合学习的编程语言&#xff0c;无论性别如何。它易于学习、功能强大&#xff0c;并且在各个领域都有广泛的应用&#xff0c;因此&#xff0c;性别不应该成为学习Python的障碍&#xff0c;那么学习Python是否就能找到满意的工作呢&#xff1f; 这是一…

吃瓜教程-Task05

目录 支持向量机 间隔与支持向量 SVM基本型 对偶问题 kkt条件 例子 对偶问题 例子 对偶问题原理解释 软间隔与正则化 替代损失函数 支持向量回归 例子 支持向量机 间隔与支持向量 在样本空间中&#xff0c;划分超平面可通过如下线性方程来描述: 样本空间中任意点x到…

数据结构【哈夫曼树】

哈夫曼树 哈夫曼树的概念哈夫曼树的构造构造算法的实现哈夫曼树应用哈夫曼编码哈夫曼编码的算法实现 哈夫曼树的概念 最优二叉树也称哈夫曼 (Huffman) 树&#xff0c;是指对于一组带有确定权值的叶子结点&#xff0c;构造的具有最小带权路径长度的二叉树。权值是指一个与特定结…

[原创]从强化学习的本质推导到PPO

前言 这篇博客很久之前就想做了&#xff0c;一直在拖是因为觉得自己对知识点理解还没有足够的透彻。但是每当去复盘基本概念的时候又很难理清逻辑&#xff0c;所以觉得即便现在半吊子水平&#xff0c;但是也想通过博客记录一下自己肤浅的学习心得&#xff0c;权当是为自己巩固…

加拿大量子研究新动作!D-Wave与滑铁卢大学合作研究量子相干性

​ &#xff08;图片来源&#xff1a;网络&#xff09; D-Wave是量子计算系统、软件和服务的领导者&#xff0c;也是量子计算机的第一家供应商。近期&#xff0c;D-Wave宣布与滑铁卢大学量子计算研究所&#xff08;IQC&#xff09;达成两项新合作。他们为量子计算系统建立了关键…

【计算机网络】网络层协议 -- ICMP协议

文章目录 1. ICMP协议简介2. ICMP协议格式3. ping命令4. ping命令与端口号没有关系&#xff01;&#xff01;&#xff01;5. traceroute命令 1. ICMP协议简介 ICMP&#xff08;Internet Control Message Protocol&#xff0c;控制报文协议&#xff09;&#xff0c;用于在IP主机…

无代码集成明道云与更多应用连接

明道云是一个APaaS平台&#xff0c;可以帮助用户快速搭建个性化企业应用&#xff0c;用户不需要代码开发就能够搭建出用户体验上佳的销售、运营、人事、采购等核心业务应用&#xff0c;打通企业内部数据&#xff0c;也能够通过API和Webhook和其他系统对接。 场景描述&#xff…

libcurl网络库的函数接口使用

文章目录 1、libcurl简介2、libcurl的使用3、函数简介4、 curl_easy_setopt函数部分选项介绍5、curl_easy_perform 函数说明&#xff08;error 状态码&#xff09;6、简单实例,包含库文件&#xff0c;头文件即可 1、libcurl简介 libcurl是一个跨平台的网络协议库&#xff0c;支…

消息队列(3) -封装数据库的操作

前言 上一篇博客我们写了, 关于交换机, 队列,绑定, 写入数据库的一些建库建表的操作 这一篇博客中,我们将建库建表操作,封装一下实现层一个类来供上层服务的调用 , 并在写完该类之后, 测试代码是否完整 实现封装 在写完上述的接口类 与 xml 后, 我们想要 创建一个类 ,来调用…

uniapp实现支付宝菜单展开与收起

需求实现支付宝类似的效果&#xff1a; 思路&#xff1a; 1.首先建立展开收起按钮&#xff0c;这里使用的是uview里面的icon图标。 2.其次建立展开菜单内容&#xff0c;这里只演示了文本信息&#xff0c;后期引入首页应用。 3.最后写js逻辑&#xff0c;展开收起时改变盒子高度和…