2台服务器负载均衡后synchronized_一篇有趣的负载均衡算法实现

负载平衡(Load balancing)是一种在多个计算机(网络、CPU、磁盘)之间均匀分配资源,以提高资源利用的技术。使用负载均衡可以最大化服务吞吐量,可能最小化响应时间,同时由于使用负载均衡时,会使用多个服务器节点代单点服务,也提高了服务的可用性。

负载均衡的实现可以软件可以硬件,硬件如大名鼎鼎的 F5 负载均衡设备,软件如 NGINX 中的负载均衡实现,又如 Springcloud Ribbon 组件中的负载均衡实现。

如果看到这里你还不知道负载均衡是干嘛的,那么只能放一张图了,毕竟没图说个啥。

5985016b6e09162bd74f9a10e3f5abc5.png

正经的负载均衡示例

负载均衡要做到在多次请求下,每台服务器被请求的次数大致相同。但是实际生产中,可能每台机器的性能不同,我们会希望性能好的机器承担的请求更多一些,这也是正常需求。

如果这样说下来你看不懂,那我就再举个例子好了,一排可爱的小熊(服务器)站好。

5a353ebd0538350caf3c8135a41d0905.png

一排要被访问的服务器

这时有人(用户)要过来打脸(请求访问)。

227d60f40e7e20e887b902cbe91b10c8.png

用户请求

那么怎么样我们才能让这每一个可爱的小熊被打的次数大致相同呢?

又或者熊 4 比较胖,抗击打能力是别人的两倍,我们怎么提高熊 4 被打的次数也是别人的两倍呢?

又或者每次出手的力度不同,有重有轻,恰巧熊 4 总是承受这种大力度啪啪打脸,熊 4 即将不省熊事,还要继续打它吗?

这些都是值得思考的问题。

说了那么多,口干舌燥,我双手已经饥渴难耐了,迫不及待的想要撸起代码了。

1. 随机访问

上面说了,为了负载均衡,我们必须保证多次出手后,熊 1 到熊 4 被打次数均衡。比如使用随机访问法,根据数学上的概率论,随机出手次数越多,每只熊被打的次数就会越相近。代码实现也比较简单,使用一个随机数,随机访问一个就可以了。

/** 服务器列表 */private static List serverList = new ArrayList<>();static {    serverList.add("192.168.1.2");    serverList.add("192.168.1.3");    serverList.add("192.168.1.4");    serverList.add("192.168.1.5");}/** * 随机路由算法 */public static String random() {    // 复制遍历用的集合,防止操作中集合有变更    List tempList = new ArrayList<>(serverList.size());    tempList.addAll(serverList);    // 随机数随机访问    int randomInt = new Random().nextInt(tempList.size());    return tempList.get(randomInt);}

因为使用了非线程安全的集合,所以在访问操作时操作的是集合的拷贝,下面几种轮询方式中也是这种思想。

写一个模拟请求方法,请求10w次,记录请求结果。

public static void main(String[] args) {    HashMap serverMap = new HashMap<>();    for (int i = 0; i  entry : serverMap.entrySet()) {        System.out.println("IP:" + entry.getKey() + ",次数:" + entry.getValue());    }}

运行得到请求结果。

IP:192.168.1.3,次数:24979IP:192.168.1.2,次数:24896IP:192.168.1.5,次数:25043IP:192.168.1.4,次数:25082

每台服务器被访问的次数都趋近于 2.5w,有点负载均衡的意思。但是随机毕竟是随机,是不能保证访问次数绝对均匀的。

2. 轮询访问

轮询访问就简单多了,拿上面的熊1到熊4来说,我们一个接一个的啪啪 - 打脸,熊1打完打熊2,熊2打完打熊3,熊4打完打熊1,最终也是实现了被打均衡。但是保证均匀总是要付出代价的,随机访问中需要随机,轮询访问中需要什么来保证轮询呢?

/** 服务器列表 */private static List serverList = new ArrayList<>();static {    serverList.add("192.168.1.2");    serverList.add("192.168.1.3");    serverList.add("192.168.1.4");    serverList.add("192.168.1.5");}private static Integer index = 0;/** * 随机路由算法 */public static String randomOneByOne() {    // 复制遍历用的集合,防止操作中集合有变更    List tempList = new ArrayList<>(serverList.size());    tempList.addAll(serverList);    String server = "";    synchronized (index) {        index++;        if (index == tempList.size()) {            index = 0;        }        server = tempList.get(index);;    }    return server;}

由代码里可以看出来,为了保证轮询,必须记录上次访问的位置,为了让在并发情况下不出现问题,还必须在使用位置记录时进行加锁,很明显这种互斥锁增加了性能开销。

依旧使用上面的测试代码测试10w次请求负载情况。

IP:192.168.1.3,次数:25000IP:192.168.1.2,次数:25000IP:192.168.1.5,次数:25000IP:192.168.1.4,次数:25000

3. 轮询加权

上面演示了轮询方式,还记得一开始提出的熊4比较胖抗击打能力强,可以承受别人2倍的挨打次数嘛?上面两种方式都没有体现出来熊 4 的这个特点,熊 4 窃喜,不痛不痒。但是熊 1 到 熊 3 已经在崩溃的边缘,不行,我们必须要让胖着多打,能者多劳,提高整体性能。

/** 服务器列表 */private static HashMap serverMap = new HashMap<>();static {    serverMap.put("192.168.1.2", 2);    serverMap.put("192.168.1.3", 2);    serverMap.put("192.168.1.4", 2);    serverMap.put("192.168.1.5", 4);}private static Integer index = 0;/** * 加权路由算法 */public static String oneByOneWithWeight() {    List tempList = new ArrayList();    HashMap tempMap = new HashMap<>();    tempMap.putAll(serverMap);    for (String key : serverMap.keySet()) {        for (int i = 0; i 

这次记录下了每台服务器的整体性能,给出一个数值,数值越大,性能越好。可以承受的请求也就越多,可以看到服务器 192.168.1.5 的性能为 4,是其他服务器的两倍,依旧 10 w 请求测试。

IP:192.168.1.3,次数:20000IP:192.168.1.2,次数:20000IP:192.168.1.5,次数:40000IP:192.168.1.4,次数:20000

192.168.1.5 承担了 2 倍的请求。

4. 随机加权

随机加权的方式和轮询加权的方式大致相同,只是把使用互斥锁轮询的方式换成了随机访问,按照概率论来说,访问量增多时,服务访问也会达到负载均衡。

/** 服务器列表 */private static HashMap serverMap = new HashMap<>();static {    serverMap.put("192.168.1.2", 2);    serverMap.put("192.168.1.3", 2);    serverMap.put("192.168.1.4", 2);    serverMap.put("192.168.1.5", 4);}/** * 加权路由算法 */public static String randomWithWeight() {    List tempList = new ArrayList();    HashMap tempMap = new HashMap<>();    tempMap.putAll(serverMap);    for (String key : serverMap.keySet()) {        for (int i = 0; i 

依旧 10 w 请求测试,192.168.1.5 的权重是其他服务器的近似两倍,

IP:192.168.1.3,次数:19934IP:192.168.1.2,次数:20033IP:192.168.1.5,次数:39900IP:192.168.1.4,次数:20133

5. IP-Hash

上面的几种方式要么使用随机数,要么使用轮询,最终都达到了请求的负载均衡。但是也有一个很明显的缺点,就是同一个用户的多次请求很有可能不是同一个服务进行处理的,这时问题来了,如果你的服务依赖于 session ,那么因为服务不同, session 也会丢失,不是我们想要的,所以出现了一种根据请求端的 ip 进行哈希计算来决定请求到哪一台服务器的方式。这种方式可以保证同一个用户的请求落在同一个服务上。

private static List serverList = new ArrayList<>();static {    serverList.add("192.168.1.2");    serverList.add("192.168.1.3");    serverList.add("192.168.1.4");    serverList.add("192.168.1.5");}/** * ip hash 路由算法 */public static String ipHash(String ip) {    // 复制遍历用的集合,防止操作中集合有变更    List tempList = new ArrayList<>(serverList.size());    tempList.addAll(serverList);    // 哈希计算请求的服务器    int index = ip.hashCode() % serverList.size();    return tempList.get(Math.abs(index));}

6. 总结

上面的四种方式看似不错,那么这样操作下来真的体现了一开始说的负载均衡吗?答案是不一定的。就像上面的最后一个提问。

又或者每次出手的力度不同,有重有轻,恰巧熊 4 总是承受这种大力度啪啪打脸,熊 4 即将不省熊事,还要继续打它吗?

服务器也是这个道理,每次请求进行的操作对资源的消耗可能是不同的。比如说某些操作它对 CPU 的使用就是比较高,也很正常。所以负载均衡有时不能简单的通过请求的负载来作为负载均衡的唯一依据。还可以结合服务的当前连接数量、最近响应时间等维度进行总体均衡,总而言之,就是为了达到资源使用的负载均衡。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/554363.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

腾讯视频下载安装免费装到手机_腾讯视频怎么上传个人本地视频

不管这个腾讯视频好用与否&#xff0c;都有一大批用户&#xff0c;本文播放器家园网小编分享腾讯视频下载安装免费装到手机_腾讯视频怎么上传个人本地视频。VIP会员频道聚合海量VIP品质内容&#xff0c;连续签到解锁惊喜奖励、摇一摇抽VIP天卡、领取会员专属权益&#xff0c;快…

php mysql 中文_PHP连接MySQL查询结果中文显示乱码解决方法

我们首先假设数据库中采用的编码为UTF-8这时我们在PHP页面中应当首先添加此处charset的值utf-8必须与文件保存时的编码类型一样之后在数据库查询前添加mysql_query("set names utf8");该行语句的编码值也应当与上面的编码值一样。总而言之&#xff0c;网页保存的编码…

怎样将腾讯视频下载到的电影传入手机_腾讯视频怎么缓存视频

不管这个腾讯视频好用与否&#xff0c;都有一大批用户&#xff0c;本文播放器家园网小编分享怎样将腾讯视频下载到的电影传入手机_腾讯视频怎么缓存视频。腾讯视频拥有独立的播放界面&#xff0c;软件采用独立的播放界面进行播放&#xff0c;用户点击喜欢的影视播放之后不会干扰…

腾讯视频主演角色弹幕怎么发

本文播放器家园网小编给大家分享“腾讯视频主演角色弹幕怎么发”。只需要打开腾讯视频&#xff0c;就可以在线享受腾讯视频网站内全部免费高清正版视频、最新影视大片、最独家的综艺、旅游、纪录片&#xff0c;在众多的播放器当中&#xff0c;腾讯视频堪称完美。腾讯视频可以在…

mysql 重装之后_mysql重装之后 复制data

(哇&#xff0c;编程小白的第一篇博客丫&#xff0c;激动)Q one&#xff1a;mysql需要重装&#xff0c;数据该怎么办。方法一&#xff1a;数据表最好是导出成.sql文件&#xff0c;这样才比较安全。方法二&#xff1a;直接copy了data文件&#xff1a;在mysql安装盘下的programda…

360极速浏览器兼容模式怎么设置在哪

360极速浏览器兼容模式怎么设置在哪&#xff0c;360浏览器怎么设置兼容模式?大部分浏览器都有两种视图模式&#xff1a;极速模式、兼容模式&#xff0c;这一点360浏览器也不例外&#xff0c;在加载速度上&#xff0c;极速模式快于兼容模式&#xff0c;要在360浏览器中切换极速…

log4j2 mysql_spring boot使用log4j2将日志写入mysql数据库

log4j2官方例子在spring boot中报错而且还是用的是org.apache.commons.dbcp包我给改了一下使用org.apache.commons.dbcp2包1.log4j2.xml如下:method"getDatabaseConnection" />includeLocation"true">AsyncLogger 表示是异步插入.需要在pom.xml中插入…

如何重置IE浏览器?重置IE浏览器的方法

ie浏览器是一款自带的浏览器服务软件&#xff0c;这款软件使用非常的方便&#xff0c;界面使用非常的简洁&#xff0c;浏览器的功能更加的全面&#xff0c;用户可以使用手机快速搜索&#xff0c;那么如何进行IE浏览器的重置呢?如果用户需要使用IE浏览器&#xff0c;想对IE浏览…

Win10系统怎么锁定IE浏览器主页

核心提示&#xff1a;Win10系统怎么锁定IE浏览器主页?一起看看吧! 目前&#xff0c;不少电脑用户都升级了win10系统&#xff0c;不过&#xff0c;关于win10系统的一些使用方法却不是很了解&#xff0c;比如说&#xff1a;当win10系统的IE浏览器被流氓软件窜改的主页网址该怎么…

vs2010 mysql linq to sql 系列_LINQ to SQL 系列 如何使用LINQ to SQL插入、修改、删除数据...

LINQ和 LINQ to SQL 都已经不是一个新事物了&#xff0c;但是我接触的比较晚&#xff0c;本着绝知此事要躬行的态度&#xff0c;决定写这个系列。本文使用的测试环境是VS 2010&#xff0c;和sql server 2005数据库。第一篇 从CUD开始&#xff0c;如何使用LINQ to SQL插入…

如何在IE浏览器中使用和管理RSS订阅源

核心提示&#xff1a;什么是RSS?简单来说&#xff0c;RSS就像微博一样。在你的源有更新的时候把更新推送给你&#xff0c;或者说在网站有更新的时候告诉你更新的内容。而源就好比是那些微博账号。 什么是RSS?简单来说&#xff0c;RSS就像微博一样。在你的源有更新的时候把更…

redis session 超时时间_Shiro性能优化:解决Session频繁读写问题

点击上方蓝色字体&#xff0c;选择“标星公众号”优质文章&#xff0c;第一时间送达作者 | 张永恒来源 | urlify.cn/YjEZNj背景Shiro 提供了强大的 Session 管理功能&#xff0c;基于 Shiro 实现 Session 共享非常方便&#xff0c;只需要定制一个我们自己的SessionDAO&#x…

360浏览器如何拦截和屏蔽网页广告

在浏览网页的时候总会弹出各种烦人的广告&#xff0c;用户可以使用浏览器设置&#xff0c;然后拦截掉网页的广告&#xff0c;操作起来非常的方便&#xff0c;用户可以使用浏览器马上学习起来&#xff0c;感兴趣的用户就一起来学习起来吧!马上就可以为用户提供最便捷的浏览方式&…

如何申请注销腾讯视频账号

今天小编给大家分享“如何申请注销腾讯视频账号”。腾讯视频在电视剧和电影播放过程中无广告&#xff0c;只要点击播放按钮&#xff0c;除了开头的广告外&#xff0c;视频畅快从头看到尾&#xff0c;当然现在有些电视剧直接把广告植入到剧中&#xff0c;哪怕你开了vip一样无法去…

mysql数据库表名大小写敏感_Mysql数据库名和表名的大小写敏感性问题

导读&#xff1a;一直以来&#xff0c;Mysql数据库名和表名的大小写都是个敏感的问题&#xff0c;困扰着Mysql数据库管理员。在 MySQL 中&#xff0c;数据库和表对应于那些目录下的目录和文件。因而&#xff0c;操作系统的敏感性决定数据库和表命名的大小写敏感。这就意味着数据…

手机优酷缓存的视频在哪找

很多人都喜爱在优酷视频上看剧或是影片&#xff0c;有时出门度假旅游或是乘火车等特殊情况&#xff0c;大家必须用手机优酷来下载好一些自身喜爱看的电视连续剧或是影片&#xff0c;便捷那时候没有网络&#xff0c;还可以在手机优酷上看电视剧&#xff0c;进而消磨无趣的時间。…

mysql触发器如果提示_mysql 触发器

1 引言Mysql的触发器和存储过程一样&#xff0c;都是嵌入到mysql的一段程序。触发器是mysql5新增的功能&#xff0c;目前线上凤巢系统、北斗系统以及哥伦布系统使用的数据库均是mysql5.0.45版本&#xff0c;很多程序比如fc-star管理端&#xff0c;sfrd(das)&#xff0c;dorad…

PP视频怎么设置退出程序时清空本地播放记录

本文小编给大家分享PP视频怎么设置退出程序时清空本地播放记录&#xff0c;如果大家在使用PP视频过程当中遇到类似问题&#xff0c;欢迎阅读本文!大家都知道PP视频作为中国最大的视频分享网站&#xff0c;它有非常全面的视频资源。而我们只要通过下载这个客户端&#xff0c;就可…

python中属性是什么意思啊_python中的“对象属性”和一般属性是什么?

假设你有一个类Personclass Person:name "Samuel"age 50country "India"def method1(self):print("Method 1")print(dir(Person))上述程序的输出如下所示&#xff1a;^{pr2}$从上面的输出中可以看到&#xff0c;它返回该对象的有效属性的排序…

PP视频播放视频时如何关闭弹屏

本文小编给大家带来的是PP视频相关的内容。PP视频播放器官方下载电脑版始终以“用户体验”为生命&#xff0c;您可运行PP视频播放器&#xff0c;在线享受奇艺网站内全部免费高清正版视频。不管是哪个视频播放器都会有喜欢和不喜欢的用户&#xff0c;这是正常的情况&#xff0c;…