Ribbon深入了解原理

首先屏蔽掉OrderMain80.java的注解:

//@RibbonClient(name="CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)

原理:

负载均衡算法:

轮询:

Rest接口第几次请求数%服务器集群总数=实际调用服务器位置下标。每次服务重启rest接口计数从1开始

假如总计二台服务器,一个接口第一次调服务器01,第三次调用还是01,第八次调用是服务器02

可以看到IRule的源码

public interface IRule {     Server choose(Object var1);     void setLoadBalancer(ILoadBalancer var1);     ILoadBalancer getLoadBalancer(); }

接下来看RoundRobinRule

RoundRobinRule extends AbstractLoadBalancerRule

(AbstractLoadBalancerRule implements IRule, IClientConfigAware)

看看实现的choose方法

public Server choose(ILoadBalancer lb, Object key) {     if (lb == null) {         log.warn("no load balancer");         return null;     } else {         Server server = null;         int count = 0;         while(true) {             if (server == null && count++ < 10) {                 List reachableServers = lb.getReachableServers();                 List allServers = lb.getAllServers();                 int upCount = reachableServers.size();                 int serverCount = allServers.size();                 if (upCount != 0 && serverCount != 0) {                     int nextServerIndex = this.incrementAndGetModulo(serverCount);                     server = (Server)allServers.get(nextServerIndex);                     if (server == null) {                         Thread.yield();                     } else {                         if (server.isAlive() && server.isReadyToServe()) {                             return server;                         }                         server = null;                     }                     continue;                 }                 log.warn("No up servers available from load balancer: " + lb);                 return null;             }             if (count >= 10) {                 log.warn("No available alive servers after 10 tries from load balancer: " + lb);             }             return server;         }     } }

private int incrementAndGetModulo(int modulo) {     int current;     int next;     do {         current = this.nextServerCyclicCounter.get();         next = (current + 1) % modulo;     } while(!this.nextServerCyclicCounter.compareAndSet(current, next));     return next; }

手写一个负载算法

保证7001/7002集群启动

接着对8001/8002微服务进行改造

在它们的controller中加入:

@GetMapping(value="/payment/lb")public String getPaymentLB(){     return serverPort; }

接着对order80进行改造

把ApplicationContextConfig的@LoadBalanced注释掉

新建一个lb,创建LoadBalancer接口

public interface LoadBalancer {     ServiceInstance instances(List serviceInstances); }

再搞个实现类

@Componentpublic class MyLB implements LoadBalancer{         private AtomicInteger atomicInteger = new AtomicInteger(0);         public final int getAndIncrement(){         int current;         int next;         do{             current = this.atomicInteger.get();             //整型最大值为2147483647             next = current>=2147483647?0:current+1;         }while (!this.atomicInteger.compareAndSet(current,next));         System.out.println("======================第几次访问: "+next);         return next;     }         @Override     public ServiceInstance instances(List serviceInstances) {         int index = getAndIncrement()%serviceInstances.size();         return serviceInstances.get(index);     } }

再回到OrderController中,加入

@Resourceprivate LoadBalancer loadBalancer;@Resourceprivate DiscoveryClient discoveryClient;

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

访问http://localhost/consumer/payment/lb   会发现一直在8001和8002之间变化

后台也一直在刷

======================第几次访问: 1

======================第几次访问: 2

======================第几次访问: 3

======================第几次访问: 4

======================第几次访问: 5

======================第几次访问: 6

以上为40-42集的内容

好文链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: