Ribbon的使用说明

Ribbon,一个软负载均衡的客户端组件

核心就是负载均衡的算法+RestTemplate
负载均衡的方法(IRule):
1 轮询
2 随机
3 权重
4 最佳(出错最少的)

pom的引入。
开始我引入的ribbon的gav,后来发现就是netfix-eureka-client自己继承了ribbon,所以就不用再引入ribbon的gav了
如图:
在这里插入图片描述

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

新建一个ribbon的规则包,因为官网写的不能把规则写再@co’mponentscan扫描的包和子包下,因为@SpringBootApplication包含这个注解,所以需要再同一级新建一个包编写规则
在这里插入图片描述
编写配置,这里暂时定义为随机的方式
在这里插入图片描述

添加@RibbonClient
在这里插入图片描述
启动服务:
我这里是先出现了3个8001再出现8002不规则的,

手写ribbon算法
先理解一下ribbon负载均衡的算法
rest接口第几次请求数%服务器集群总数量=实际调用服务器位置下标,每次服务重启后rest从1开始
就是从注册中心发现服务,然后看有多少个服务来获取下标,用下标来调用
假如发现了两个服务:
1%2。。。1(余数) index[1]
2%2。。。 0 index[0]



就下标0,1,0,1。。。这样调用就实现了轮询
要自己实现就需要知道怎么来的,这是根据idea生成的脑图
在这里插入图片描述

进入IRule看一下怎么定义的
在这里插入图片描述
继承了AbstractLoadBalancerRule
在这里插入图片描述

//选择
public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            log.warn("no load balancer");
            return null;
        }

        Server server = null;
        int count = 0;
        while (server == null && count++ < 10) {
            List<Server> reachableServers = lb.getReachableServers();
            List<Server> allServers = lb.getAllServers();
            int upCount = reachableServers.size();
            int serverCount = allServers.size();

            if ((upCount == 0) || (serverCount == 0)) {
                log.warn("No up servers available from load balancer: " + lb);
                return null;
            }

            int nextServerIndex = incrementAndGetModulo(serverCount);
            server = allServers.get(nextServerIndex);

            if (server == null) {
                /* Transient. */
                Thread.yield();
                continue;
            }

            if (server.isAlive() && (server.isReadyToServe())) {
                return (server);
            }

            // Next.
            server = null;
        }

        if (count >= 10) {
            log.warn("No available alive servers after 10 tries from load balancer: "
                    + lb);
        }
        return server;
    }

    /**
     * Inspired by the implementation of {@link AtomicInteger#incrementAndGet()}.
     *
     * @param modulo The modulo to bound the value of the counter.
     * @return The next value.
     */
    private int incrementAndGetModulo(int modulo) {
    //自旋锁,compareAndSet,选择判断并交换
        for (;;) {
            int current = nextServerCyclicCounter.get();
            int next = (current + 1) % modulo;
            if (nextServerCyclicCounter.compareAndSet(current, next))
                return next;
        }
    }

    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(), key);
    }

在服务调用端新增测试接口
在这里插入图片描述
两个服务都写一个,方便测试

修改80服务,去掉@LoadBalanced
在这里插入图片描述
编写一个loadbalabcend接口并实现

@Component
public class MyLB implements LoadBalanced{
    //编写一个原子类,初始值为0
    private AtomicInteger atomicInteger = new AtomicInteger(0);

    //坐标
    private final int getAndIncrement(){
        int current;
        int next;
        do {
            current = this.atomicInteger.get();
            next = current >= 2147483647 ? 0 : current + 1;//整形的最大值
        }while (!this.atomicInteger.compareAndSet(current,next));  //第一个参数是期望值,第二个参数是修改值
        System.out.println("*******第几次访问,次数next: "+next);
        return next;
    }

    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
        int index = getAndIncrement() % serviceInstances.size(); //得到服务器的下标位置
        return serviceInstances.get(index);
    }
}

在controller层调用

@GetMapping(value = "/consumer/payment/lb")
    public String getPaymentLB(){
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        if (instances == null || instances.size() <= 0){
            return null;
        }
        ServiceInstance serviceInstance = loadBalanced.instances(instances);
        URI uri = serviceInstance.getUri();
        return restTemplate.getForObject(uri+"/payment/lb",String.class);
    }

启动服务,访问,就实现了简单的轮询的负载均衡在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值