Spring Cloud 学习 | - 04 - 自定义Ribbon负载均衡策略

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/E09620126/article/details/88900410

Spring Cloud 学习 | - 04 - 自定义Ribbon负载均衡策略

学习 Spring Cloud 之路,文中 Spring Boot 版本为 2.1.3.RELEASESpring Cloud 版本为 Greenwich.SR1 。因能力有限,难免会有不足或者错误之处,还望不吝指正,谢!

接上篇 Spring Cloud 学习 | - 03 - 服务消费(Rest + Ribbon实现负载均衡),我们使用Rest+Ribbon实现了负载均衡,默认策略是轮询策略。接下来,我们看看怎么修改负载均衡的规则。

1. 启动Eureka

具体Eureka相关的,这里就不再赘述,详情请参阅之前的文章内容。这里贴一下基本的配置及代码。

1.1 Eureka依赖:

主要Maven依赖:

		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

1.2 配置文件

application.yml

## app port conf
server:
  port: 8761
spring:
  application:
    name: spring-cloud-eureka
eureka:
  client:
    service-url:
      # EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其它Server的地址
      defaultZone: http://localhost:${server.port}/eureka
    register-with-eureka: false #由于该应用为注册中心,所以设置为false,代表不向注册中心注册自己
    fetch-registry: false #由于注册中心的职责就是维护服务实例,它并不需要去检索服务,所以也设置为false
  server:
    enable-self-preservation: false # 关闭自我保护机制

1.3 开启EurekaServer功能

@SpringBootApplication
@EnableEurekaServer
public class SpringCloudEurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaApplication.class, args);
    }
}

启动Eureka服务。

2. 启动服务提供者

具体这里就不详细说明了,请查阅前一篇博文,这里主要贴一下主要配置和代码。

2.1 主要依赖

		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2.2 配置文件

server:
  port: 8090
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
  instance:
    prefer-ip-address: true # 返回ip而不是host名称
#    ip-address: 127.0.0.1 # 指定自己的ip信息
    lease-expiration-duration-in-seconds: 15 # 服务失效时间,默认值90秒
    lease-renewal-interval-in-seconds: 5 # 服务续约(renew)的间隔,默认为30秒
spring:
  application:
    name: user-provider

2.3 启用服务发现注解

@SpringBootApplication
@EnableDiscoveryClient
public class UserProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserProviderApplication.class, args);
    }
}

2.4 Service

@Service
public class UserServiceImpl implements UserService {
    /**
     * 查询所有用户
     * @return
     */
    @Override
    public List findAll() {
        List list = Arrays.asList("Cindy","Pony","Marry");
        return list;
    }
}

2.5 Controller

@RestController
@RequestMapping("/user")
public class UserController {
    @Value("${server.port}")
    private String port;
    @Autowired
    private UserService userService;

    @GetMapping("/list")
    public Map list(){
        Map<String,Object> data = new HashMap<>(16);
        data.put("port", port);
        data.put("rows", userService.findAll());
        return data;
    }
}

2.6 启动服务

分别启动2个user-provider服务,端口分别为80908091,详细步骤请参阅上一篇博文。
启动完成后,查看eureka注册中心:
在这里插入图片描述

3. 自定义负载均衡策略

3.1 新建一个测试类和方法

我们用LoadBalancerClient获取应用实例,在控制台输入主机和端口,重复10次。

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserConsumerApplicationTests {

    @Autowired(required = false)
    private LoadBalancerClient client;

    @Test
    public void testRule(){
        for (int i = 0; i < 10; i++) {
            ServiceInstance instance = client.choose("user-provider");
            String host = instance.getHost();
            int port = instance.getPort();
            System.err.println("Host=" + host + ",port=" + port);
        }
    }
}

先来看一下,默认的轮询测试结果:
在这里插入图片描述
结果是顺序轮流的调用。

3.2 修改负载均衡规则

我们只要注入一个实现IRule的Bean即可,这里注入Ribbon里自带的一个规则为例(其他的,请实现IRule接口即可),默认实现的规则有:
在这里插入图片描述
这里以RandomRule为例:
新建一个Configuration配置类,或者直接在启动类XxxApplication里注入IRule的Bean:

    @Bean
    public IRule customRule(){
        return new RandomRule();
    }

这样便可以了。我们测试一下:
在这里插入图片描述
输出结果是随机的,证明随机的策略生效了。
下边我们说下,对指定的服务配置负载均衡策略的方法。

3.3 自定义负载均衡策略

3.3.1 方式一配置文件.yml实现

官方的说明文档如下:
在这里插入图片描述
.yml配置的格式:<clientName>.ribbon.NFLoadBalancerRuleClassName:自定义的Rule规则类(需要实现IRule接口),我们修改自己的.yml配置,新增如下内容:

user-provider: # 我们为user-provider这个服务配置自定义的策略
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 自定义的策略类

注释掉刚才全局的策略配置:

    // @Bean
    // public IRule customRule(){
    //     return new RandomRule();
    // }

这样就OK了,我们测试游戏,是不是随机的调用规则:
在这里插入图片描述
我们看到是随机的,配置正确。

3.3.2 方式二配置类Configuration实现

  • 先注释掉刚才的.yml配置方式代码:

    #user-provider: # 我们为user-provider这个服务配置自定义的策略
    #  ribbon:
    #    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 自定义的策略类
    
  • 我们新建一个Rrule配置类,这个类要注意下package的位置,不能再XxxApplication启动类同级及其子包下,Sprig Cloud官方文档说明如下:
    在这里插入图片描述

  • 新建配置类CustomRuleConfig,路径如下
    在这里插入图片描述

    @Configuration
    public class CustomRuleConfig {
        @Bean
        public IRule customRule(){
            return new RandomRule();
        }
    }
    
  • 修改启动类XxxApplication,添加注解@RibbonClient

    @SpringBootApplication
    @EnableDiscoveryClient
    @RibbonClient(name = "user-provider",configuration = CustomRuleConfig.class)
    public class UserConsumerApplication {
        public static void main(String[] args) {
            SpringApplication.run(UserConsumerApplication.class, args);
        }
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    

    name:表示是指定哪个服务启用这个策略,
    configuration :表示指定哪个自定义的策略规则

  • 好了,我们测试一下:
    在这里插入图片描述
    结果是随机的,采用了指定负载均衡的规则。

4. 附:Ribbon内嵌的7种负载均衡的策略说明:

No. Rule Desc
1 RoundRobinRule 轮询
2 RandomRule 随机
3 AvailabilityFilteringRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数量超过阈值的服 务,然后对剩余的服务列表按照轮询策略进行访问
4 WeightedResponseTimeRule 根据平均响应事件计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高,刚启动时如果统计信息不足,则使用RoundRobinRule 策略,等统计信息足够,会切换到WeightedResponseTimeRule
5 RetryRule 先按照RoundRobinRule 的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务
6 BestAvailableRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
7 ZoneAvoidanceRule 复合判断server所在区域的性能和server的可用性选择服务器

猜你喜欢

转载自blog.csdn.net/E09620126/article/details/88900410