看了Ribbon的负载均衡算法,手写一个轮询的负载均衡算法
1.首先先把RestTemplate上的@LoadBanced去掉,使用自己的均衡算法
2.创建LoadBancer接口,方便Spring注入,方法为接收服务集群后返回其中一个服务
1 public interface LoadBalancer { 2 ServiceInstance instance(List<ServiceInstance> serviceInstances); 3 }
3.创建子类实现方法(主要思想为CAS实现轮询)
1 @Component 2 public class MyLoadBalancer implements LoadBalancer{ 3 4 private AtomicInteger atomicInteger = new AtomicInteger(0);//多线程下保证安全,记录下访问次数,并算出返回的服务下标 5 6 public final int getAndIncrement() { 7 int current; 8 int next; 9 do { 10 current = this.atomicInteger.get(); 11 next = current >= 2147483647 ? 0 :current + 1;//防止int溢出 12 }while (!atomicInteger.compareAndSet(current, next));//CAS 13 System.out.println("*****第"+next+"次访问*****");//打印方便看效果 14 return next; 15 } 16 17 @Override 18 public ServiceInstance instance(List<ServiceInstance> serviceInstances) { 19 int index = getAndIncrement() % serviceInstances.size();//根据第几次访问得出本次服务器下标 20 return serviceInstances.get(index);//返回 21 } 22 }
4.消费者Controller进行测试
1 @GetMapping(value = "/test/loadbalancer") 2 public String testLoadBalancer() { 3 List<ServiceInstance> serviceInstances = discoveryClient.getInstances("SERVICE-NAME"); 4 if (serviceInstances == null || serviceInstances.size() <= 0) { 5 return null; 6 } 7 ServiceInstance serviceInstance = loadBalancer.instance(serviceInstances); 8 URI uri = serviceInstance.getUri(); 9 return restTemplate.getForObject(uri+"/show/serverport", String.class); 10 }
5.服务提供者显示出轮询的效果
1 @Value("${server.port}") 2 private String serverPort; 3 @GetMapping(value = "/show/serverport") 4 public String getPaymentLB() { 5 return serverPort; 6 }
原文:https://www.cnblogs.com/2016024249-/p/12514642.html