你管这破玩意儿叫负载均衡?

你管这破玩意儿叫负载均衡?

    • 那么四层负载均衡器是如何工作的呢
    • 总结

相信大家都听过这样的一道经典面试题:「请说出在淘宝网输入一个关键词到最终展示网页的整个流程,越详细越好」

这个问题很难,涉及到 HTTP,TCP,网关,LVS 等一系列相关的概念及诸多协议的工作机制,如果你能掌握到这其中的每个知识点,那将极大地点亮你的技能树,对于网络是如何运作也会了然于胸,即便不能完全掌握,但知道流量怎么流转的对你排查定位问题会大有帮助,我之前就利用这些知识定位到不少问题,为了弄清楚整个流程,我查阅了很多资料,相信应该可以把这个问题讲明白,不过写着写着发现篇幅实在太长,所以分为上下两篇来分别介绍一下,本篇先介绍流量在后端的的整体架构图,下一篇会深入剖析各个细节点,如 LVS ,NAT 的工作细节等,这其中会涉及到交换机,路由器的工作机制等知识点,相信大家看了肯定有帮助。

李大牛创业了,由于前期没啥流量,所以他只部署了一台 tomcat server,让客户端将请求直接打到这台 server 上

在这里插入图片描述

这样部署一开始也没啥问题,因为业务量不是很大,单机足以扛住,但后来李大牛的业务踩中了风口,业务迅猛发展,于是单机的性能逐渐遇到了瓶颈,而且由于只部署了一台机器,这台机器挂掉了业务也就跌零了,这可不行,所以为了避免单机性能瓶颈与解决单点故障的隐患,李大牛决定多部署几台机器(假设为三台),这样可以让 client 随机打向其中的一台机器,这样就算其中一台机器挂了,另外的机器还存活,让 client 打向其它没有宕机的机器即可

在这里插入图片描述

现在问题来了,client 到底该打向这三台机器的哪一台呢,如果让 client 来选择肯定不合适,因为client 必须知道有哪几台 server,然后再用轮询等方式随机连接其中一台机器,但如果其中某台 server 宕机了,client 是无法提前感知到的,那么很可能 client 会连接到这台宕掉的 server 上,所以选择哪台机器来连接的工作最好放在 server 中,具体怎么做呢,在架构设计中有个经典的共识:没有什么是加一层解决不了的,如果有那就再加一层,所以我们在 server 端再加一层,将其命名为 LB(Load Balance,负载均衡),由 LB 统一接收 client 的请求,然后再由它来决定具体与哪一个 server 通信,一般业界普遍使用 Nginx 作为 LB

在这里插入图片描述
采用这样的架构设计总算支撑了业务的快速增长,但随后不久李大牛发现这样的架构有点问题:所有的流量都能打到 server 上,这显然是有问题的,不太安全,那能不能在流量打到 server 前再做一层鉴权操作呢,鉴权通过了我们才让它打到 server 上,我们把这一层叫做网关(为了避免单点故障,网关也要以集群的形式存在)

在这里插入图片描述
这样的话所有的流量在打到 server 前都要经过网关这一层,鉴权通过后才把流量转发到 server 中,否则就向 client 返回报错信息,除了鉴权外,网关还起到风控(防止羊毛党),协议转换(比如将 HTTP 转换成 Dubbo),流量控制等功能,以最大程度地保证转发给 server 的流量是安全的,可控的。

这样的设计持续了很长一段时间,但是后来李大牛发现这样的设计其实还是有问题,不管是动态请求,还是静态资源(如 js,css文件)请求都打到 tomcat 了,这样在流量大时会造成 tomcat 承受极大的压力,其实对于静态资源的处理 tomcat 不如 Nginx,tomcat 每次都要从磁盘加载文件比较影响性能,而 Nginx 有 proxy cache 等功能可以极大提升对静态资源的处理能力。

所谓的 proxy cache 是指 nginx 从静态资源服务器上获取资源后会缓存在本地的内存+磁盘中,下次请求如果命中缓存就从 Nginx 本机的 Cache 中直接返回了

所以李大牛又作了如下优化:如果是动态请求,则经过 gateway 打到 tomcat,如果是 Nginx,则打到静态资源服务器上
在这里插入图片描述
这就是我们所说的 动静分离,将静态请求与动态请求分开,这样 tomcat 就可以专注于处理其擅长的动态请求,而静态资源由于利用到了 Nginx 的 proxy cache 等功能,后端的处理能力又上了一个台阶。

另外需要注意的是并不是所有的动态请求都需要经过网关,像我们的运营中心后台由于是内部员工使用的,所以它的鉴权与网关的 api 鉴权并不相同,所以我们直接部署了两台运营中心的 server ,直接让 Nginx 将运营中心的请求打到了这两台 server 上,绕过了网关。

在这里插入图片描述
当然为了避免单点故障 Nginx 也需要部署至少两台机器,于是我们的架构变成了下面这样,Nginx 部署两台,以主备的形式存在,备 Nginx 会通过 keepalived 机制(发送心跳包) 来及时感知到主 Nginx 的存活,发现宕机自己就顶上充当主 Nginx 的角色
在这里插入图片描述
看起来这样的架构确实不错,但要注意的是 Nginx 是七层(即应用 层)负载均衡器 ,这意味着如果它要转发流量首先得和 client 建立一个 TCP 连接,并且转发的时候也要与转发到的上游 server 建立一个 TCP 连接,而我们知道建立 TCP 连接其实是需要耗费内存(TCP Socket,接收/发送缓存区等需要占用内存)的,客户端和上游服务器要发送数据都需要先发送暂存到到 Nginx 再经由另一端的 TCP 连接传给对方。
在这里插入图片描述
所以 Nginx 的负载能力受限于机器I/O,CPU内存等一系列配置,一旦连接很多(比如达到百万)的话,Nginx 抗负载能力就会急遽下降。
经过分析可知 Nginx 的负载能力较差主要是因为它是七层负载均衡器必须要在上下游分别建立两个 TCP 所致,那么是否能设计一个类似路由器那样的只负载转发包但不需要建立连接的负载均衡器呢,这样由于不需要建立连接,只负责转发包,不需要维护额外的 TCP 连接,它的负载能力必然大大提升,于是四层负载均衡器 LVS 就诞生了,简单对比下两者的区别。
在这里插入图片描述
可以看到 LVS 只是单纯地转发包,不需要和上下游建立连接即可转发包,相比于 Nginx 它的抗负载能力强、性能高(能达到 F5 硬件的 60%),对内存和cpu资源消耗比较低

那么四层负载均衡器是如何工作的呢

负载均衡设备在接收到第一个来自客户端的SYN 请求时,即通过负载均衡算法选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器 IP ),直接转发给该服务器。TCP 的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。

综上所述,我们在 Nginx 上再加了一层 LVS,以让它来承接我们的所有流量,当然为了保证 LVS 的可用性,我们也采用主备的方式部署 LVS,另外采用这种架构如果 Nginx 容量不够我们可以很方便地进行水平扩容,于是我们的架构改进如下:
在这里插入图片描述
当然只有一台 LVS 的话在流量很大的情况下也是扛不住的,怎么办,多加几台啊,使用 DNS 负载均衡,在 DNS 服务器解析域名的时候随机打到其中一台 LVS 不就行了
在这里插入图片描述
通过这样的方式终于可以让流量稳定流转了,有个点可能一些朋友会有疑问,下面我们一起来看看

既然 LVS 可以采用部署多台的形式来避免单点故障,那 Nginx 也可以啊,而且 Nginx 在 1.9之后也开始支持四层负载均衡了,所以貌似 LVS 不是很有必要?

如果不用 LVS 则架构图是这样的
在这里插入图片描述
通过部署多台 Nginx 的方式在流量不是那么大的时候确实是可行,但 LVS 是 Linux 的内核模块,工作在内核态,它直接在内核中处理数据包,避免了用户空间和内核空间切换的开销,它的处理速度非常快,适合极高的并发请求。

而 Nginx 工作在用户态,所以在性能和稳定性上 Nginx 是不如 LVS 的,通过 LVS 进行初级流量分发,然后由 NGINX 进行更复杂的应用层处理,实现了功能和性能的最佳组合。这就是为什么我们要采用 LVS + Nginx 的部署方式。

另外相信大家也注意到了,如果流量很大时,静态资源应该部署在 CDN 上, CDN 会自动选择离用户最近的节点返回给用户,所以我们最终的架构改进如下
在这里插入图片描述

总结

架构一定要结合业务的实际情况来设计,脱离业务谈架构其实是耍流氓,可以看到上文每一个架构的衍化都与我们的业务发展息息相关,对于中小型流量没有那么大的公司,其实用 Nginx 作为负载均衡足够,在流量迅猛增长后则考虑使用 lvs+nginx,当然像美团这样的巨量流量(数十 Gbps的流量、上千万的并发连接),lvs 也不管用了(实测虽然使用了 lvs 但依然出现了不少丢包的现象)所以它们开发出了自己的一套四层负载均衡器 MGW。
另外看了本文相信大家对分层的概念应该有更透彻的理解,没有什么是分层解决不了的事,如果有,那就再多加一层,分层使每个模块各司其职,功能解藕,而且方便扩展,大家很熟悉的 TCP/IP 就是个很好的例子,每层只管负责自己的事,至于下层是什么实现的上层是不 care 的

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

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

相关文章

MATLAB基础应用精讲-【数模应用】SPSSPRO数据处理

目录 SPSS SPSSRO 数据标签 1、作用 2、输入输出描述 3、案例示例 4、案例数据

Ubuntu 中 Pycharm 的一个奇怪bug:命令行换行处会丢失字符

如果命令行一行显示不完原本连续的一行,那么在末尾处的若干个字符可能会丢失。 可能的解决方案: 1. 检查 PyCharm 终端设置 PyCharm 的终端可能需要配置,以确保换行时不会丢失字符。 打开 PyCharm。进入 File > Settings(W…

Python第二语言(二、Python语言基础)

目录 1. python中常用的6中数据类型 2. Print语句(输出程序) 3. 字面量 4. 注释 5. 变量 6. 数据类型 7. type()语句:查询数据类型 8. 数据类型转换语句 9. 标识符 10. 算术运算符 11. 赋值运算符 && 复合赋值运算符 12. …

3. redis常见部署架构

redis常见部署架构 一、redis常见部署架构1、常见部署架构2、多实例部署2.1 规划安装目录、配置文件2.2.2 编辑实例配置文件2.2.3 启动实例2.2.4 测试数据读写 3、redis主从复制3.1 规划3.2 从服务器配置3.3 验证主从状态3.4 主从角色切换 4、分片集群4.1 原理4.2 分片集群的部…

如何反编译jar并修改后还原为jar

如何反编译jar并修改后还原为jar 目标:修改jar包中某个类的某个方法后还原为新的jar 1.新建android工程,把旧的jar添加为lib 2.用jadx-gui打开旧的jar并保存所有资源 3.找到保存的资源中想修改的.java类 4.复制类中的内容, 在android工程中新建一个同样路径的包,并在包下创建…

CSAPP Lab02——Bomb Lab完成思路详解

看见的看不见的 瞬间的永恒的 青草长啊大雪飘扬 ——月亮之上 完整代码见:CSAPP/bomb at main SnowLegend-star/CSAPP (github.com) 01 字符串比较 简单的把输入的字符串和地址“0x402400”内早已存储的字符串相比较。如果两个字符串相等则函数返回,否…

【Git】如何不管本地文件,强制git pull

要在 Git 中强制执行 git pull 操作,忽略本地文件的更改,可以按照以下步骤操作: 保存当前工作状态:如果你有未提交的更改,可以使用 git stash 将这些更改存储起来。 git stash强制拉取最新代码:使用 git re…

力扣2156.查找给定哈希值的子串

力扣2156.查找给定哈希值的子串 rolling hash:求带权的值 左边是高位 右边是低位 本题要求左边低位 只要反向求即可 class Solution {public:string subStrHash(string s, int power, int modulo, int k, int hashValue) {int n s.size();long long M modulo,p…

ffmpeg视频编码原理和实战-(2)视频帧的创建和编码packet压缩

源文件&#xff1a; #include <iostream> using namespace std; extern "C" { //指定函数是c语言函数&#xff0c;函数名不包含重载标注 //引用ffmpeg头文件 #include <libavcodec/avcodec.h> } //预处理指令导入库 #pragma comment(lib,"avcodec.…

9.抽象类和接口

抽象类 抽象类概念 在面向对象的概念中&#xff0c;所有的对象都是通过类来描绘的&#xff0c;但是反过来&#xff0c;并不是所有的类都是用来描绘对象的&#xff0c;如果一个类中没有包含足够的信息来描绘一个具体的对象&#xff0c;这样的类就是抽象类 比如&#xff1a; 我…

微信小程序动画和Canvas笔记

微信小程序动画和Canvas 动画 使用wx.createAnimation创建动画对象 // 创建动画对象 const animation wx.createAnimation({duration: 1000, // 动画持续时间timingFunction: ease, // 动画速度曲线delay: 0, // 动画延迟时间transformOrigin: 50% 50% 0, // 动画的中心点 …

error /var/lib/jenkins/workspace/*/node_modules/node-sass: Command failed.

原因&#xff1a;node-sass版本不一致 版本图&#xff1a; 解决方案&#xff1a; 进入到jenkins项目目录下&#xff0c;修改package.json文件 将7.0.1改成6.0.1版本

【python深度学习】——pytorch中tensor的view、resize(resize_)与reshape

TOC 1. view() view()方法具有以下特性&#xff1a; 它只能在tensor是连续的时候使用&#xff08;可以调用is_contiguous()方法查看tensor是否连续&#xff09;, 如果要对不连续的张量使用&#xff0c; 需要先使用.contiguous()使其在内存上连续。view()方法不改变tensor的s…

Python自建chatgpt服务器:使用Flask实现类似Chat服务器流式API接口

引言 使用Flask框架可以轻松实现一个类似chatgpt流式响应的接口&#xff0c;该接口通过POST请求接收prompt和history参数&#xff0c;分别对应为聊天系统的提示词和对话历史&#xff0c;server则给予server-sent event (SSE)返回聊天系统的响应。 服务端 开发前的思考 我们…

【LeetCode每日一题】3067. 在带权树网络中统计可连接服务器对数目-DFS和图

Hey我的编程小伙伴们&#x1f44b;&#xff0c;今天我要和大家分享一道我在LeetCode上遇到的超有趣的题目——编号3067的“在带权树网络中统计可连接服务器对数目”。这是一道非常适合练习DFS和图的题目哦&#xff01;&#x1f913;&#x1f4bb; 邻接图是什么&#xff1f; 在…

2024.05.22 校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、校招 | TP-LINK 2025届提前批校园招聘正式启动 校招 | TP-LINK 2025届提前批校园招聘正式启动 2、实习 | 航空工业一飞院2024年实习生招聘正式启动&#xff01; 实习 | 航空工业一飞院…

为Ubuntu 14.04升级 Kernel V4.4的内核

1&#xff1a;下载2个文件 wget https://kernel.ubuntu.com/mainline/v4.4-wily/linux-headers-4.4.0-040400-generic_4.4.0-040400.201601101930_amd64.deb wget https://kernel.ubuntu.com/mainline/v4.4-wily/linux-image-4.4.0-040400-generic_4.4.0-040400.201601101930_…

构建LangChain应用程序的示例代码:14、使用LangChain、GPT和Activeloop的Deep Lake来处理代码库

使用LangChain、GPT和Activeloop的Deep Lake来处理代码库 在本教程中 我们将使用Langchain Activeloop的Deep Lake与GPT一起分析LangChain本身的代码库。 设计 准备数据&#xff1a; 使用langchain_community.document_loaders.TextLoader上传所有Python项目文件。我们将…

【加密与解密】【03】加密系统

术语 RSA&#xff0c;加密算法&#xff0c;同时也是一个公司的名称&#xff0c;该公司制定了PKCS公钥加密标准PKI&#xff0c;Public Key Infrastructure&#xff0c;公钥基础设施PKCS&#xff0c;Public Key Cryptography Standards&#xff0c;公钥加密标准X.509&#xff0c…

模式识别选择题

影响K-均值聚类算法效果的主要因素之一是什么&#xff1f; A. 初始聚类中心的选取 B. 样本输入顺序 C. 模式相似性测度 D. 分类准则 答案&#xff1a;A支持向量机&#xff08;SVM&#xff09;在处理非线性问题时&#xff0c;通常使用什么方法&#xff1f; A. 引入核函数 B. 增加…