博客
关于我
Ribbon 负载均衡调用04——ribbon 负载均衡算法||手写轮询算法(原理+JUC)CAS+自旋锁
阅读量:520 次
发布时间:2019-03-07

本文共 6930 字,大约阅读时间需要 23 分钟。





RoundRobinRule.java  源码剖析

/* * * Copyright 2013 Netflix, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */package com.netflix.loadbalancer;import com.netflix.client.config.IClientConfig;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.util.List;import java.util.concurrent.atomic.AtomicInteger;/** * The most well known and basic load balancing strategy, i.e. Round Robin Rule. * * @author stonse * @author Nikos Michalakis 
* */public class RoundRobinRule extends AbstractLoadBalancerRule { private AtomicInteger nextServerCyclicCounter; private static final boolean AVAILABLE_ONLY_SERVERS = true; private static final boolean ALL_SERVERS = false; private static Logger log = LoggerFactory.getLogger(RoundRobinRule.class); public RoundRobinRule() { nextServerCyclicCounter = new AtomicInteger(0); } public RoundRobinRule(ILoadBalancer lb) { this(); setLoadBalancer(lb); } 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
reachableServers = lb.getReachableServers(); List
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) { 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); } @Override public void initWithNiwsConfig(IClientConfig clientConfig) { }}






LoadBalancer.java

package com.dym.springcloud.lb;import org.springframework.cloud.client.ServiceInstance;import java.util.List;public interface LoadBalancer{    ServiceInstance instances(List
serviceInstances);}

MyLB.java

package com.dym.springcloud.lb;import org.springframework.cloud.client.ServiceInstance;import org.springframework.stereotype.Component;import java.util.List;import java.util.concurrent.atomic.AtomicInteger;@Componentpublic class MyLB implements LoadBalancer{    private AtomicInteger atomicInteger = new AtomicInteger(0);    public 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;    }    //负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标  ,每次服务重启动后rest接口计数从1开始。    @Override    public ServiceInstance instances(List
serviceInstances) { int index = getAndIncrement() % serviceInstances.size(); return serviceInstances.get(index); }}

OrderController.java

package com.dym.springcloud.controller;import com.dym.springcloud.entities.CommonResult;import com.dym.springcloud.entities.Payment;import com.dym.springcloud.lb.LoadBalancer;import lombok.extern.slf4j.Slf4j;import org.springframework.cloud.client.ServiceInstance;import org.springframework.cloud.client.discovery.DiscoveryClient;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;import java.net.URI;import java.util.List;@RestController@Slf4jpublic class OrderController{    //public static final String PAYMENT_URL = "http://localhost:8001";    public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";    @Resource    private RestTemplate restTemplate;    @Resource    private LoadBalancer loadBalancer;    @Resource    private DiscoveryClient discoveryClient;    @GetMapping("/consumer/payment/create")    public CommonResult
create(Payment payment) { return restTemplate.postForObject(PAYMENT_URL +"/payment/create",payment,CommonResult.class); } @GetMapping("/consumer/payment/get/{id}") public CommonResult
getPayment(@PathVariable("id") Long id) { return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class); } @GetMapping("/consumer/payment/getForEntity/{id}") public CommonResult
getPayment2(@PathVariable("id") Long id) { ResponseEntity
entity = restTemplate.getForEntity(PAYMENT_URL+"/payment/get/"+id,CommonResult.class); if(entity.getStatusCode().is2xxSuccessful()){ return entity.getBody(); }else{ return new CommonResult<>(444,"操作失败"); } } @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://wsznz.baihongyu.com/

你可能感兴趣的文章
Netty 的 Handler 链调用机制
查看>>
Netty 编解码器和 Handler 调用机制
查看>>
Netty 编解码器详解
查看>>
Netty 解决TCP粘包/半包使用
查看>>
Netty 调用,效率这么低还用啥?
查看>>
Netty 高性能架构设计
查看>>
Netty+Protostuff实现单机压测秒级接收35万个对象实践经验分享
查看>>
Netty+SpringBoot+FastDFS+Html5实现聊天App详解(一)
查看>>
netty--helloword程序
查看>>
netty2---服务端和客户端
查看>>
【Flink】Flink 2023 Flink易用性和稳定性在Shopee的优化-视频笔记
查看>>
Netty5.x 和3.x、4.x的区别及注意事项(官方翻译)
查看>>
netty——bytebuf的创建、内存分配与池化、组成、扩容规则、写入读取、内存回收、零拷贝
查看>>
netty——Channl的常用方法、ChannelFuture、CloseFuture
查看>>
netty——EventLoop概念、处理普通任务定时任务、处理io事件、EventLoopGroup
查看>>
netty——Future和Promise的使用 线程间的通信
查看>>
netty——Handler和pipeline
查看>>
Vue输出HTML
查看>>
netty——黏包半包的解决方案、滑动窗口的概念
查看>>
Netty中Http客户端、服务端的编解码器
查看>>