`

java实现轮询和加权轮询

阅读更多

1. 一般轮询算法

服务器类

package com.sosop.roundRobin;

public class Server {
	private String ip;
	private int weight;
	
	public Server(String ip) {
		super();
		this.ip = ip;
	}

	public Server(String ip, int weight) {
		this.ip     = ip;
		this.weight = weight;
	}
	
	public String getIp() {
		return ip;
	}
	public void setIp(String ip) {
		this.ip = ip;
	}
	public int getWeight() {
		return weight;
	}
	public void setWeight(int weight) {
		this.weight = weight;
	}

	@Override
	public String toString() {
		return "Server [ip=" + ip + ", weight=" + weight + "]";
	}	
}

 实现与测试

package com.sosop.roundRobin;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class NormalRoundRobin {
	
	private List<Server> servers;
	
	private int currentIndex;
	private int totalServer;
	
	public NormalRoundRobin() {
		servers = new ArrayList<>();
		servers.add(new Server("192.168.1.2"));
		servers.add(new Server("192.168.1.3"));
		servers.add(new Server("192.168.1.4"));
		servers.add(new Server("192.168.1.5"));
		servers.add(new Server("192.168.1.6"));
		servers.add(new Server("192.168.1.7"));
		servers.add(new Server("192.168.1.8"));
		totalServer = servers.size();
		currentIndex = totalServer - 1;
	}


	// 轮询
	public Server round() {
		currentIndex = (currentIndex + 1) % totalServer;
		return servers.get(currentIndex);
	}
	
	
	public static void main(String[] args) {
		final NormalRoundRobin r = new NormalRoundRobin();
		// 不带并发的轮询
		for (int i = 0; i < 14; i++) {
			System.out.println(r.round());
		}
		
		System.out.println();
		System.out.println("==========================");
		System.out.println();
		
		final CyclicBarrier b = new CyclicBarrier(14);
		
		// 带并发的轮询
		for (int i = 0; i < 14; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						b.await();
						System.out.println(Thread.currentThread().getName() + " " + r.round());
					} catch (InterruptedException | BrokenBarrierException e) {
						e.printStackTrace();
					}
				}
			}, "thread" + i).start();
		}
	}
	
}

结果:

Server [ip=192.168.1.2, weight=0]
Server [ip=192.168.1.3, weight=0]
Server [ip=192.168.1.4, weight=0]
Server [ip=192.168.1.5, weight=0]
Server [ip=192.168.1.6, weight=0]
Server [ip=192.168.1.7, weight=0]
Server [ip=192.168.1.8, weight=0]
Server [ip=192.168.1.2, weight=0]
Server [ip=192.168.1.3, weight=0]
Server [ip=192.168.1.4, weight=0]
Server [ip=192.168.1.5, weight=0]
Server [ip=192.168.1.6, weight=0]
Server [ip=192.168.1.7, weight=0]
Server [ip=192.168.1.8, weight=0]

==========================

thread13 Server [ip=192.168.1.2, weight=0]
thread4 Server [ip=192.168.1.6, weight=0]
thread3 Server [ip=192.168.1.5, weight=0]
thread1 Server [ip=192.168.1.3, weight=0]
thread12 Server [ip=192.168.1.7, weight=0]
thread0 Server [ip=192.168.1.2, weight=0]
thread2 Server [ip=192.168.1.4, weight=0]
thread10 Server [ip=192.168.1.6, weight=0]
thread11 Server [ip=192.168.1.5, weight=0]
thread8 Server [ip=192.168.1.3, weight=0]
thread9 Server [ip=192.168.1.4, weight=0]
thread7 Server [ip=192.168.1.2, weight=0]
thread6 Server [ip=192.168.1.8, weight=0]
thread5 Server [ip=192.168.1.7, weight=0]

 

2.加权轮询

package com.sosop.roundRobin;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class WeightRoundRobin {
	private List<Server> servers;

	private int currentIndex;
	private int totalServer;
	private int currentWeight;
	private int maxWeight;
	private int gcdWeight;

	public WeightRoundRobin() {
		servers = new ArrayList<>();
		servers.add(new Server("192.168.1.2", 5));
		servers.add(new Server("192.168.1.3", 10));
		servers.add(new Server("192.168.1.4", 15));
		servers.add(new Server("192.168.1.5", 100));
		servers.add(new Server("192.168.1.6", 5));
		servers.add(new Server("192.168.1.7", 20));
		servers.add(new Server("192.168.1.8", 30));
		totalServer = servers.size();
		currentIndex = totalServer - 1;
		maxWeight = maxWeight();
		gcdWeight = serverGcd();
	}

	public Server round() {
		while (true) {
			currentIndex = (currentIndex + 1) % totalServer;
			if (currentIndex == 0) {
				currentWeight = currentWeight - gcdWeight;
				if (currentWeight <= 0) {
					currentWeight = maxWeight;
					if(currentWeight == 0) {
						return null;
					}
				}
			}
			
			if(servers.get(currentIndex).getWeight() >= currentWeight) {
				return servers.get(currentIndex);
			}
		}
	}

	/**
	 * 返回所有服务器的权重的最大公约数
	 * 
	 * @return
	 */
	private int serverGcd() {
		int comDivisor = 0;
		for (int i = 0; i < totalServer - 1; i++) {
			if (comDivisor == 0) {
				comDivisor = gcd(servers.get(i).getWeight(), servers.get(i + 1).getWeight());
			} else {
				comDivisor = gcd(comDivisor, servers.get(i + 1).getWeight());
			}
		}
		return comDivisor;
	}

	/**
	 * 获得服务器中的最大权重
	 * 
	 * @return
	 */
	private int maxWeight() {
		int max = servers.get(0).getWeight();
		int tmp;
		for (int i = 1; i < totalServer; i++) {
			tmp = servers.get(i).getWeight();
			if (max < tmp) {
				max = tmp;
			}
		}
		return max;
	}

	/**
	 * 求两个数的最大公约数 4和6最大公约数是2
	 * 
	 * @param num1
	 * @param num2
	 * @return
	 */
	private int gcd(int num1, int num2) {
		BigInteger i1 = new BigInteger(String.valueOf(num1));
		BigInteger i2 = new BigInteger(String.valueOf(num2));
		return i1.gcd(i2).intValue();
	}

	public static void main(String[] args) {
		final WeightRoundRobin wr = new WeightRoundRobin();
		// 非并发情况
		for (int i = 0; i < 100; i++) {
			System.out.println(wr.round());
		}
		
		System.out.println();
		System.out.println("==========");
		System.out.println();
		
		final CyclicBarrier b = new CyclicBarrier(30);
		// 并发情况
		for (int i = 0; i < 30; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						b.await();
						System.out.println(Thread.currentThread().getName() + " " + wr.round());
					} catch (InterruptedException | BrokenBarrierException e) {
						e.printStackTrace();
					}
				}
			}, "thread" + i).start();
		}
	}
}

 

结果:

Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.3, weight=10]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.2, weight=5]
Server [ip=192.168.1.3, weight=10]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.6, weight=5]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.3, weight=10]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.2, weight=5]
Server [ip=192.168.1.3, weight=10]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.6, weight=5]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.3, weight=10]

==========

thread0 Server [ip=192.168.1.5, weight=100]
thread3 Server [ip=192.168.1.2, weight=5]
thread7 Server [ip=192.168.1.6, weight=5]
thread10 Server [ip=192.168.1.5, weight=100]
thread12 Server [ip=192.168.1.5, weight=100]
thread15 Server [ip=192.168.1.5, weight=100]
thread18 Server [ip=192.168.1.5, weight=100]
thread2 Server [ip=192.168.1.8, weight=30]
thread29 Server [ip=192.168.1.5, weight=100]
thread1 Server [ip=192.168.1.7, weight=20]
thread27 Server [ip=192.168.1.8, weight=30]
thread26 Server [ip=192.168.1.5, weight=100]
thread25 Server [ip=192.168.1.8, weight=30]
thread24 Server [ip=192.168.1.5, weight=100]
thread23 Server [ip=192.168.1.5, weight=100]
thread22 Server [ip=192.168.1.5, weight=100]
thread21 Server [ip=192.168.1.5, weight=100]
thread20 Server [ip=192.168.1.5, weight=100]
thread19 Server [ip=192.168.1.5, weight=100]
thread17 Server [ip=192.168.1.5, weight=100]
thread16 Server [ip=192.168.1.5, weight=100]
thread14 Server [ip=192.168.1.5, weight=100]
thread13 Server [ip=192.168.1.5, weight=100]
thread11 Server [ip=192.168.1.5, weight=100]
thread9 Server [ip=192.168.1.8, weight=30]
thread8 Server [ip=192.168.1.7, weight=20]
thread6 Server [ip=192.168.1.5, weight=100]
thread5 Server [ip=192.168.1.4, weight=15]
thread4 Server [ip=192.168.1.3, weight=10]
thread28 Server [ip=192.168.1.5, weight=100]

分享到:
评论

相关推荐

    自己编写平滑加权轮询算法,实现反向代理集群服务的平滑分配.doc

    通过 Java 语言,使用平滑加权轮询算法,结合线程池和 Socket 网络编程等技术,实现了反向代理集群服务的平滑分配,并通过降权/提权实现宕机服务的”剔除“和缓冲恢复。 一、理解全过程 1.1 概述 要实现 Socket ...

    Java加权负载均衡策略实现过程解析

    接下来,我们需要实现加权轮询算法来分配流量。我们可以使用以下代码来实现: ```java public void run() { // 重建一个Map,避免服务器的上下线导致的并发问题 Map, Integer&gt; serverMap = new HashMap, Integer&gt;...

    详解Nginx轮询算法底层实现的方法

    Nginx的轮询算法提供了两种实现方式:简单轮询和加权轮询。简单轮询适用于服务器处理能力相近的情况,而加权轮询可以根据服务器性能动态调整请求分配,优化资源利用率。理解并掌握这两种算法的原理,对于优化Nginx...

    Crmeb Java 项目封装打包.pdf

    Nginx支持多种负载均衡策略,例如轮询(默认)、加权轮询(Weighted Round Robin)等。加权轮询允许为每个服务器分配不同的权重,权重越大,被分配到请求的概率越高。这样可以实现流量的动态分配,提高系统的可用性...

    最新面试文档Java类,常规高手快速成长的问答,解决口笨;解决知识难点;解决面试八股文

    Dubbo采用了10层模式架构,可以分为三层:Business层由开发者提供服务接口和实现;RPC调用核心层处理实际的远程调用,包括负载均衡、集群容错和代理等;Remoting层则处理网络传输和数据转换。 Dubbo提供了六项核心...

    2024年Java高工面试题 2024年Java高工面试题 2024年Java高工面试题

    - **加权轮询**: 按照权重进行轮询。 - **加权随机**: 按照权重进行随机选择。 - **一致性哈希**: 保持节点变化时数据迁移最小。 - **最小活跃算法**: 优先选择负载最低的服务节点。 ### 八、数据结构 #### 1. ...

    2020年-银盛支付-Java中级.pdf

    - WeightedResponseTimeRule:加权响应时间策略,根据响应时间进行加权轮询。 - AvailabilityFilteringRule:可用过滤策略,排除故障或并发请求超过阈值的服务器,然后进行线性轮询。 - ZoneAvoidanceRule:区域...

    论文研究-基于JCF中间件的负载预测与过载迁移的融合算法.pdf

    在JCF(Java component framework)中间件平台上的实验结果表明,该算法优于静态加权轮询和动态加权轮询算法,在提高均衡效率、增加集群系统的吞吐量、降低服务请求响应时间多方面有着显著效果,在实际应用中有较大...

    mail-micro-service:邮件微服务

    mail-micro-service是基于SpringBoot、JavaMail实现的邮件微服务系统,支持以轮询、加权轮询方式负载多邮箱配置,提供邮件发送API。 开发需求 由于免费邮箱存在邮件发送数量和频率的上限,若发送频繁,可能会被邮件...

    金融支付Java中级工程师岗位面试真题

    当然,Ribbon还支持其他策略,如随机选择、最大可用、加权响应时间、可用过滤和区域感知等。 6. **SpringBoot常用注解及实现** - `@Bean` 注解用于标记一个方法生成的实例作为Spring容器中的Bean。默认是单例模式...

    Nginx+Tomcat的集群搭建操作步骤

    Nginx以其高效的处理能力和反向代理功能,常被用作前端服务器,将请求分发给后端的Tomcat应用服务器集群,实现负载均衡。 Nginx自身采用单线程进程模型,并依赖于共享内存进行进程间通信,这使其性能非常高。Nginx...

    大数据应用案例 大数据培训视频教程-大数据高并发架构实战案例.pdf

    Nginx作为一款高效的反向代理服务器,常用于处理静态内容和实现动态内容的分离。课程中,学员将学习Nginx的基础安装和配置,以及如何进行反向代理和URL转发,实现动静态资源的有效管理。 此外,课程还提到了共享...

    第二章 Web框架的实现原理(1).docx

    - **静态算法**:如轮询法和加权轮询法。这类算法不考虑服务器当前的状态,而是按照固定的规则分配请求。 - **轮询法**:依次将请求发送给不同的服务器。 - **加权轮询法**:考虑到不同服务器的处理能力差异,为...

    深圳-银盛支付-Java中级面试.pdf

    - **加权轮询** (`WeightedResponseTimeRule`):根据各服务实例的响应时间进行加权处理后,再使用轮询的方式进行选择。 - **可用过滤** (`AvailabilityFilteringRule`):先过滤掉故障的服务实例,再根据特定规则选择...

    一线互联网企业面试题.pdf

    3. Nginx请求转发算法:Nginx是一个高性能的HTTP和反向代理服务器,它支持多种负载均衡算法,包括轮询、加权轮询、IP哈希等。 4. 用HashMap实现Redis问题:在分布式系统中,HashMap并不具备线程安全特性,无法直接...

    matlab轮询调度算法代码-starred:已加星标

    -完全不使用C和Make来构建不带任何Java的android应用 -新的可启动USB解决方案。 -一个小小的秘密商店,可以保留您的小秘密 -Lexbor是开放源代码HTML Renderer库的开发。 -猿编程语言 -mimalloc是具有出色性能的紧凑...

    RPC那些事儿

    2. **客户端负载均衡**:客户端自行选择服务器,如轮询、随机、加权轮询、加权随机、一致性哈希等算法。 高可用性(HA)是分布式系统设计的目标,通过冗余和故障转移机制减少停机时间。常见的HA工作方式包括: 1. ...

    SpringCloud 服务负载均衡和调用 Ribbon、OpenFeign的方法

    Ribbon 是 Netflix 提供的客户端负载均衡器,它作为一个客户端的负载均衡中间件,实现了基于 Java 的客户端负载均衡算法。Ribbon 默认集成了 Eureka,可以从 Eureka Server 获取服务列表并进行负载均衡。Ribbon 提供...

    Java超级详细的面试文档(335页)

    - 加权轮询:按照服务实例的权重比例依次选择服务实例。 - 最短响应时间权重随机:根据服务实例的平均响应时间动态调整权重,响应时间越短的服务实例被选中的概率越高。 - **工作原理**:服务提供者与消费者通过...

Global site tag (gtag.js) - Google Analytics