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); }