• 【云原生】SpringCloud系列之客户端负载均衡Ribbon


    【云原生】SpringCloud系列之客户端负载均衡Ribbon

    基本概念

    在微服务架构中,负载均衡是必须使用的技术,通过它来实现系统的高可用、集群扩容等功能。负载均衡可以分为两种:服务端负载均衡和客户端负载均衡。通常所说的负载均衡指服务器负载均衡,可通过硬件设备或软件来实现,硬件比如:F5、Array等,软件比如:LVS、Nginx等。
    负载均衡按实现方式分类可区分为:服务端负载均衡(比如Nacos负载均衡)客户端负载均衡
    SpringCloud Ribbon是基于客户端的负载均衡工具,它可以将面向服务的 REST 模板请求自动转换成客户端负载均衡的服务调用。执行过程如下图:
    在这里插入图片描述

    1. 服务消费者与服务提供者实例在启动时向 Nacos 注册;
    2. 订单服务向商品服务发起通信前,Ribbon 向 Nacos 查询商品服务的可用实例列表;
    3. Ribbon 根据设置的负载策略从服务提供者可用实例列表中选择实例;
    4. 服务消费者实例向服务提供者实例发起请求,完成 RESTful 通信;

    Ribbon 是由 Netflix 发布的负载均衡器,它有助于控制 HTTP 和 TCP 的客户端的行为。Ribbon 属于客户端负载均衡。
    为 Ribbon 配置服务提供者地址后,Ribbon 就可基于某种负载均衡算法,自动的帮助服务消费者进行请求。同时 Ribbon 默认为我们提供了很多负载均衡算法,例如:轮询、随机算法等。

    配置 Ribbon 负载均衡策略

    Ribbon 内置多种负载均衡策略,常用的分为以下几种。

    • RoundRobinRule:

    轮询策略,Ribbon 默认策略。默认超过 10 次获取到的 server 都不可用,会返回个空的 server。

    • RandomRule:

    随机策略,如果随机到的 server 为 null 或者不可用的话。会不停地循环选取。

    • RetryRule

    重试策略,定时限内循环重试。默认继承 RoundRobinRule,也持自定义注,RetryRule 会在每次选取之后,对选举的 server 进判断,是否为 null,是否 alive,并且在 500ms 内会不停地选取判断。而 RoundRobinRule 失效的策略是超过 10 次,RandomRule 没有失效时间的概念,只要 serverList 没都挂。

    • BestAvailableRule

    最小连接数策略,遍历 serverList,选取出可的且连接数最小的个 server。那么会调用 RoundRobinRule 重新选取。

    • AvailabilityFilteringRule

    可用过滤策略。扩展了轮询策略,会先通过默认的轮询选取个 server,再去判断该 server 是否超时可用、当前连接数是否超限,都成功再返回。

    • ZoneAvoidanceRule

    区域权衡策略。扩展了轮询策略,除了过滤超时和链接数过多的 server,还会过滤掉不符合要求的 zone 区域的所有节点,始终保证在个区域/机房内的服务实例进行轮询。
    这里所有负载均衡策略名本质都是 com.netflix.loadbalancer 包下的类:
    在这里插入图片描述

    要更改微服务通信时采用的负载均衡策略也很简单,在 application.yml 中采用下面格式书写即可。

    provider-service: #服务提供者的微服务id 
      ribbon: 
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #设置对应的负载均衡类 
    
    • 1
    • 2
    • 3

    当采用随机策略,杂乱的顺序说明随机策略已生效。

    Ribbon主要组件和作用

    ILoadBalancer:定义一系列的操作接口,比如选择服务实例。
    在这里插入图片描述
    IRule:算法策略,内置算法策略来为服务实例的选择提供服务。
    在这里插入图片描述
    ServerList:负责服务实例信息的获取,可以获取配置文件中的,也可以从注册中心获取。
    在这里插入图片描述
    ServerListFilter:过滤掉某些不想要的服务实例信息。
    在这里插入图片描述
    ServerListUpdater:更新本地缓存的服务实例信息。
    在这里插入图片描述
    IPing:对已有的服务实例进行可用性检查,保证选择的服务都是可用的。
    在这里插入图片描述
    如果需要自定义相关组件,需要实现上述接口。

    Ribbon使用

    Ribbon 的使用方式主要分为下面这三种,

    1. 原生 API,Ribbon 是 Netflix 开源的,如果你没有使用 Spring Cloud,也可以在项目中单独使用 Ribbon,在这种场景下就需要使用 Ribbon 的原生 API。
    2. Ribbon + RestTemplate,当我们项目整合了 Spring Cloud 时,就可以用 Ribbon 为 RestTemplate 提供负载均衡的服务。
    3. Ribbon + Feign,关于 Feign 的使用方式后续我会继续整理到博客中,欢迎持续关注。

    原生API

    配置一个服务列表,数据格式为 IP + PORT,可以固定写几个服务列表,也可以从别处读取,比如注册中心。
    构建一个负载实例,将服务列表传入,再指定对应的负载均衡策略,RandomRule 是随机策略。具体的应用逻辑写在 call 方法里,call 方法的参数是 Server 对象,Server 也就是我们第一步构建的服务列表信息,得到 Server 后就可以获取到对应的 IP 和端口,然后进行接口的调用。
    代码案例如下:

    	/**
    	 * 轮询请求测试
    	 */
    	@Test
    	public void roundRobinRuleTest(){
    		// 服务列表
    		List serverList = Arrays.asList(new Server("localhost", 8080),
    				new Server("localhost", 8081),
    				new Server("localhost", 8082));
    		// 构建负载实例
    		BaseLoadBalancer loadBalancer = LoadBalancerBuilder.newBuilder().buildFixedServerListLoadBalancer(serverList);
    		loadBalancer.setRule(new RoundRobinRule());
    		// 调用5次来测试效果
    		for (int i = 0; i < 6; i++) {
    			String result = LoadBalancerCommand.builder().withLoadBalancer(loadBalancer).build()
    					.submit(new ServerOperation() {
    						@Override
    						public Observable call(Server server) {
    							try {
    								String addr = "http://" + server.getHost() + ":" + server.getPort();
    								System.out.println("调用地址:" + addr);
    								return Observable.just("");
    							} catch (Exception e) {
    								return Observable.error(e);
    							}
    						}
    					}).toBlocking().first();
    			System.out.println("调用结果:" + result);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    RestTemplate调用

    RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程 HTTP 服务的方法,能够大大提高客户端的编写效率。
    将 RestTemplate 和 Ribbon 整合起来,只需要在配置 RestTemplate 实例的时候,加一个 @LoadBalanced 的注解,这样 RestTemplate 在调用接口时,就不需要用固定的 IP 加端口的方式调用接口,而是可以用服务名称的方式进行接口的调用,自动具备客户端负载均衡的效果。

    // RestTemplate 配置类
    @Configuration
    public class RestConfiguration {
    
    	@Bean
        // @LoadBalanced 注解让RestTemplate 能够直接使用服务名称调用对应的接口
    	@LoadBalanced
    	public RestTemplate restTemplate() {
    		return new RestTemplate();
    	}
    	
    }
    
        @Autowired
    	private RestTemplate restTemplate;
    	
    	@GetMapping("/get")
    	public Object get() {
    		User user = restTemplate.getForEntity("http://system-service/user/get?id=1", User.class).getBody();
    		//User user = restTemplate.getForEntity("http://localhost:8084/user/get?id=1", User.class).getBody();
    		return user;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    本文内容到此结束了,
    如有收获欢迎点赞??收藏??关注,您的鼓励是我最大的动力。
    如有错误疑问??欢迎各位大佬指出。
    主页的博客汇总???

    保持热爱,奔赴下一场山海。???

    在这里插入图片描述

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    C++每日面经
    (八)VBA常用基础知识:workbooks操作之打开workbook
    对表白的看法
    LDR6035智能蓝牙音响可充可放(5.9.12.15.20V)快充快放设备充电
    Vue 3的高颜值UI组件库
    CentOS7系统搭建web环境 php&nginx&pgsql
    【Java 进阶篇】JavaScript 表单验证详解
    .NET借助虚拟网卡实现一个简单异地组网工具
    Shell脚本之正则表达式详解
    在 Python 中创建 Getter 和 Setter
  • 原文地址:https://blog.csdn.net/m0_67392661/article/details/126080738