springcloud-Ribbon之手写轮询算法

  接下来是跟着阳哥进行算法的手写。先说一下看前想法:起初我以为 阳哥 是 自定义 一个类 去实现 ILoadBalancer接口,然后在实现类里面实现算法逻辑。然后发现我错了,根本就不是那么回事,也就是手写的轮询代码跟 底层代码压 没啥联系,单纯地根据轮询公式 拿到 哪台服务实例下标,然后拿到该服务器势力的URI 进行访问而已,是在下想多了。下面说实现思路。

  前提是记得把@LoadBalanced注释掉,由我们自己决定哪台服务器实例

 //@LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

  1.创建一个接口 LoadBalance,定义一个方法,该方法就是拿到 提供服务的 服务器实例

public interface LoadBalanced {

    public ServiceInstance getNextServerIns(List<ServiceInstance> serviceInstances); //得到提供服务的服务实例
}

  2.创建一个实现类,实现该接口

@Component
public class MyLB implements LoadBalanced {

    private static final AtomicInteger curr = new AtomicInteger(0);

    @Override
    public ServiceInstance getNextServerIns(List<ServiceInstance> serviceInstances) {

        //拿到当前 第几次 请求
        int next = getAndIncre();

        //得到当前服务器的下标
        int currentServerIndex = next % serviceInstances.size();

        //返回服务器
        return serviceInstances.get(currentServerIndex);
    }

    private static final int getAndIncre() {

        int current;
        int next;
        do {
            //获取当前请求总数
            current = curr.get();
            //请求总数+1
            next = (current+1)>=Integer.MAX_VALUE?1:current+1;
        }while (!curr.compareAndSet(current, next));

        return next;
    }
}

  3.测试代码。

    @Autowired
    private LoadBalanced loadBalanced;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private RestTemplate restTemplate;
@GetMapping(
"/consumer/payment/myrule") public String myLB(){ List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE"); ServiceInstance instance = loadBalanced.getNextServerIns(instances); URI uri = instance.getUri(); return restTemplate.getForObject(uri+"/payment/myrule",String.class); }

 

posted @ 2021-02-21 21:20  爱编程DE文兄  阅读(156)  评论(0编辑  收藏  举报