【使用Zookeeper当作注册中心】自己定制负载均衡常见策略
自己定制负载均衡常见策略
- 一、前言
- 随机(Random)策略的实现
- 轮询(Round Robin)策略的实现
- 哈希(Hash)策略
一、前言
大伙肯定知道,在分布式开发中,目前使用较多的注册中心有以下几个:
- Apache Zookeeper
- Netflix Eureka
- Alibaba Nacos
由于 Zookeeper 在面对高频次的服务注册和发现操作可能会一定的性能损耗等原因,搞得现在好多人都不用 Zookeeper 当做注册中心了。但它也提供了强一致性和高可靠性的特性,也没有被淘汰。
Zookeeper 本身并没有提供现成的服务发现功能,它更专注于分布式协调的能力。所以在使用 Zookeeper 作为注册中心时,需要自己在客户端实现服务的发现和负载均衡的逻辑。当然也可以去整合相关组件简化开发过程。
常见的负载均衡有以下三种:
- 随机(random)策略
- 轮询(round robin)策略
- 哈希(hash)策略
下面的话以寻注册中心的服务地址的需求来去对三种策略进行实现。
// 这是对应的策略接口
public interface RouteHandle {// 参数1:服务地址集合// 参数2:对应的key,我这里使用的是userId,这个结合自身项目需求String routeServer(List<String> values, String key);}
随机(Random)策略的实现
/*** 随机的负载均衡*/
public class RandomHandle implements RouteHandle {@Overridepublic String routeServer(List<String> values, String key) {int size = values.size();if (size == 0) {throw new ApplicationException(UserErrorCode.SERVER_NOT_AVAILABLE);}// 去获取一个小于size的索引值// 你可以简单理解:随机整型数&sizeint index = ThreadLocalRandom.current().nextInt(size);return values.get(index);}
}
轮询(Round Robin)策略的实现
轮询策略即将请求次数和总的服务树取模,然后得出索引去得到服务信息。
/*** 轮询策略*/
public class LoopHandle implements RouteHandle {private AtomicLong index = new AtomicLong();@Overridepublic String routeServer(List<String> values, String key) {int size = values.size();if (size == 0) {throw new ApplicationException(UserErrorCode.SERVER_NOT_AVAILABLE);}Long l = index.incrementAndGet() % size;if (l < 0) {index.set(0L);l = 0L;}return values.get(l.intValue());}
}
哈希(Hash)策略
这里指的 Hash 策略一般指的是一次性 Hash 算法实现的策略。传统的 hash 在添加或删除一个节点的时候,会出现缓存失效,失效缓存比例为:m/(m+1);传统hash一般是将资源的 hashcode % table.size()(服务数)得到节点索引然后将访问服务,这样的话当增加一个节点的时候,除了hashcode为1的时候其对应的服务不变其他都缓存失效(0就不算它了,近似的一个值吧)也就是近于缓存失效比例为 m/m+1。
传统的hash造成的缓存失效很容易就把服务给搞蹦了,因为有大量资源访问不到的请求嘛。
然后就有了一致性hash算法,它将映射集合规定为0~2^32-1的范围的环,首尾相连。
将节点放到(注册到)环中,然后根据资源的hash去顺时针寻其节点服务。
注意:当注册节点的时候,也有可能会出现hash偏斜问题,即节点都被放到了环的一边,使得资源大部分都使用的是俩边的节点,这个时候我们需要将每个服务节点设置一些虚拟节点注册到环上,这样的话每个服务节点近似均衡的分配给资源了。
这里参考的文献:
一致性hash算法讲解——Java实现
下面对 hash 策略进行实现,下面是使用 TreeMap 对一次性hash算法进行实现的,这是因为它底层是使用 红黑树 进行实现的,有序,且添加起来比起平衡二叉树这样的不用老左旋右旋。主要是因为有序,对闭环的顺时针有序选节点是一致的,所以用 TreeMap 实现它比较多。当然也可以自身定义策略去实现。
/*** 使用 TreeMap 实现一致性hash*/
public class TreeMapConsistentHash extends AbstractConsistentHash {private TreeMap<Long, String> treeMap = new TreeMap<>();private static final int NODE_SIZE = 2; // 每个节点再注册虚拟节点的数量@Overrideprotected void add(long key, String value) {for (int i = 0; i < NODE_SIZE; i++) {treeMap.put(super.hash("node" + key + i), value);}treeMap.put(key, value);}@Overrideprotected String getFirstNodeValue(String value) {Long hash = super.hash(value);SortedMap<Long, String> last = treeMap.tailMap(hash);if(!last.isEmpty()){return last.get(last.firstKey());}if(treeMap.size() == 0){throw new ApplicationException(UserErrorCode.SERVER_NOT_AVAILABLE);}return treeMap.firstEntry().getValue();}@Overrideprotected void processBefore() {treeMap.clear(); // 清空是因为,可能出现添加或删除服务的现象}
}
重点就是 add 和 getFirstNodeValue 方法,至于父类其他方法的实现不影响理解这个策略。
相关文章:
【使用Zookeeper当作注册中心】自己定制负载均衡常见策略
自己定制负载均衡常见策略 一、前言随机(Random)策略的实现轮询(Round Robin)策略的实现哈希(Hash)策略 一、前言 大伙肯定知道,在分布式开发中,目前使用较多的注册中心有以下几个&…...
设计模式十七:迭代器模式(Iterator Pattern)
迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供了一种访问聚合对象(例如列表、集合、数组等)中各个元素的方法,而无需暴露其内部表示。迭代器模式将遍历元素和访问元素的责任分离开来࿰…...
Python制作爱心并打包成手机端可执行文件
前言 本文是想要将python代码打包成在手机上能执行的文件 尝试了几个库, 有这也那样的限制,最终还是选了BeeWare 环境:python3.7.x 开始 找到打包有相关工具os-android-apk-builder,buildozer,cx_Freezeÿ…...
使用docker-compose.yml快速搭建开发、部署环境(nginx、tomcat、mysql、jar包、各种程序)以及多容器通信和统一配置
目录 docker-compose语法(更多说明可查看下面代码)imagehostnamecontainer_namevolumesnetworks yml文件的使用启动停止 开发环境(这里以python为例)部署环境nginxmysqltomcatjar包打包后的可执行程序 常见问题与解决方案多个容器…...
管理类联考——逻辑——真题篇——按知识分类——汇总篇——二、论证逻辑——支持加强——第三节——分类3——类比题干支持
文章目录 第三节 支持加强-分类3-类比题干支持真题(2017-28)-支持加强-正面支持-表达“确实如此”真题(2017-36)-支持加强-正面支持-表达“确实如此”真题(2017-39)-支持加强-正面支持-方法有效或方法可行,但多半不选择方法无恶果真题(2017-50)-支持加强真题(2018-2…...
搜索旋转排序数组
整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nums[1], …, …...
Steam搬砖项目:最长久稳定的副业!
项目应该大家都有听说话,但是细节问题,如何操作可能有些不是很清楚,今天在这里简单分享一下。 这个Steam搬砖项目主要赚钱汇率差和价值差,是一个细分领取的小项目。 不用引流,时间也是比较自由的,你可以兼…...
最小化安装移动云大云操作系统--BCLinux-R8-U8-Server-x86_64-230802版
CentOS 结束技术支持,转为RHEL的前置stream版本后,国内开源Linux服务器OS生态转向了开源龙蜥和开源欧拉两大开源社区,对应衍生出了一系列商用Linux服务器系统。BC-Linux V8.8是中国移动基于龙蜥社区Anolis OS 8.8版本深度定制的企业级X86服务…...
神经网络基础-神经网络补充概念-05-导数
概念 导数是微积分中的一个概念,用于描述函数在某一点的变化率。在数学中,函数的导数表示函数值随着自变量的微小变化而产生的变化量,即斜率或变化率。 假设有一个函数 f(x),其中 x 是自变量,y f(x) 是因变量。函数…...
kubernetes — 安装Ingress
1、 Ingress 1、安装-Nginx-Ingress kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml 2、设为默认的Ingress [rootk8s01 ~]# vim default_ingress.yaml apiVersion: networking.…...
SSR使用HTTPS
1.安装 npm i browser-sync 2. 再angular.json里配置 "serve-ssr": {"builder": "nguniversal/builders:ssr-dev-server","options": {"ssl": true,"sslCert": "./node_modules/browser-sync/certs/server…...
Spring Boot中使用validator如何实现接口入参自动检验
文章目录 一、背景二、使用三、举例 一、背景 在项目开发过程中,经常会对一些字段进行校验,比如字段的非空校验、字段的长度校验等,如果在每个需要的地方写一堆if else 会让你的代码变的冗余笨重且相对不好维护,如何更加规范和优…...
thinkphp 5 实现UNION ALL 3个联表查询,并且带上搜索条件,名称,时间,手机号
在ThinkPHP 5中实现带有搜索条件、名称、时间和手机号的3个联表查询(UNION ALL),您可以按照以下步骤进行操作: 确保已经配置好数据库连接信息和相关的模型。 使用union()方法来构建3个联表查询,同时在每个查询中添加所…...
React 之 Router - 路由详解
一、Router的基本使用 1. 安装react-router react-router会包含一些react-native的内容,web开发并不需要 npm install react-router-dom 2. 设置使用模式 BrowserRouter或HashRouter Router中包含了对路径改变的监听,并且会将相应的路径传递给子组件Bro…...
框架分析(1)-IT人必须会
框架分析(1)-IT人必须会 专栏介绍当今主流框架前端框架后端框架移动应用框架数据库框架测试框架 Angular关键特点和功能:组件化架构双向数据绑定依赖注入路由功能强大的模板语法测试友好 优缺点分析优点缺点 总结 专栏介绍 link 主要对目前市…...
前端面试的游览器部分(7)每天10个小知识点
目录 系列文章目录前端面试的游览器部分(1)每天10个小知识点前端面试的游览器部分(2)每天10个小知识点前端面试的游览器部分(3)每天10个小知识点前端面试的游览器部分(4)每天10个小知…...
认识Junit
1. 前言 2. Junit注解 2.1. 常用的注解 2.1.1. Test 表示当前方法是一个测试方法(不需要main来执行) Test void Test01() throws InterruptedException {System.out.println("测试用例1");WebDriver webDriver new ChromeDriver();webDriver.get("https:/…...
Unity C# 引用池 ReferencePool
Unity C# 引用池 ReferencePool 1.目的 对于多次创建的数据使用new 关键字是十分消耗性能的,使用完成后由GC去自动释放,当一个类型的数据频繁创建可以使用引用池进行管理。 2.实现 项目目录 IReference 接口 要放入引用池的数据只需要继承这个接口…...
opencv 进阶10-人脸识别原理说明及示例-cv2.CascadeClassifier.detectMultiScale()
人脸识别是指程序对输入的人脸图像进行判断,并识别出其对应的人的过程。人脸识别程 序像我们人类一样,“看到”一张人脸后就能够分辨出这个人是家人、朋友还是明星。 当然,要实现人脸识别,首先要判断当前图像内是否出现了人脸&…...
〔013〕Stable Diffusion 之 图片自动评分和不健康内容过滤器 篇
✨ 目录 🎈 下载咖啡美学评价插件🎈 咖啡美学评价使用🎈 不健康内容过滤器插件🎈 下载咖啡美学评价插件 想让系统帮你的图片作品打分评价,可以下载咖啡美学自动评价插件插件地址:https://github.com/p1atdev/stable-diffusion-webui-cafe-aesthetic也可以通过扩展列表…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...
【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...
