SpringCloud学习笔记(三)Ribbon负载均衡

目录

Ribbon概述

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。

LB(负载均衡)

LB,即负载均衡(Load Balance),在微服务或分布式集群中经常用的一种应用。
负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA。
常见的负载均衡有软件Nginx,LVS,硬件 F5等。
相应的在中间件,例如:dubbo和SpringCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义。

  • 集中式LB
    即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方;
  • 进程式LB
    将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。
    Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

Ribbon配置初步

修改Spring_pro_consume_80。
pom加入Ribbon和Eureka依赖

 <!-- Ribbon设置 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

在消费者启动类上添加Ribbon和Eureka客户端注解:

@EnableEurekaClient
@RibbonClient(name = "MICROSERVICE-ZUREKA-ALL")

name属性值为微服务名称,即为该微服务负载均衡。
修改RestTemplate类,增加load注解:

@Configuration
public class ConfigureBean {
    //
    @Bean
    @LoadBalanced //负载均衡注解
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

修改application.yml,加入Eureka注册信息。

server:
  port: 80
eureka:
  client:
    register-with-eureka: false     #false表示不向注册中心注册自己。
    fetch-registry: true     #false表示自己端就是注册中心
    service-url:
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
      defaultZone: http://eureka7002:7002/eureka/,http://eureka7003:7003/eureka/,http://eureka7001:7001/eureka

修改客户端访问类:

@RestController
public class UserController {

    private static final String REST_URL_PREFIX = "http://MICROSERVICE-ZUREKA-ALL";
    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping(value = {"/consume/alluser"}, method = RequestMethod.GET)
    public List<User> query() {
        //System.out.println(restTemplate.getForObject(REST_URL_PREFIX + "/alluser", List.class).toString());
        return restTemplate.getForObject(REST_URL_PREFIX + "/alluser", List.class);

    }

Ribbon和Eureka整合后Consumer可以直接调用服务而不用再关心地址和端口号。

Ribbon负载均衡

在这里插入图片描述
前面提到Ribbon是基于客户端的负载均衡,所以Ribbon的配置一般在消费端。
Ribbon的工作方式分为:
第一步先选择 EurekaServer ,它优先选择在同一个区域内负载较少的server.
第二步再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址。
其中Ribbon提供了多种策略:比如轮询、随机和根据响应时间加权。

测试

第一步:
需要创建三个微服务实例,他们服务名称一致,提供统一服务。
复制Spring_pro_provide_8001的application.yml文件,修改名称为application-01.yml、application-02.yml。
在这里插入图片描述
三个微服务的spring.application.name都为:microservice-zureka-all
可以将instance-id修改,区分三个实例。
分别为:
spring_pro_provide_8001
spring_pro_provide_8002
spring_pro_provide_8003

第二步:
为了验证Ribbon负载均衡的不同策略,需要创建三个不同的数据库,三个微服务分别从这三个数据库返回数据,用来区分当启用不同的负载均衡策略时,服务的调用情况。
本地创建microservce2、microservce1、microservce三个数据。
调用情况为:
spring_pro_provide_8001 microservce
spring_pro_provide_8002 microservce1
spring_pro_provide_8003 microservce2
在这里插入图片描述
修改完成后,依次启动Eureka集群、服务提供者集群、服务消费者。
在这里插入图片描述
如图所示,三个微服务已经成功注册到Eureka注册中心,同时Eureka集群服务也成功启动。
调用测试,消费者成功启动后,调用接口,查看返回的数据。
第一次请求返回数据库3,表明消费者调用了微服务spring_pro_provide8003。
在这里插入图片描述
第二次刷新后,如图。
在这里插入图片描述
请求返回数据库2,表明消费者调用了微服务spring_pro_provide8002。
第三次刷新后,如图。
在这里插入图片描述
请求返回数据库1,表明消费者调用了微服务spring_pro_provide8001。

可以看出Ribbon服务启用了,采用默认的轮询策略去访问三个微服务提供者。
如果想采用随机、响应时间或者自定义策略,可以创建Irule对象,并注入bean。
在这里插入图片描述
此时Ribbon策略为随机算法。

自定义算法

创建自定义类RandomSun,继承AbstractLoadBalancerRule。

package sun.nwnu.myrule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.*;

import java.util.List;


public class RandomSun extends AbstractLoadBalancerRule {
   private int ruletotal = 0;
   private int ruleindex = 0;

    @SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        } else {
            Server server = null;

            while(server == null) {
                if (Thread.interrupted()) {
                    return null;
                }

                List<Server> upList = lb.getReachableServers();
                List<Server> allList = lb.getAllServers();
                int serverCount = allList.size();
                if (serverCount == 0) {
                    return null;
                }
                //自定义轮询算法,规则为每个服务被击中5次后轮询下个服务
                if(ruletotal < 5){
                    server = (Server)upList.get(ruleindex);
                    ruletotal++;
                }else {
                    ruletotal = 0;
                    ruleindex++;
                    if(ruleindex >= upList.size()){
                        ruleindex =0;
                        ruletotal =0;
                    }
                }

                if (server == null) {
                    Thread.yield();
                } else {
                    if (server.isAlive()) {
                        return server;
                    }

                    server = null;
                    Thread.yield();
                }
            }

            return server;
        }
    }

    public Server choose(Object key) {
        return this.choose(this.getLoadBalancer(), key);
    }

    public void initWithNiwsConfig(IClientConfig clientConfig) {
    }

}

创建MyselfRule。

@Configuration
public class MyselfRule {
    /**
     *
     * @return 返回Ribbon的策略
     */
    public IRule getrule(){
        return new RandomSun();
    }
}

此时,自定义算法规则为每个服务被击中5次后轮询下个服务。

Ribbon核心组件IRule

IRule:根据特定算法中从服务器列表中选取一个要访问的服务,Ribbon默认的算法为ZoneAvoidanceRule;

Ribbon中的7中负载均衡算法:

(1)RoundRobinRule:轮询;

(2)RandomRule:随机;

(3)AvailabilityFilteringRule:会先过滤掉由于多次访问故障而处于断路器状态的服务,还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问;

(4)WeightedResponseTimeRule:根据平均响应时间计算所有服务的权重,响应时间越快的服务权重越大被选中的概率越大。刚启动时如果统计信息不足,则使用RoundRobinRule(轮询)策略,等统计信息足够,会切换到WeightedResponseTimeRule;

(5)RetryRule:先按照RoundRobinRule(轮询)策略获取服务,如果获取服务失败则在指定时间内进行重试,获取可用的服务;

(6)BestAvailableRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务;

(7)ZoneAvoidanceRule:复合判断Server所在区域的性能和Server的可用性选择服务器,在没有Zone的情况下是类似轮询的算法;

ribbion的负载均衡算法结构:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值