为了账号安全,请及时绑定邮箱和手机立即绑定

了解负载均衡算法,长连接下负载均衡算法存在的弊端

标签:
Java

或许很多同学接触过负载均衡,大部分是来自于Nginx里配置的认识,一般情况下为了提高Tomcat的并发量都是基于Nginx做负载均衡,示例如下:

server{
    listen 80;
    server_name www.baidu.com;
    
    #负载均衡池(推荐)
    upstream tomcat1{
        server 192.168.25.141:8080 weight=1;
        server 192.168.25.142:8080 weight=2 max_fails=3 fail_timeout=30s;
        #权重
        #多少次失败之后,任务该服务挂了
        #超时时间
    }
    #负载均衡池(ip_hash)
    upstream tomcat2{
        server 192.168.25.141:8080 weight=1;
        server 192.168.25.142:8080 weight=2;
        ip_hash;#每个ip永远只请求指定的ip,不需要做session处理
    }
    
    location / {
    	proxy_pass http://tomcat1;
    }
}

类似Nginx这种负载均衡器,它主要是一个代理层,但是很多情况下,我们需要手工去实现自己的负载均衡功能,当然,一般在中间件开发当中遇到的比较多(业务系统相对少一点),场景案例如下:

①Dubbo,客户端发起调用的时候,需要从多个地址里面选择一个进行调用

②SpringCloud体系里面的Ribbon负载均衡器

③分布式文件系统(FastDFS,HDFS),文件上传的时候,首先需要去管理节点获取具体的存储节点的IP信息,这个时候,管理节点需要实现负载均衡算法

思考:如果领导让我们实现一个分布式任务调度中间件,我们应该怎么实现呢?

图片描述

方案描述: ①基于Zookeeper实现分布式锁;②到执行时间点时,定时任务工程则去获取分布式锁,谁抢到锁,谁有执行权限。

方案优点: ①思路简单;②实现起来比较容易

方案缺点: ①每个定时工程实现比较复杂,需要手工集成定时器(不同人开发可能选择不同的定时器技术,去定时线程池、JDK Timer、Spring Task、Quartz等,技术得不到统一);②无法有效的管理所有定时任务,实现在线控制任务的状态(暂停、停止、启动等)

图片描述

方案描述: ①每个定时工程只需要实现某个标准接口即可,无需关系定时器问题;②每个定时工程启动的时候连接管理节点,并且把所有定时作业注册到管理节点(封装好Client客户端);③管理节点本身集成定时器,并且提供在线管理每个定时作业的状态;④管理节点通过远程触发的方式去触发具体某个定时工程去执行。

方案优点: ①定时工程开发比较简单;②管理节点具备强大的功能,可以统一管理所有的定时作业

方案缺点: 实现起来会稍微复杂点

回归正题,管理节点在实现远程触发的时候,它必须实现负载策略去选择具体的节点执行任务。这基本上就是开发一个中间件的常见思路了(跟业务系统思想上是存在区别的)

首先,如果去实现常见的负载均衡算法呢?

首先,我们先了解常见的负载均衡算法的种类:①随机;②轮询;③随机+权重;④轮询+权重;⑤最小连接数;

负载均衡的UML图
图片描述

描述:定义一个接口,然后不同类型的负载算法对应不同的实现类

优点:思路简单

缺点:①每个实现类都需要做一些重复的判断工作,比如:List是否为空,如果List只有一条记录的情况直接返回;②具体选择哪个策略完全让用户自己去选择,不是很好

图片描述

描述:①增加一个抽象类,抽象类的作用是做一些通用的工作(比如:判断List是否为空,是否等于1);②增加一个策略类,目的是解耦负载算法和业务的关系。

其次,常见负载算法的大概实现思路是什么呢?

①随机,思路很简单,就是通过Random生成一个随机数,这个随机数就是List的下标值。

②轮询,通过一个全局变量控制当前取值的位置,每次取值时,该值加1,如果一旦该值大于等于List的长度,则重置。

③权重+随机|轮询,核心是如何实现权重呢?其实很简单,根据每条记录的权重值,生成对应比例的数据放到一个新集合即可,这样的话,最后取值的概率跟权重比是一致的。

最后,长连接情况下,负载均衡算法会存在什么问题呢?

在短连接的情况下,请求完成之后释放连接资源,这样情况下即使负载失衡产生的影响也不至于很大,但是长连接它是建立连接之后可以多次通讯不立马释放资源,一旦负载失衡,那么将会导致连接过多的服务器压力过大。请看下面的具体分析:

情况一: 最小连接数算法
描述:最小连接数,通过判断哪个服务器的连接数最小,然后选择连接到该服务器
缺点:①如果某个服务器一旦宕机,重启之后,那么它的连接数最小,大量的连接就会涌进来,导致该服务器压力非常的大;②如果新增一个服务器节点,那么道理是一样的。

情况二: 轮询算法
描述:通过轮询的方式把连接平均的分配给每个服务器
缺点:①如果某个服务器一旦宕机,重启之后,它的连接数永远最小,造成每个服务器的连接数不够平衡;②如果新增一个服务器节点,那么道理是一样的。

解决思路:采用轮询算法,并且给每个连接设置生命周期,比如:通过心跳检查如果该连接没有数据包时,则断开连接,让连接重连,这样的话,会逐渐让每个服务器的连接数保持平衡。

负载均衡算法的Demo源码:
https://gitee.com/zwyyf/demo-loadbalance.git

慕课网专栏(架构思维成长之微服务+仿百度网盘源码):
https://www.imooc.com/read/73

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消