java常见轮询算法

2023-11-11

轮询算法

轮询算法就是通过一个算法,对提供的一组列表进行计算,按照一定规则取出列表中的元素,常见的有顺序模式、随机模式、加权模式,加权平滑模式。

定义轮询算法的接口:

/**
 * 轮询算法接口
 */
public interface Balance<T> {
	
	T chooseOne(List<T> list);
}

1、随机模式轮询

public class RandomBalance<T> implements Balance<T> {

	private Random random = new Random();

	@Override
	public T chooseOne(List<T> list) {
		int sum = list.size();
		return list.get(random.nextInt(sum));
	}
	
	/**
	 * 测试
	 **/
	public static void main(String[] args) {
		List<Service> services = new ArrayList<>();
		for (int i = 0; i < 5; i++) {
			Service e = new Service();
			e.setIp("address:"+i);
			e.setWeight(1);
			services.add(e);
		}
		RandomBalance<Service> bl = new RandomBalance<>();
		for (int i = 0; i < services.size(); i++) {
			System.out.println(bl.chooseOne(services));
		}
	}
}

2、顺序轮询模式

public class QueueBalance<T> implements Balance<T> {

	private volatile int index = 0;

	public synchronized T chooseOne(List<T> list) {
		if(list==null||list.size()==0) return null;
		int sum = list.size();
		int temp = index % sum;
		T t = list.get(temp);
		index++;
		return t;
	}
	
	/**
	 * 测试
	 **/
	public static void main(String[] args) {
		List<Service> services = new ArrayList<>();
		for (int i = 0; i < 20; i++) {
			Service e = new Service();
			e.setIp("address:"+i);
			e.setWeight(1);
			services.add(e);
		}
		QueueBalance<Service> bl = new QueueBalance<>();
		for (int i = 0; i < services.size(); i++) {
			System.out.println(bl.chooseOne(services));
		}
	}

}

3、加权模式

public class WeightBalance implements Balance<Service> {
	
    private volatile static int index;

	@Override
	public synchronized Service chooseOne(List<Service> list) {
		int sum = list.stream().mapToInt(Service::getWeight).sum();
		int temp = 0;
		int cur = (index++) % sum;
		for (Service service : list) {
			temp = temp + service.getWeight();
			if(cur < temp) {
				return service;
			}
		}
		return null;
	}
	
	public static void main(String[] args) {
		List<Service> services = new ArrayList<>();
		
		Service server1 = new Service();
		server1.setIp("address1");
		server1.setWeight(1);
		
		Service server2 = new Service();
		server2.setIp("address2");
		server2.setWeight(3);
		
		Service server3 = new Service();
		server3.setIp("address3");
		server3.setWeight(5);
		
		services.add(server1);
		services.add(server2);
		services.add(server3);
		
        WeightBalance loadBalance = new WeightBalance();
		
		for (int i = 0; i < 20; i++) {
			System.out.println("第"+i+"次请求服务ip为:"+loadBalance.chooseOne(services).getIp());
		}
	}	
	
}

加权模式存在的问题就是,轮询是以权重值累加第一个小于当前index取模值,最后的结果就是Aserivde N次,Bservice N次,Cservice N次,我们要实现的效果的在总次数内,每个service调用的次数是自身权重在总权重的比例*总调用次数,并且这些调用次数是平滑分布的。这个效果就要看下面的SmoothWeightBalance

4、平滑加权模式

/**
 * 权重模式均匀轮询
 *
 * 通俗语概述---摘抄网络
 * 平滑加权轮询那个算法可以这样想:(total是不变的,因为每次有一个节点减掉total后,每个节点都会加一次
 * 自身权重,所以总共又增加了一个total)每次选出节点后,都是减掉这个节点权重一个total;自身权重越大的节
 * 点增长越快,那么比其他节点大的几率就越高,被选中的机会就越多;而自身权重比较低的,自身current_weight
 * 增长比较慢,所以比其他大的几率小,被选中的机会就少。(挨的刀子是一样大的,但是哪棵韭菜长得快,哪棵就
 * 更容易挨刀子;东北大米年收1次,海南能收3次)
 */
public class SmoothWeightBalance implements Balance<Service> {

	  /**
     * 存储当前weight
     */
    private Map<String, Integer> map = new HashMap<>();

	/**
	 *  加权平滑轮询
	 *  	实现原理:将请求为key,权重值初始为value,每一轮取最大的weight,然后将最大的weight-总数,再将每个递增自身weight。
	 *  	解析: 每一轮所有server的当前weight递增总数等于最大weight的server减少的总数,从而保证持续取值时减少不会将权重越减
	 *  越少。而权重值越大,那么增长时抢占最大权重值的机会越大,这个几率值和初始weight成正比。就好比草长的越快,那么被割的机会越大。
	 */
	public Service chooseOne(List<Service> services) {
		// 给予每个service的在map中的权重值为自身初始weight
		 services.forEach(service ->
		    map.computeIfAbsent(service.toString(), key -> service.getWeight())
		 );
		int sum = services.stream().mapToInt(Service::getWeight).sum(); // 权重总数
		
		// 找当前weight值最大的server
		Service maxService = null;
		for (Service service : services) {
			Integer currentWeight = map.get(service.toString());
			if (maxService == null || currentWeight > map.get(maxService.toString())) {
				maxService = service; // 找当前weight最大的server
			}
		}
		
		// 将最大的 - total总数 (备注:默认weight获取:server.getWeight , 当前weight获取 : map.get(server.toString))
		map.put(maxService.toString(), map.get(maxService.toString()) - sum);
		
		// 递增所有server的weight值 (总递增数等于total)
		for (Service service : services) {
			Integer oldweight = map.get(service.toString());
			map.put(service.toString(), oldweight + service.getWeight());
		}
		
		return maxService;
	}
	
	/**
	 * 测试
	 */
	public static void main(String[] args) {
		List<Service> services = new ArrayList<>();
		Service server1 = new Service();
		server1.setIp("address1");
		server1.setWeight(1);

		Service server2 = new Service();
		server2.setIp("address2");
		server2.setWeight(3);

		Service server3 = new Service();
		server3.setIp("address3");
		server3.setWeight(5);

		services.add(server1);
		services.add(server2);
		services.add(server3);

		SmoothWeightBalance loadBalance = new SmoothWeightBalance();

		for (int i = 0; i < 20; i++) {
			System.out.println("第" + i + "次请求服务ip为:" + loadBalance.chooseOne(services).getIp());
		}
	}
}

 

end!

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java常见轮询算法 的相关文章

  • 创建型模式2——工厂模式(简单工厂、工厂方法、抽象工厂)

    简单工厂 模式动机 意图 定义一个创建对象的接口 让其子类自己决定实例化哪一个工厂类 工厂模式使其创建过程延迟到子类进行 主要解决 主要解决接口选择的问题 简单工厂模式的要点在于 当你需要什么 只需要传入一个正确的参数 就可以获取你所需要的
  • OpenGL ES加载纹理

    iOS OpenGL ES加载纹理 GLKit 1 准备工作 创建UIViewController文件并继承GLKViewController 遵守协议GLKViewDelegate 实现协议方法 void glkView GLKView
  • [Vue warn] Failed to resolve component:报错问题。

    在一个vue3项目中 引入一个自定义组件时出现了 Vue warn Failed to resolve component 组件名 这样的警告 引入的组件没有出现在页面中 网上查了半天没找到原因 后来将vue3中的defineCompone
  • cs231n_反向传播求导篇

    我们已经知道基本的标量除以矩阵 或向量 矩阵 或向量 除以标量 以及稍微复杂一点的向量除向量 1 1 1 行向量除以向量除以矩阵 矩阵除以向量的方法 那么矩阵除以矩阵呢 例如 XN DWD C fN C X N
  • 用python+pytest框架写UI自动化

    使用 Python 编写 UI 自动化测试通常需要使用 Pytest 测试框架 下面是编写 Python Pytest UI 自动化测试的一般步骤 安装 Python Pytest 和相关的库 例如 Selenium WebDriver 和
  • WM_CHAR 获取键盘按下的字符

    DEMO3 11 CPP WM CHAR demo INCLUDES define WIN32 LEAN AND MEAN just say no to MFC include
  • QT-固定全局文字大小

    问题描述 W10 将缩放与布局设置为 gt 100 时 QT的文字会放大超过原来的文字框 解决 使用这种方法是让Windows来控制缩放 而不是Qt 添加一个资源文件qt conf 内容为 Platforms WindowsArgument
  • linux 时钟漂移,Redis 实现分布式锁之Redlock 算法浅析

    保证分布式锁有效的三个属性 Safety Properties 安全性 此处也就是互斥性 任意时刻只能有一个客户端可以持有锁 Liveness Property A 无死锁 即使持有锁的客户端崩溃或被分区 也可以获得锁 Liveness P
  • pandas中groupby函数中参数ax_index和group_keys的区别

    前言 笔者在学习pandas中groupby函数时 发现ax index True False和group key True False这两个参数相近又有所不同 特写出此文供大家分享 一 首先创建一个DataFrame df pd Data
  • thymeleaf模板报红

    问题 解决 忽略所有警告或错误 1 或者忽略Thymeleaf有关警告或错误 2 2 取消这个勾 关闭IDEA对于thymeleaf的数据验证选项
  • BP神经网络的详细推导

    文章目录 概述 一 神经元模型 二 感知机与多层网络 三 误差逆传播算法 四 全局最小与局部最小 五 BP算法的改进 1 引入动量法 2 尺度变换法 3 自适应学习率调整法 六 BP神经网络的训练 1 产生数据样本集 2 确定网络的类型和结
  • QMap倒序遍历

    for QList
  • 中英文期刊卷号和期号

    一 中文期刊 国内期刊为了给期刊排序方便查询 都按照时间分卷和期 卷是期之上的时间分类 卷是从创刊开始按照年度排序的编号 期是这一年中按时间排序的编号 比如2017年3月发表的论文 按照卷号期号排可能就是 第23卷第3期 国内对期刊卷号期号
  • 【简述】VSCode使用ssh连接linux服务器并安装使用jupyter notebook/Anaconda/pytorch

    1 通过管理员获得该Unbutu服务器的IP 账号 密码 2 打开VSCode 安装扩展Remote SSH 3 在VsCode左侧边栏点击Remote Explorer使用该扩展 新建Remote 输入IP 账号并连接 4 在上方弹出窗口
  • Unix/Linux编程:fork()进程详解

    文章目录 理论 进程 fork wait exec fork 实践 验证 fork函数被调用一次但返回两次 子进程和父进程之间不共享数据空间 父子进程间的文件共享 fork的内存语义 同步信号以规避 fork 之后的竞争条件 fork 解决
  • Flutter切换页面后保持状态不刷新

    1 使用IndexedStack实现 IndexedStack继承自Stack 它的作用是显示第index个child 其它child在页面上是不可见的 但所有child的状态都被保持 所以这个Widget可以实现我们的需求 我们只需要将现
  • PointNet介绍

    论文 PointNet Deep Learning on Point Sets for 3D Classification and Segmentation 代码 https github com charlesq34 pointnet 0
  • 【无标题】C++课程学习笔记(南科大于仕琪老师)

    这几天我突然想写CSDN了 前段时间我打开了我的CSDN 发现我其实只写了3篇文章 其实写CSDN是一个好习惯 我之前这么多年都没有发现这个好习惯 现在我要求自己只有有所心得就应该写下来 一方面与大家共勉 另一方面通过和大家的交流我希望自己

随机推荐

  • UDS诊断之负响应码

    1 0x10服务 服务诊断会话控制 否定响应码 NRC 定义 Defination 0x12 服务器支持诊断请求中的服务标识符 Service ID 但不支持收到的子功能参数时 回复此编码 0x13 请求服务的诊断报文中的数据长度与定义不一
  • Linux虚拟化网络之路由转发实战

    一 Linux路由配置 如果要在不同网段直接通讯 需要添加路由 Linux添加路由命令如下 route add del net host target netmask Nm gw Gw dev If add 添加一条路由规则 del 删除一
  • 简单的shell文件编写:拷贝特定的可执行文件到某特定目录下。

    写这个文件夹是为了把自己在fedora9上交叉编译的可执行文件复制到arm板上便于执行 这样每次都不用输入一长串文件名了 调用这个脚本 它会自动 拷贝ARM可执行文件到指定的目录下 例子是 home stephen stephenshare
  • 平均年薪30万的深度学习算法工程师,正面临100万的人才缺口

    深度学习的突破极大推动了人工智能的发展 并广泛应用在计算机视觉 自然语言处理等领域中 谷歌 百度的IDL 腾讯的AI lab 华为等都在重金布局人工智能 同时 以深度学习为核心技术的人工智能企业不断涌现 我们耳熟能详的有 格林深瞳 商汤科技
  • 【IPv6】设置win10和win11允许访问IPv6站点

    设置win10和win11允许访问IPv6站点 步骤如下 1 打开控制面板 2 点击 网络和 Internet 3 点击 网络和共享中心 4 点击连接的网络 5 点击 属性 6 把 Internet 协议版本 6 TCP IPv6 选项勾上
  • Android调用环信的EaseUI V3.0发送语音不成功的问题。

    这两个在集成环信实现IM功能 在开发过程中遇到一个问题 发送文字 表情 图片 位置都是正常的 但是语音就是一直发送不成功 并且只是在第一次安装app登录账号之后发送语音的时候才会出现发送不成功的问题 如果把app杀掉重新打开或者退出账号重新
  • 【华为OD机试】最大股票收益【2023 B卷

    华为OD机试 真题 点这里 华为OD机试 真题考点分类 点这里 题目描述 假设知道某段连续时间内股票价格 计算通过买入卖出可获得的最大收益 输入一个大小为 n 的数 price p1 p2 p3 p4 pn pi 是第i天的股票价格 pi
  • Quartus如何生成顶层文件里的小模块,解决波形图无法导入输入输出

    生成模块 有这么个模块叫SRAM 就可以在顶层文件里找到了 解决波形图无法导入输入输出 统一名字 文件夹名字和 qpf文件一致和顶层文件名字一样 还和波形图文件一样
  • nodejs npm run build 打包压缩zip文件

    步骤1 安装 npm install archiver D 步骤2 根目录下新建zip js 内容如下 const fs require fs const archiver require archiver 创建文件输出流 let outp
  • This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.

    困难 是智者的机遇 是人与人差距所在 疑惑 D pytools anaconda PyCharm 2018 3 5 helpers pycharm matplotlib backend backend interagg py 62 User
  • Vue项目中grid布局的应用

    Vue项目中grid布局的应用 一 使用背景 二 常见属性 1 grid template 属性 1 1 columns列相关配置 1 1 1 指定列的个数 1 1 2 auto fill属性 自动填充 1 1 3 fr 比例关系 1 1
  • windows向linux传送文件

    windows与Linux之间传送文件 1 用putty的内置小组件PSCP exe 此法可行 pscp exe 可从putty官方下载 然后放到 windows 的c windows system32目录下 这样cmd 命令提示符窗口 输
  • linux下使用ffmpeg录屏

    linux系统中 使用ffmpeg进行录屏与截图 把 dev fb0设备的framebuffer显示图像录制为视频 ffmpeg f fbdev framerate 10 i dev fb0 out avi 编码帧率默认值为25fps 把
  • Android查看应用签名方法

    查看keystore文件签名 查看keystore文件签名信息 前提要有keystore文件和密钥 才能够获取keystore文件的签名信息 打开 AS工具窗口栏右边的 Gradle gt Project gt app gt Tasks g
  • QtCreator设置多个qmake

    qt Creator 有时候需要设置不同qt库文件 也就是不同qmake 我们可以设置 1 Tools gt KIts 然后选择Manual gt add 然后添加Name写5 15或者其它名字 然后点击Qt Version gt Manu
  • PID算法(没办法完全理解的东西)

    快速 P 准确 I 稳定 D P Proportion 比例 就是输入偏差乘以一个常数 I Integral 积分 就是对输入偏差进行积分运算 D Derivative 微分 对输入偏差进行微分运算 输入偏差 读出的被控制对象的值 设定值
  • 24. 二叉搜索树的最近公共祖先

    题目链接 235 二叉搜索树的最近公共祖先 大概思路 题目要求 给定一颗二叉搜索树 两个确定值q p 要求q p的最近公共祖先 思路 利用搜索树的特性 当q p的值均小于遍历的节点值的时候 可以判断q p均在根节点的左子树上 小于则在右子树
  • DUKE大学BOE数据集 OCT图像积液分割数据集

    使用此数据集用来做积液分割研究 地址 http people duke edu sf59 Chiu BOE 2014 dataset htm 使用python将 mat转换为图片格式 对BOE MAT格式文件处理成图片 import cv2
  • 数据生成

    数据生成 MATLAB实现MCMC马尔科夫蒙特卡洛模拟的数据生成 目录 数据生成 MATLAB实现MCMC马尔科夫蒙特卡洛模拟的数据生成 生成效果 基本描述 模型描述 程序设计 参考资料 生成效果 基本描述 1 MATLAB实现MCMC马尔
  • java常见轮询算法

    轮询算法 轮询算法就是通过一个算法 对提供的一组列表进行计算 按照一定规则取出列表中的元素 常见的有顺序模式 随机模式 加权模式 加权平滑模式 定义轮询算法的接口 轮询算法接口 public interface Balance