【使用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也可以通过扩展列表…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
