栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Ribbon负载均衡(二)Ribbon负载均衡策略

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Ribbon负载均衡(二)Ribbon负载均衡策略

Ribbon负载均衡策略

文章目录
      • Ribbon负载均衡策略
        • 1.默认-轮询策略
          • 1.1 修改User服务,使用Ribbon默认轮询策略
          • 1.2 RestTemplate配置
          • 1.3 RestTemplate访问Order订单服务
          • 1.4 重启user服务
          • 1.5 测试Ribbon轮询访问
        • 2.随机策略
          • 2.1 定义RandomLoadBalancer 随机负载均衡策略
          • 2.2 LoadBalancerClients指定使用策略
          • 2.3 重启user服务,验证随机策略

Ribbon默认的是轮询策略,那么还有其他策略么?该如何使用其他策略
Ribbon 一共7 种策略

  1. 轮询策略 RoundRobinRule
  2. 随机策略 RandomRule
  3. 轮询重试策略 RetryRule
  4. 响应速度决定权重 WeightedResponseTimeRule
  5. 最优可用 BestAvailableRule, 采用并发连接数判断最优,连接数最小的节点
  6. 可用性过滤规则 AvailabilityFilteringRule
  7. 区域内可用性能最优 ZoneAvoidanceRule

如果需要一些前置配置的比如服务创建及Eureka使用,可以看下上一篇文章
Ribbon负载均衡(一)Ribbon实战
我使用的版本如下

本文使用的版本是 Springboot-2.6.7 ,Spring Cloud -2021.0.2 , Eureka 版本3.1.2

这坑爹玩意,这里面在Eureka 下面的jar包中是没有ribbon的, 没IRule接口,如何定义负载均衡策略 ?推荐使用 Springcloud LoadBalancer 替换Ribbon

Springcloud LoadBalancer只有两种负载均衡策略+自定义负载均衡策略


springcloud 2020.0.1 版本之后 删除了eureka中的ribbon,替代ribbon的是spring cloud自带的LoadBalancer
Spring-cloud-starter-loadbalancer 的jar 这个应该是和Ribbon的功能一样,但是他就提供了RandomLoadBalancer 随机 和RoundRobinLoadBalancer 轮询的方式,默认使用的是轮询的方式

1.默认-轮询策略

我们改造一下

1.1 修改User服务,使用Ribbon默认轮询策略

增加config/RestTemplateConfig 配置文件, 引入RestTemplate便于访问http接口

1.2 RestTemplate配置

RestTemplateConfig.java

package com.ribbon.user.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

        //如果不加上面的注释 @LoadBalanced 就不会从eureka上获取 order服务地址, 也就不会使用负载均衡,
        // 你访问的 http://order/order order服务的host就会找不到
        @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

1.3 RestTemplate访问Order订单服务
package com.ribbon.user.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
@Slf4j
public class UserController {


    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/user")
    public String test() {
        log.info("client 发起UserController");
        return "user";
    }


    @GetMapping("/testribbon")
    public String testRibbon() {

        //restTemplate 请求访问 order订单服务的 order URL ,
        // 参数URL   http://order/order   第一个order 就是服务名字 就是注册在Eureka上的 服务名字 第二个order就是 controller 入口
        // 第二个参数String.class 就是 访问返回值
        String result = restTemplate.getForObject("http://order/order", String.class);
        log.info("user 发起UserController 测试ribbon 调用 :{} ", result);
        return result;
    }

}

1.4 重启user服务

访问 localhost:8088/testribbon
如果报错, 看下你的RestTemplate种的@LoadBalanced 注解是否加上,不加上默认是使用正常的restTemplate 访问IP+PORT ,你的URL是 http://order/order 不会去Eureka上获取order服务的地址及端口的

没有@LoadBalanced 注解 会报如下错误
nested exception is java.net.UnknownHostException: order] with root cause
java.net.UnknownHostException: order

2022-05-15 21:51:03.169 ERROR 6216 --- [nio-8088-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://order/order": order; nested exception is java.net.UnknownHostException: order] with root cause

java.net.UnknownHostException: order
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184) ~[na:1.8.0_181]

服务正常启动

1.5 测试Ribbon轮询访问

访问testribbon接口,看看RestTemplate访问的是否是轮询访问三个节点中的一个
可以看到顺序那都是 two,one,three,的确是轮询访问三个服务

2.随机策略

如何实现Ribbon对order服务随机策略?我们只要定制规则即可? 但是我们已经没了Ribbon 所以你是引入不了 IRule 接口去重新定义Rule负载均衡策略的,咋办?????

SpringCloud重新定义了一套 ReactorLoadBalancer 策略

2.1 定义RandomLoadBalancer 随机负载均衡策略

定义随机策略

package com.ribbon.user.config;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;



public class CustomLoadBalancerConfiguration {

    @Bean
    ReactorLoadBalancer randomLoadBalancer(Environment environment,
                                                            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(loadBalancerClientFactory
                .getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    }
}

为什么这个类上不加 @Configuration 让Spring 扫描到它? 因为官方文档中给除了明确说法 不要加注释@Configuration 或者你可以在Spring 包扫描外 新建这个配置

2.2 LoadBalancerClients指定使用策略

修改RestTemplateConfig 配置文件 ,很重要!!!!!
配置LoadBalancerClients 指定你的 service服务 及使用的负载均衡策略

package com.ribbon.user.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;


@Configuration

//在这里配置我们自定义的LoadBalancer策略
// 如果扩展算法 需要自己去实现ReactorServiceInstanceLoadBalancer接口
// 标准@LoadBalancerClients(defaultConfiguration = {name = "CLOUD-PAYMENT-SERVICE", configuration = CustomLoadBalancerConfiguration.class})
//注意这里的name属性 需要和eureka页面中的服务提供者名字保持一致
@LoadBalancerClient(name = "order", configuration = CustomLoadBalancerConfiguration.class)
public class RestTemplateConfig {

    //如果不加上面的注释 @LoadBalanced 就不会从eureka上获取 order服务地址, 也就不会使用负载均衡,
    // 你访问的 http://order/order order服务的host就会找不到
    @Bean
    @LoadBalanced
    //使用这个     @LoadBalanced 注解给restTemplate赋予了负载均衡的能力
    RestTemplate restTemplate() {
        return new RestTemplate();
    }


}

2.3 重启user服务,验证随机策略

访问 http://localhost:8088/testribbon 接口 可以看到 随机取调用某台节点
实现了随机访问的负载均衡模式


至此我们已经简单的可以使用 SpringCloud LoadBalancer了 , 这两种都是基本的负载均衡策略,下一篇 我们介绍下 如何用 SpringCloud LoadBalancer 取自定义负载均衡策略

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/888700.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号