博客
关于我
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/

你可能感兴趣的文章
MySQL5.7.37windows解压版的安装使用
查看>>
mysql5.7免费下载地址
查看>>
mysql5.7命令总结
查看>>
mysql5.7安装
查看>>
mysql5.7性能调优my.ini
查看>>
MySQL5.7新增Performance Schema表
查看>>
Mysql5.7深入学习 1.MySQL 5.7 中的新增功能
查看>>
Webpack 之 basic chunk graph
查看>>
Mysql5.7版本单机版my.cnf配置文件
查看>>
mysql5.7的安装和Navicat的安装
查看>>
mysql5.7示例数据库_Linux MySQL5.7多实例数据库配置
查看>>
Mysql8 数据库安装及主从配置 | Spring Cloud 2
查看>>
mysql8 配置文件配置group 问题 sql语句group不能使用报错解决 mysql8.X版本的my.cnf配置文件 my.cnf文件 能够使用的my.cnf配置文件
查看>>
MySQL8.0.29启动报错Different lower_case_table_names settings for server (‘0‘) and data dictionary (‘1‘)
查看>>
MYSQL8.0以上忘记root密码
查看>>
Mysql8.0以上重置初始密码的方法
查看>>
mysql8.0新特性-自增变量的持久化
查看>>
Mysql8.0注意url变更写法
查看>>
Mysql8.0的特性
查看>>
MySQL8修改密码报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
查看>>