05-详解调用服务时负载均衡的配置及其原理

负载均衡

负载均衡的原理(通用)

@LoadBalanced注解用来拦截它所标记的RestTemplate发起的http请求, 底层是利用了一个名为Ribbon的组件来实现负载均衡功能(Cloud高版本已经弃用)

在这里插入图片描述

LoadBalancerInterceptor的intercept方法会对RestTemplate的请求进行拦截

public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {private LoadBalancerClient loadBalancer;private LoadBalancerRequestFactory requestFactory;public LoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory) {this.loadBalancer = loadBalancer;this.requestFactory = requestFactory;}public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) {this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));}public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {// 获取请求uri,如http://userservice/user/1URI originalUri = request.getURI()// 获取uri路径的主机名,其实就是服务名称userserviceString serviceName = originalUri.getHost();Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);        // 处理服务名称和用户请求return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));}
}

RibbonLoadBalancerClient的execute方法根据服务名称获取服务实例地址列表,随后利用负载均衡算法得到一个真实的服务地址信息

public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint) throws IOException {// 根据服务名称得到去Eureka服务端中获取服务的实例地址列表并保存DynamicServerListLoadBalancer到的allServeList属性当中ILoadBalancer loadBalancer = this.getLoadBalancer(serviceId);// 利用内置的负载均衡算法,从服务的实例地址列表中选择一个实例地址Server server = this.getServer(loadBalancer, hint);if (server == null) {throw new IllegalStateException("No instances available for " + serviceId);} else {RibbonServer ribbonServer = new RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));return this.execute(serviceId, (ServiceInstance)ribbonServer, (LoadBalancerRequest)request);}
}

负载均衡规则IRule: RibbonLoadBalancerClient的getServer方法最终调用父类BaseLoadBalancer的chooseServer方法

public class BaseLoadBalancer extends AbstractLoadBalancer implements PrimeConnectionListener, IClientConfigAware {private static Logger logger = LoggerFactory.getLogger(BaseLoadBalancer.class);// IRule的实现类不同表示负载均衡的策略不同,RoundRobinRule表示轮循调度private static final IRule DEFAULT_RULE = new RoundRobinRule();private static final BaseLoadBalancer.SerialPingStrategy DEFAULT_PING_STRATEGY = new BaseLoadBalancer.SerialPingStrategy((SyntheticClass_1)null);private static final String DEFAULT_NAME = "default";private static final String PREFIX = "LoadBalancer_";protected IRule rule;protected IPingStrategy pingStrategy;protected IPing ping;public Server chooseServer(Object key) {if (this.counter == null) {this.counter = this.createCounter();}this.counter.increment();if (this.rule == null) {return null;} else {try {// 选出一个负载均衡的策略return this.rule.choose(key);} catch (Exception var3) {logger.warn("LoadBalancer [{}]:  Error choosing server for key {}", new Object[]{this.name, key, var3});return null;}}}
}

负载均衡策略

负载均衡的规则都定义在IRule接口中,而IRule有很多不同的实现类,默认的实现就是ZoneAvoidanceRule表示区域内轮询方案

在这里插入图片描述

在这里插入图片描述

自定义负载均衡规则

编程方式(全局):在order-service模块中启动类中注册一个IRule类型的Bean到Spring容器中,对order-service服务想要调用的微服务均有效

  • 优缺点: 配置灵活但修改时需要重新打包发布
@Bean
public IRule randomRule(){// 创建负载均衡的实现类对象return new RandomRule();
}

配置文件方式(局部):在order-service模块的配置文件中添加userservice.ribbon.NFLoadBalancerRuleClassName配置,只针对调用的某个微服务有效

  • 优缺点: 直观方便无需重新打包发布,但是无法做全局配置,只能指定调用的某一个微服务的负载均衡规则
userservice: # 给user-service服务添加负载均衡规则ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则

饥饿加载(通用)

Ribbon默认是采用懒加载,只有在用户第一次访问时才会创建LoadBalanceClient负载均衡类做服务拉取的动作,这样用户第一次访问时就大大增加了请求时间

采用饥饿加载是在项目启动时就创建LoadBalanceClient负载均衡类加载指定的服务, 这样用户第一次访问时就大大缩短了请求时间

order-service模块的application.yml配置文件中添加新的配置属性ribbon.eager-load.enabled/clients

ribbon:eager-load:enabled: true # 开启饥饿加载# 指定对userservice单个服务进行饥饿加载clients: userservice  # 指定对多个服务进行饥饿加载clients: - userservice- xxxservice

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

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

相关文章

Java - CAS在Java中的应用、CAS的三大问题

什么是CAS CAS&#xff08;Compare-and-Swap&#xff09;是一种乐观锁的实现方式&#xff0c;全称为“比较并交换”&#xff0c;是一种无锁的原子操作。 在并发编程中&#xff0c;我们都知道i操作是非线程安全的&#xff0c;这是因为 i操作不是原子操作 i语句只需要执行一条指令…

111.am40刷机折腾记4-firefly镜像-dp正常显示

1. 平台&#xff1a; rk3399 am40 4g32g 2. 内核&#xff1a;firefly的内核&#xff08;整体镜像&#xff09; 版本&#xff1a; linux4.4.194 3. 交叉编译工具 &#xff1a;暂时不编译 4. 宿主机&#xff1a;ubuntu18.04 5. 需要的素材和资料&#xff1a;boot-am40-202…

python的Pandas库介绍

&#x1f388; 博主&#xff1a;一只程序猿子 &#x1f388; 博客主页&#xff1a;一只程序猿子 博客主页 &#x1f388; 个人介绍&#xff1a;爱好(bushi)编程&#xff01; &#x1f388; 创作不易&#xff1a;喜欢的话麻烦您点个&#x1f44d;和⭐&#xff01; &#x1f388;…

JavaScript中冷门但有用的String.raw

文章梗概 本文讲解的String.raw&#xff0c;作为JavaScript中的静态方法&#xff0c;用来获取模板字符串的原始字符串形式&#xff0c;需要注意的是与字符串模板搭配时候的事项。 介绍 String.raw() 静态方法是模板字符串的标签函数。它的作用类似于 Python 中的 r 前缀或 C#…

mmdetection里的测速脚本

由于大论文里需要对各个算法进行测速&#xff0c;因此抛开官方文档的使用说明&#xff0c;记录一下我是怎么使用mmdetection里的脚本进行测速的。 mmdetection版本&#xff1a;2.23.0 一、新版本benchmark.py&#xff08;需要分布式&#xff09; 打开tools/analysis_tools/b…

在Deepin中安装x11vnc工具并结合内网穿透软件实现远程访问桌面

文章目录 1. 安装x11vnc2. 本地远程连接测试3. Deepin安装Cpolar4. 配置公网远程地址5. 公网远程连接Deepin桌面6. 固定连接公网地址7. 固定公网地址连接测试 x11vnc是一种在Linux系统中实现远程桌面控制的工具&#xff0c;它的原理是通过X Window系统的协议来实现远程桌面的展…

Docker部署开源分布式任务调度平台DolphinScheduler并实现远程访问办公

文章目录 前言1. 安装部署DolphinScheduler1.1 启动服务 2. 登录DolphinScheduler界面3. 安装内网穿透工具4. 配置Dolphin Scheduler公网地址5. 固定DolphinScheduler公网地址 前言 本篇教程和大家分享一下DolphinScheduler的安装部署及如何实现公网远程访问&#xff0c;结合内…

Java连接数据库增删改查-MyBatis

准备工作&#xff1a; 1.创建一个springboot项目&#xff0c;并添加四个依赖 分别是&#xff0c;MyBatis的启动依赖和安装依赖&#xff0c;SQL的依赖&#xff0c;测试依赖&#xff0c;如下&#xff1a; 2.然后创建一张至少两条数据的表 &#xff08;表可以用各种图形化工具创…

[c]零钱兑换

题目比较简单&#xff0c;看答案就能看懂什么意思 #include<stdio.h> int main() {int count 0;int n;scanf("%d", &n);for (int i 0; i < n; i){for (int k 0; k <n/2; k){for (int j 0; j < n/5 ; j){if (i 2 * k 5 * j n){count;}}}}p…

【图片版】计算机组成原理考前复习题【第3章 存储系统-2(Cache)】

目录 前言 考前复习题&#xff08;必记&#xff09; 结尾 前言 在计算机组成原理的学习过程中&#xff0c;我们深入探索了计算机系统概述这一重要领域。计算机系统作为现代科技的核心&#xff0c;是整个计算机科学的基石。我们将学到的知识与理论转化为了能够解决现实问题…

递归的两个特点、典型案例----汉诺塔问题

一、递归的两个特点 1、要自己调用自己 2、递归函数里要有结束条件。 二、汉诺塔问题 有三根柱子&#xff0c;现在在一根柱子上&#xff0c;从下往上&#xff0c;按照大小顺序摞着很多盘子。现在要把这些盘子全部放到另一根柱子上&#xff0c;且盘子依然按照从大到小顺序摞着…

【Cisco Packet Tracer】路由器 NAT实验

NAT的实现方式有三种&#xff0c;即静态转换Static Nat、动态转换Dynamic Nat和端口多路复用OverLoad。 静态转换是指内部本地地址一对一转换成内部全局地址&#xff0c;相当内部本地的每一台PC都绑定了一个全局地址。一般用于在内网中对外提供服务的服务器。 [3] 动态转换是指…