Java开发 - 负载均衡你了解多少?

news2025/1/17 6:06:15

前言

前面很多篇博客都有涉及到负载均衡,而负载均衡也并不是某一个框架的专利,从博主接触Java以来,使用的很多框架都自带了负载均衡的特点。今天,我们就来一探究竟,了解下负载均衡是什么,该怎么在项目中使用负载均衡。

什么是负载均衡

负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。

负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。

通俗点来讲,就好比你要去蹲坑,坑位有五六七八个,你去哪个坑都能解决你的问题,你可能这次去一号坑,下次二号坑......总之,可随机;也可以你自己喜欢哪个坑就常去哪个坑,这个叫权重;甚至你可以每次不重样,这就是轮训。比较常见的就这几张,实际上,负载均衡的策略远比我们想象的要多。

具体有哪些负载均衡策略,可以查看以下内容:

负载均衡有哪些常见策略?

负载均衡百度百科

其实吧,具体有哪些我不敢说不重要,你只要知道常用的几种就可以了,但涉及到不同的框架,可能存在负载均衡方式不一样的情况,需要在使用中慢慢体会。 

为什么要使用负载均衡

我们可以假设一下,比如我们要在618去购买一个商品,这个商品只存在于一台服务器上,但是618大促价格很优惠,很多人都要去买,结果抢购的时候发现,由于访问量过载导致服务器卡死或者反应很慢,你的用户最后骂骂咧咧的卸载了你的应用,并发誓再也不用了,是不是血亏?

但是,如果你的商品服务器有多台,通过负载均衡策略将大流量分流到不同的服务器上,缓解了服务器压力,用户在购买的时候非常流畅,那么用户会不会更加喜欢使用你的应用呢?答案是肯定的。

我记得十几年前上学的时候,那时还是GPRS网络,网页QQ慢的勒,但当时并不觉得慢,只是觉得新奇,用现在的互联网思想来说,GPRS恐怕就是静止的网页,现在别说GPRS了,4G网很多人都不用了,更别提E网和3G网络了,卡卡的应用在当前快节奏的生活中完全无法生存。而这,就是我们要使用负载均衡的原因。

有哪些常用框架自带负载均衡

具体有哪些框架带负载均衡策略?这个其实是有很多的,我们可以查看上面博主推荐的两篇文章。此处,博主根据自己的使用情况,将用过的包含负载均衡功能的框架和大家做一个简单的分享,以便大家在使用的过程中能够明确目标,提高效率。

Nacos负载均衡

Nacos的负载均衡是在集群环境下,同时存在多个相同的服务B,此时服务A需要去调用服务B,因为B服务存在多个,那么具体调用哪个服务B呢?此时就用到了负载均衡,默认情况下是轮询的,不会厚此薄彼,但我们希望这种负载均衡可以优先本集群内调用,若本集群内的服务B不可用,再去调用其他集群的服务B。详情看下图:

我们总是希望集群A的实例优先调用集群A的其他实例,如果发生其他实例宕机的情况,再去调用其他集群的实例。这样的调用和负载均衡在上一篇中博主有详细讲解,此处不再赘述,传送门:Java开发 - 带你了解集群间的相互调用,你还在等什么?

但是吧,话说回来,这又和Nacos又有什么关系呢?实际上,Nacos只是起到了注册中心的作用,真正的负载均衡并不是Nacos,而是另有其人,我们继续往下面看。

RestTemplate负载均衡

Java开发 - 带你了解集群间的相互调用,你还在等什么?

在上面这篇博客中,博主分别是用了RestTemplate和Dubbo两个远程访问的RPC组件,其实还有一个RPC组件Feign,但基本都差不多,比如RestTemplate的负载均衡,我们在yml文件中添加了如下配置:

helloWorld:
  ribbon:
#    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则

还需要将RestTemplate交给Bean:

package com.codingfire.helloservice.config;
 
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
 
@Configuration
public class RestTemplateConfig {
 
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
 

如此这般,你就可以直接使用RestTemplate了。

被注释的是随机访问其他服务,正在使用的是优先访问本集群的服务,本集群服务宕机才会访问其他集群的服务。这样就可以减轻服务器的压力,就好比一个工作,一个人做的时候累死了,给你加一个人一起做,一人一半,就轻松太多了。

但由于RestTemplate有如下缺点:

  • 不能针对不同的HTTP请求方法(GET,POST,PUT,DELETE)进行定制化处理;
  • 不支持异步HTTP请求
  • 没有良好的API文档,导致开发者很难理解和使用它;
  • 错误处理机制不够完善,很难捕获和处理请求过程中的异常。

基于其缺点和其他RPC的优势, RestTemplate现在已经很少人用了。但若是一些简单的项目,还是有使用价值的,毕竟使用起来是真的简单,可以不使用注册中心,但前提是你不用负载均衡,通过ip:port+路径的方式请求。总觉得这么做不太妥当,只能说,看项目规模和投入成本吧,这直接决定了你所用的技术。

Dubbo负载均衡

现在来说Dubbo,Dubbo的负载均衡其实和RestTemplate差不多,毕竟都是远程调用,不同点在于Dubbo必需要使用注册中心,否则无法发现服务,当然RestTemplate也是可以使用注册中心的,在这篇博客中我们有详细教程:Java开发 - 带你了解集群间的相互调用,你还在等什么?

Dubbo的负载均衡在这篇博客中也有详细教程,但是,博主查阅了不少资料,关于Dubbo怎么优先访问本集群的实例还没有解决,算是一个遗憾,关于Dubbo的详细介绍,博主后期准备单独出一篇内容来详细介绍,还请大家稍安勿躁。

Dubbo的负载均衡在配置中设置:

dubbo:
  protocol:
    port: -1 # 设置Dubbo服务调用的端口 设置-1能够实现动态自动设置合适端口,生成规则是从20880开始递增
    name: dubbo # 设置端口名称,一般固定就叫dubbo
  registry:
    address: nacos://localhost:8848 # 配置当前Dubbo注册中心的类型和地址
  consumer:
    check: false # 设置为false表示当前项目启动时,不检查要调用的远程服务是否可用,避免报错

只要port设置-1,就可以动态设置合适的端口,你不用关心IP,这就是注册中心的妙用,他们都会被注册到注册中心,Dubbo可以根据其注册名找到对应服务。

其负载均衡算法博主推荐这篇文章给大家看看:

dubbo的负载均衡详解 讲解的倒是挺详细,大家只要知道怎么用就可以。

KeepAlived负载均衡

KeepAlived主要作用是IP飘移,博主曾在数据库使用,做IP的漂移,其好处是虚拟一个IP作为链接的对象,也可用于代理web服务器,不过相较于Nginx来说相对要复杂些,但并不是不可以。

一般来说,我们经常把使用了KeepAlived的框架称为高可用架构,具体怎么个高可用,推荐两篇博客给大家看看:

Keepalived 实现负载均衡

Keepalived负载均衡 

关于KeepAlived的使用,此处暂不讲解,后续陆陆续续出吧,总有讲解完的一天,想想都是一个浩大的工程。

Nginx负载均衡

刚刚有提到Nginx代理,Nginx常被用来做web的代理服务器,或者是反向代理,关于web服务器的代理就是基于反向代理的,只不过代理的是多台服务器,属于是静态资源的集群,可见一下配置:

#upstream指令可以定义一组服务器
upstream targetserver{	
    server 192.168.0.121:8080;
    server 192.168.0.121:8081;
}

server {
    listen       8080;
    server_name  localhost;
    location / {
        proxy_pass http://targetserver;
    }
}

Nginx提供了如下负载均衡策略:

名称说明特点
轮询默认方式
weight权重方式根据权重分发请求,权重大的分配到请求的概率大
ip_hash依据ip分配方式根据客户端请求的IP地址计算hash值, 根据hash值来分发请求, 同一个IP发起的请求,会发转发到同一个服务器上
least_conn依据最少连接方式哪个服务器当前处理的连接少,请求优先转发到这台服务器
url_hash依据url分配方式根据客户端请求url的hash值,来分发请求, 同一个url请求,会发转发到同一个服务器上
fair依据响应时间方式优先把请求分发给处理请求时间短的服务器

比如权重:

#upstream指令可以定义一组服务器
upstream targetserver{	
    server 192.168.0.121:8080 weight=10;
    server 192.168.0.121:8081 weight=5;
}

详细的配置此处不再赘述,此处只做扫盲,请自行查找。 

Mycat负载均衡

Mycat是啥应该都知道吧?如果你不知道是啥,那分库分表总该知道吧?没错Mtcat就是用于分库分表的框架。

所以,Haproxy+keepalived+mycat高可用负载均衡集群你了解多少?

在Haproxy的配置文件中有这么一段配置:

listen  mycat
        bind 0.0.0.0:3300
        mode tcp
        balance roundrobin
        server mycat-120 192.168.0.120:8066 check port 8066 maxconn 300
        server mycat-121 192.168.0.121:8066 check port 8066 maxconn 300

Haproxy监听mycat,并且做了负载均衡,其逻辑是,keepalived IP飘移并且监听Haproxy状态,Haproxy监听mycat,mycat连接数据库做分库分表。此处主要是做了数据库连接的负载均衡,详细的步骤博主暂时就不讲解了,大家可自行了解,博主也会在后续的博客中详细加讲解这种模式的使用。

Gateway负载均衡

Gateway也是具备一定的负载均衡能力的,Gateway的负载均衡规则是通过服务注册中心的服务名/接口实现负载均衡的,实际上并没有什么明显的配置,如随机啊,轮询啊,权重啊这些。

如果你看了Nacos的负载均衡,并看了那篇推荐的博客,你会发现,在Nacos中,可以对集群的服务配置权重,虽然并不是直接通过Gateway来设置权重,只能说这也是种办法。

有些同学会讲,我在配置文件中通过URI设置lb不是负载均衡吗?是的!uri 的协议为 lb( load Balance ),表示启用 Gateway 的负载均衡功能。但这实际上并不是Gateway本身的能力,是以注册中心上微服务名为路径创建动态路由进行转发,从而实现的动态路由功能。本质上是Nacos(注册中心)的能力。见以下配置:

spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求

虽然说负载均衡是Nacos的能力,但由于配置在Gateway下,我们就当是Gateway的能力。

给大家推荐几篇网关的文章:

三、Gateway实现负载均衡

23.Gateway 动态路由,负载均衡 

结语

你还知道哪些具备负载均衡能力的框架呢?可以和博主一起探讨一下,博主抛砖引玉,还望大家不吝赐教。本篇博客写完了,但博主的心却很沉重。虽然讲的比较浅,但是博主想的却很多,也看到了自己的很多不足之处,技术这条路从来都不是一蹴而就的,它是一门绝对不容出错的艺术,因为错了,就无法得到想要的结果。未来很远,还需要继续努力。

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

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

相关文章

Python 函数:理解并使用 return 语句

你好,我是悦创。 函数在 Python 编程中起着至关重要的作用。他们封装了一段代码,并给它一个名字,这样我们可以在程序的任何地方,通过这个名字来调用这段代码。return 是函数的一个重要组成部分,它可以使函数输出一个值…

差分方程转化为Z变换方程

差分方程是描述离散时间系统动态行为的数学工具,而Z变换则是将离散时间信号从时间域转换到复频域的工具。因此,将差分方程转换为Z变换方程可以方便我们在复频域分析离散时间系统的动态行为。 假设我们有一个差分方程: a n x [ n ] a n − 1 x [ n − 1…

rabbitmq第二课-RabbitMQ核心编程模型以及消息应用场景详解

一、回顾RabbitMQ基础概念 二、RabbitMQ基础编程模型 使用RabbitMQ提供的原生客户端API进行交互。这是使用RabbitMQ的基础。 1.1、maven依赖 <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version&g…

C语言:使用指针使字符串逆序

题目&#xff1a; 链接&#xff1a;字符逆序__牛客网 来源&#xff1a;牛客网 将一个字符串str的内容颠倒过来&#xff0c;并输出。 输入描述: 输入一个字符串&#xff0c;可以有空格 输出描述: 输出逆序的字符串 示例1 输入 I am a student 输出 tneduts a ma I …

VUE 2X 生命周期 ⑩①

目录 文章有误请指正&#xff0c;如果觉得对你有用&#xff0c;请点三连一波&#xff0c;蟹蟹支持✨ V u e j s Vuejs Vuejs初见生面周期分析生命周期生命周期总结总结 文章有误请指正&#xff0c;如果觉得对你有用&#xff0c;请点三连一波&#xff0c;蟹蟹支持✨ ⡖⠒⠒⠒⠤⢄…

《算法设计与分析》学习笔记

目录 算法基本概念 算法的定义 算法复杂度分析 渐近记号 ①渐近上界记号O ②渐近下界记号Ω ③渐近紧确界记号 Θ ④非渐近紧确上界记号o ⑤非渐近紧确下界记号ω 渐进记号极限定义 分治 分治步骤 递归树 ​编辑代入法 主方法 改变变量 二叉树 堆 建堆 堆排…

【promptulate专栏】使用GPT和XMind快速构建思维导图

本文节选自笔者博客&#xff1a;https://www.blog.zeeland.cn/archives/ao302950h3j &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是Zeeland&#xff0c;全栈领域优质创作者。&#x1f4dd; CSDN主页&#xff1a;Zeeland&#x1f525;&#x1f4e3; 我的博客&#…

【Java】缓存常见问题及解决方式

文章目录 一、缓存常见问题二、数据不一致2.1、一致性问题2.2、解决方案 三、缓存穿透3.1、问题3.2、解决方案布隆过滤器使用布隆过滤器解决缓存穿透 四、缓存击穿4.1、问题4.2、解决方案 五、缓存雪崩5.1、问题5.2、解决方案 六、大key及热点key6.1、问题6.2、解决方案大key热…

【Leetcode刷题】字符串匹配

本篇文章为LeetCode 字符串匹配模块的刷题笔记&#xff0c;仅供参考。 目录 Leetcode28.找出字符串中第一个匹配项的下标Leetcode214.最短回文串Leetcode459.重复的子字符串Leetcode686.重复叠加字符串匹配Leetcode1023.驼峰式匹配Leetcode1392.最长快乐前缀Leetcode1668.最大重…

【SpringBoot】一、SpringBoot3改变新特性

前言 本文适合具有springboot的基础的同学。 SpringBoot3改变&新特性 一、前置条件二、自动配置包位置变化1、Springboot2.X2、Springboot3.X 三、jakata api迁移1、Springboot2.X2、Springboot3.X3、SpringBoot3使用druid有问题&#xff0c;因为它引用的是旧的包 四 新特…

App Crawler

Google官方出了一款App遍历工具App Crawler。 文档&#xff1a;应用抓取工具 | Android 开发者 | Android Developers App Crawler工具是Android Jetpack的一部分&#xff0c;它可自动的运行你的App&#xff0c;不需要编写或维护任何代码。 通过App Crawler运行App&…

实训四:索引与视图 - 索引(teachingdb数据库)

索引与数据库完整性 第1关&#xff1a;索引任务描述相关知识索引是什么索引的分类索引的创建和删除查询表中索引 编程要求参考代码 第2关&#xff1a;删除索引-练习任务描述相关知识编程要求测试说明参考代码 第1关&#xff1a;索引 任务描述 本关任务&#xff1a;为 student…

【Leetcode60天带刷】day21二叉树——530.二叉搜索树的最小绝对差 ,501.二叉搜索树中的众数 ,236. 二叉树的最近公共祖先

题目&#xff1a; 530. 二叉搜索树的最小绝对差 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的绝对值。 示例 1&#xff1a; 输入&#xff1a;root [4,2,6,1,3] 输出&#xff1…

chatgpt赋能python:Python与电影评分

Python与电影评分 近年来&#xff0c;越来越多的人选择通过网络来观看电影。然而&#xff0c;在选择一部电影时&#xff0c;看到的只是电影名称和海报。这时就需要借助电影评分来给自己做出更明智的选择。Python作为一门流行的编程语言&#xff0c;它的应用程序提供了许多有用…

图形视图体系结构(Graphics View)

Graphics View框架结构的主要特点 Graphics View框架结构的主要特点如下。 &#xff08;1&#xff09;在Graphics View框架结构中&#xff0c;系统可以利用Qt绘图系统的反锯齿、OpenGL工具来改善绘图性能。 &#xff08;2&#xff09;Graphics View支持事件传播体系结构&…

利用Charles进行Mock测试

一、Charles介绍 Charles是一款用Java编写的代理软件&#xff0c;电脑或者手机访问网站首先会访问到Charles代理工具上&#xff0c;由代理工具再把访问数据转发到相应的网站上&#xff0c;所以可以很好的通过设置Charles&#xff0c;对接口的请求和响应进行加工处理。 …

【Linux】Linux权限的概念、Linux权限管理、文件类型和访问权限的设置、粘滞位介绍

文章目录 1.Linux权限的概念2.Linux权限管理2.1文件访问者的分类2.2文件类型的访问权限2.3文件权限值的表示方法2.4文件访问权限的相关设置方法 3.目录的权限4.粘滞位 1.Linux权限的概念 在生活中&#xff0c;一件事情是否允许被一个人做&#xff0c;就是叫做权限&#xff0c;权…

【Leetcode60天带刷】day32回溯算法——122.买卖股票的最佳时机II ,55. 跳跃游戏 ,45.跳跃游戏II

​ 题目&#xff1a; 122. 买卖股票的最佳时机 II 给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买&#xff0c;然后在 同一…

MYSQL数据库应用中的17个关键问题

一、单Master 单Master的情况是普遍存在的&#xff0c;对于很多个人站点、初创公司、小型内部系统&#xff0c;考虑到成本、更新频率、系统重要性等问题&#xff0c;系统只依赖一个单例数据库提供服务&#xff0c;基本上已经满足需求。这种场景下我觉得重点应该关注的话题有上图…

图像预处理 Tricks【1】:Contours

系列文章目录 文章目录 系列文章目录前言1. cv2.findContours()1.1. 方法概述1.2. cv2.findContours()1.2.1. 轮廓检索模式1.2.2. 轮廓逼近方法 2. cv2.drawContours()2.1. 方法概述2.2. cv2.drawContours() 3. cv2.contourArea()3.1. 方法概述3.2. cv2.contourArea()3.3. 存在…