springCloud之Eureka之负载均衡Ribbon

引言

说完了注册中心Eureka,虽然Eureka可以实现服务的发现和调用,但在微服务体系中,服务的发现和调用往往是需要伴随着负载均衡这个概念一体的。而在SpringCloud中自然也存在着与Eureka配套的负载均衡组件,也就是Ribbon组件。

Ribbon介绍

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套 客户端 负载均衡 工具

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

使用 Ribbon 工作原理

所有的项目都会注册到 Eureka 中,Eureka 允许不同项目的 spring.application.name 相同。当相同时会认为是这些项目是一个集群,所以同一个项目部署多次都是设置应用程序名相同。

Application Client 会从 Eureka 中根据 spring.application.name 加载 Application Service 的列表。根据设定的负载均衡算法,从列表中取出一个 URL,到此 Ribbon 的事情结束。剩下的事情由程序员自己进行技术选型,选择一个 HTTP 协议工具,通过这个 URL 调用 Application Service。

注意:以下事情和 Ribbon 没有关系的
Application Service 注册到 Eureka 过程。这是 Eureka 的功能。
Application Client 从 Eureka 取出注册列表。这是 Eureka 的功能。
Application Client 通过 URL 访问 Application Service 。这个根据自己使用的 HTTP 工具。
只有 Application Client 从 Eureka 中取出列表后进行负载均衡算法的过程和Ribbon有关。

Ribbon使用

  • 1.导入依赖,需要在消费者中导入ribbon和eureka依赖
    在这里插入图片描述
 <!--Ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <!--Eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
  • 2.配置文件
#Eureka
eureka:
client:
  register-with-eureka: false #不在注册中心注册自己
  service-url:
    defaultZone : http://eureka8001.com:8001/eureka/,http://eureka8002.com:8002/eureka/,http://eureka8003.com:8003/eureka/
  • 3.添加负载均衡注解
@Configuration
public class BeanConfig {

 @Bean
 @LoadBalanced //Ribbon开启负载均衡
 public RestTemplate getRestTemplate(){
     
     return  new RestTemplate();
 }

}
  • 4.启动类添加Eureka注解
    在这里插入图片描述

配置多个服务提供者

为了明确的表示,注册中心和负载均衡的功能实现,启动三个Eureka服务,启动三个服务提供者,启动一个服务消费者,目标实现==调用服务消费者相同的接口,调用不同的服务提供者的服务。==不同的服务返回不同的id:7001,7002,7003
在这里插入图片描述
项目启动后,每一个eureka中有两个eureka服务,相同的application有对应三个服务提供者
在这里插入图片描述
访问相同的服务地址,负载均衡到不同的服务提供者,不影响返回的结果。(id为了区分不同的服务而设置)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Ribbon核心组件IRule实现负载均衡算法

IRule:根据特定算法从服务列表中选取一个要访问的服务。默认是轮询
每一接口实现,都是一个负载均衡策略
在这里插入图片描述
设置随机的负载均衡策略
在配置类中,生成一个有spring管理的IRule对象,当项目启动后如果有spring管理的bean,则用相应的负载均衡策略,如果没有,则使用默认的随机策略。

@Configuration
public class BeanConfig {

    @Bean
    @LoadBalanced //Ribbon开启负载君和的注解
    //AvailabilityFilteringRule 过滤掉跳闸,加载慢。。的服务,其他的轮询
    //RandomRule 随机
    //RetryRule 重试
    //RoundRobinRule 轮询
    //WeightedResponseTimeRule 设置权重
    public RestTemplate getRestTemplate(){

        return  new RestTemplate();
    }
    //设置随机的负载均衡策略
    @Bean
    public IRule myRule(){
        return  new RandomRule();
    }

}

自定义负载均衡策略(依次访问3次,循环访问)

  • .模仿实现类
    在这里插入图片描述
  • 具体代码实现
package com.kuang.myRule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class myRule extends AbstractLoadBalancerRule {
    private int total =0;
    private int currentIndex =0;
    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;
                }
                //自定义部分代码开始
                if(total<3){
                    server =upList.get(currentIndex);
                    total++;
                }else{
                    total=1;
                    currentIndex++;
                   if(currentIndex>allList.size()-1){//如果有服务挂起,不会报错
                        currentIndex=0;
                    }
                }
                server =upList.get(currentIndex);
                //自定义部分代码结束

                //原随机代码
                //int index = this.chooseRandomInt(serverCount); 获取随机下标
               // server = (Server)upList.get(index); 获取server
                if (server == null) {
                    Thread.yield();
                } else {
                    if (server.isAlive()) {
                        return server;
                    }

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

            return server;
        }
    }

    protected int chooseRandomInt(int serverCount) {
        return ThreadLocalRandom.current().nextInt(serverCount);
    }

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

    public void initWithNiwsConfig(IClientConfig clientConfig) {
    }

}
  • 将配置类中的负载均衡换成自定义
    在这里插入图片描述
    这样就可以实现没有服务轮询三次的负载均衡策略。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值