SpringCloud之Eureka注册中心与Robbin负载均衡(三)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
EMR Serverless StarRocks,5000CU*H 48000GB*H
简介: SpringCloud之Eureka注册中心与Robbin负载均衡(三)

负载均衡


在刚才的案例中,我们启动了一个classes-service,然后通过DiscoveryClient来获取服务实例信息,然后获取ip和端口来访问。


但是实际环境中,我们往往会开启很多个eureka-service的集群。此时我们获取的服务列表中就会有多个,到底该访问哪一个呢?


一般这种情况下我们就需要编写负载均衡算法,在多个实例列表中进行选择。微信图片_20220526132324.png不过Eureka中已经帮我们集成了负载均衡组件:Ribbon,简单修改代码即可使用。

什么是Ribbon:

微信图片_20220526132340.png

接下来,我们就来使用Ribbon实现负载均衡。


启动两个服务实例


首先我们启动两个classes-service实例,一个9010,一个9011。

步骤一:为两个端口号配置yml文件

微信图片_20220526132345.png

application-9010.yml

微信图片_20220526132350.png

application-9011.yml

微信图片_20220526132357.png

步骤二:配置两个启动项

微信图片_20220526132403.png


微信图片_20220526132410.png

测试微信图片_20220526132438.png 

开启负债均衡


因为Eureka中已经集成了Ribbon,所以我们无需引入新的依赖。直接修改代码:

在RestTemplate的方法上添加@LoadBalanced注解即可微信图片_20220526132443.png

修改 ClassesController ,添加标识内容

package com.czxy.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@RestController
@RequestMapping("/classes")
public class ClassesController {
    @Resource
    private HttpServletRequest request;
    @GetMapping
    public List<String> findAll(){
        List<String> list = new ArrayList<>();
        list.add("Java12班");
        list.add("Java34班");
        list.add("服务端端口:" + request.getServerPort());
        return list;
    }
}

访问“学生服务”进行测试:微信图片_20220526132450.png

扩展:源码追踪


为什么我们只输入了service名称就可以访问了呢?之前还要获取ip和端口。

显然有人帮我们根据service名称,获取到了服务实例的ip和端口。它就是LoadBalancerInterceptor

我们进行源码跟踪:微信图片_20220526132457.png

继续跟入execute方法:发现获取了8082端口的服务


微信图片_20220526132503.png

继续跟入execute方法:发现获取了8082端口的服务微信图片_20220526132508.png

优化:负载均衡策略


为什么我们只输入了service名称就可以访问了呢? 显然有人帮我们根据service名称,获取到了服务实例的ip和端口。

通过对底层原理的分析,Ribbon采用是负载均衡策略进行的处理。


负载均衡策略初体验


第一步】添加整合Junit的坐标微信图片_20220526132513.png

<!--测试-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

【第二步】编写测试类

微信图片_20220526132521.png

package com.czxy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = StudentApplication.class)
public class TestRibbon {
    @Resource
    private RibbonLoadBalancerClient client;
    @Test
    public void test(){
        for (int i = 0; i < 100; i++) {
            ServiceInstance instance = this.client.choose("classes-service");
            System.out.println(instance.getHost() + ":" + instance.getPort());
        }
    }
}

微信图片_20220526132530.png

结果:

微信图片_20220526132539.png

负载均衡的配置


SpringBoot提供了修改负载均衡规则的配置入口:

{服务名称}.ribbon.NFLoadBalancerRuleClassName=具体策略

例如:

# 指定服务设置负载均衡策略
classes-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

# 指定服务设置负载均衡策略

classes-service:

 ribbon:

   NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule微信图片_20220526132546.png


再次测试,发现结果变成了随机:

微信图片_20220526132554.png

常见策略的配置(注意:下面提供了3个策略,同时只能使用一个。

微信图片_20220526132559.png

优化:重试机制


CAP原则


注册中心通常需要遵循CAP原则,CAP指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),往往三者不可兼得。


Eureka的服务治理主要强调是AP:即可用性和可靠性。


Eureka为了实现更高的服务可用性,牺牲了一定的一致性,极端情况下它宁愿接收故障实例也不愿丢掉健康实例,正如我们上面所说的自我保护机制。


但是,此时如果我们调用了这些不正常的服务,调用就会失败,从而导致其它服务不能正常工作!这显然不是我们愿意看到的。


效果演示


【第一步】我们现在关闭一个classes-service 9011实例:


【第二步】因为服务剔除的延迟,student-service并不会立即得到最新的服务列表,此时再次访问你会得到错误提示微信图片_20220526132606.png

【第三步】整合Spring Retry

此时,9010服务其实是正常的。微信图片_20220526132613.png

重试机制:Retry


因此Spring Cloud 整合了Spring Retry 来增强RestTemplate的重试能力,当一次服务调用失败后,不会立即抛出一次,而是再次重试另一个服务。

引入spring-retry依赖

微信图片_20220526132622.png

<!--重试-->
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

只需要简单配置即可实现Ribbon的重试:

server:
  port: 9020
spring:
  application:
    name: student-service
  cloud:
    loadbalancer:
      retry:
        enabled: true
eureka:
  client:
    service-url: #注册中心位置,多个地址以','隔开
      defaultZone: http://localhost:10086/eureka/,http://localhost:10087/eureka
    registry-fetch-interval-seconds: 5 #从注册中心,获得列表的间隔时间
  instance: #web页面显示效果和访问路径
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address: true
    lease-renewal-interval-in-seconds: 5   #服务续约(renew)的间隔,默认值90秒
    lease-expiration-duration-in-seconds: 10  #服务失效时间,默认为30秒
# 指定服务设置负载均衡策略
#classes-service:
#  ribbon:
#    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
#    NFLoadBalancerRuleClassName : com.netflix.loadbalancer.BestAvailableRule          #并发最少
#    NFLoadBalancerRuleClassName : com.netflix.loadbalancer.WeightedResponseTimeRule       #请求时间权重
classes-service:
  ribbon:
    ConnectTimeout: 250               # Ribbon的连接超时时间
    ReadTimeout: 1000                 # Ribbon的数据读取超时时间
    OkToRetryOnAllOperations: true  # 是否对所有操作都进行重试
    MaxAutoRetriesNextServer: 1     # 切换实例的重试次数
    MaxAutoRetries: 1                 # 对当前实例的重试次数
相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
2月前
|
负载均衡 算法 Java
Spring Cloud全解析:负载均衡算法
本文介绍了负载均衡的两种方式:集中式负载均衡和进程内负载均衡,以及常见的负载均衡算法,包括轮询、随机、源地址哈希、加权轮询、加权随机和最小连接数等方法,帮助读者更好地理解和应用负载均衡技术。
|
4月前
|
NoSQL Java Nacos
SpringCloud集成Seata并使用Nacos做注册中心与配置中心
SpringCloud集成Seata并使用Nacos做注册中心与配置中心
127 3
|
1天前
|
负载均衡 算法 Java
除了 Ribbon,Spring Cloud 中还有哪些负载均衡组件?
这些负载均衡组件各有特点,在不同的场景和需求下,可以根据项目的具体情况选择合适的负载均衡组件来实现高效、稳定的服务调用。
13 5
|
2月前
|
负载均衡 Java 对象存储
负载均衡策略:Spring Cloud与Netflix OSS的最佳实践
负载均衡策略:Spring Cloud与Netflix OSS的最佳实践
46 2
|
2月前
|
负载均衡 Java Nacos
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
微服务介绍、SpringCloud、服务拆分和远程调用、Eureka注册中心、Ribbon负载均衡、Nacos注册中心
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
|
3月前
|
负载均衡 算法 微服务
基于gRPC的注册发现与负载均衡的原理和实战
基于gRPC的注册发现与负载均衡的原理和实战
|
3月前
|
XML Java 数据格式
Spring Cloud全解析:注册中心之zookeeper注册中心
使用ZooKeeper作为Spring Cloud的注册中心无需单独部署服务器,直接利用ZooKeeper服务端功能。项目通过`spring-cloud-starter-zookeeper-discovery`依赖实现服务注册与发现。配置文件指定连接地址,如`localhost:2181`。启动应用后,服务自动注册到ZooKeeper的`/services`路径下,形成临时节点,包含服务实例信息。
290 3
|
4月前
|
负载均衡 Java Spring
Spring cloud gateway 如何在路由时进行负载均衡
Spring cloud gateway 如何在路由时进行负载均衡
473 15
|
4月前
|
Java Spring
spring cloud gateway在使用 zookeeper 注册中心时,配置https 进行服务转发
spring cloud gateway在使用 zookeeper 注册中心时,配置https 进行服务转发
109 3
|
5月前
|
Java Nacos 微服务
Spring Cloud微服务在Windows本地开发时禁用Nacos注册中心注册
Spring Cloud微服务在Windows本地开发时禁用Nacos注册中心注册