一、lvs的四种工作模式:
LVS 有四种主要工作模式:NAT 模式、DR 模式、TUN 模式和Full-NAT 模式
1、NAT模式:
工作原理
- LVS 作为客户端和真实服务器(RS)之间的中间节点,接收客户端请求后,修改请求的目标 IP 地址(改为 RS 的 IP),并转发给 RS。
- RS 处理请求后,直接将响应返回给 LVS(需配置网关为 LVS),LVS 再修改响应的源 IP 地址(改回 VIP),返回给客户端。
关键特点
- 单一 IP 暴露:客户端只看到 LVS 的虚拟 IP(VIP),RS 的真实 IP 对客户端透明。
- 请求和响应都经过 LVS:LVS 成为流量瓶颈(尤其在大流量场景下)。
- RS 必须与 LVS 在同一网段:RS 的网关需指向 LVS。
优点
- 实现简单,无需对 RS 进行特殊配置。
- 支持跨网段部署(只要 LVS 能访问 RS)。
缺点
- LVS 需处理双向流量,性能受限。
- RS 数量不宜过多(通常几十台以内)。
应用场景:
小规模负载均衡,如企业内部应用;安全性要求高,需隐藏 RS 真实 IP。
2、DR模式
工作原理
- LVS 接收客户端请求后,不修改 IP 头部,而是在数据链路层修改 MAC 地址(将目标 MAC 改为 RS 的 MAC),直接转发给 RS。
- RS 处理请求后,直接将响应返回给客户端(无需经过 LVS),通过配置 VIP 别名实现。
关键特点
- 请求经过 LVS,响应直接返回客户端:LVS 仅处理入站流量,性能显著提升。
- 所有设备需在同一物理网段:依赖二层转发(如交换机),跨网段需特殊配置。
- RS 需配置 VIP 别名:但 RS 不会将 VIP 作为默认网关。
优点
- 性能高,适用于大流量场景(如电商、视频网站)。
- LVS 负载压力小,可支持更多 RS。
缺点
- 部署复杂度高(需配置 ARP 抑制)。
- 跨网段支持有限。
应用场景
高并发场景,如大型网站、API 网关;需处理大量请求的后端服务(如 MySQL 集群)。
3、TUN模式
工作原理
- LVS 接收客户端请求后,不修改原始 IP 包,而是封装一个新的 IP 头部(外层 IP 目标为 RS),通过 IP 隧道转发给 RS。
- RS 解封装后处理请求,直接将响应返回给客户端(无需经过 LVS),同样需配置 VIP 别名。
关键特点
- 请求经过 LVS,响应直接返回客户端:与 DR 模式类似,但通过 IP 隧道实现,支持跨地域部署。
- RS 需支持 IP 隧道协议(如 IPIP),并配置 VIP 别名。
- 网络拓扑灵活:RS 可分布在不同地理位置。
优点
- 支持跨地域负载均衡(如多地数据中心)。
- 性能高,LVS 仅处理入站流量。
缺点
- 隧道封装增加网络开销。
- RS 配置复杂(需支持隧道协议)。
应用场景
跨地域分布式系统(如 CDN 节点负载均衡);云服务提供商的负载均衡架构。
4、三种模式对比表格
维度 | NAT 模式 | DR 模式 | TUN 模式 |
---|---|---|---|
转发机制 | 修改 IP 地址 | 修改 MAC 地址 | IP 隧道封装 |
流量路径 | 请求和响应都经过 LVS | 请求经 LVS,响应直接回客户端 | 同 DR 模式 |
网络要求 | RS 与 LVS 需在同一网段 | 所有设备需在同一物理网段 | 支持跨地域部署 |
RS 配置 | 网关指向 LVS | 配置 VIP 别名,ARP 抑制 | 支持 IP 隧道,配置 VIP 别名 |
性能 | 较低(双向流量) | 高(单向流量) | 较高(单向流量,但有封装开销) |
典型场景 | 小规模内部应用 | 大型网站、高并发服务 | 跨地域分布式系统 |
5、Full-NAT 模式(补充)
-
工作原理:LVS 同时修改请求的源 IP(改为 LVS 的 IP)和目标 IP(改为 RS 的 IP),RS 响应时直接返回给 LVS,再由 LVS 转发给客户端。
-
特点:支持 RS 与 LVS 不在同一网段,但性能低于 DR 和 TUN 模式,适用于特殊网络环境。
综合选择:
-
小流量、简单部署:选 NAT 模式。
-
大流量、同网段:选 DR 模式(性能最优)。
-
跨地域、分布式:选 TUN 模式。
-
特殊网络环境:选 Full-NAT 模式。
二、代理和负载均衡的区别
维度 | 代理(Proxy) | 负载均衡(Load Balancer) |
---|---|---|
核心目标 | 中间转发、隔离网络、功能增强(如缓存、过滤) | 分配流量到多台服务器,提高可用性和吞吐量 |
处理对象 | 通常针对单条连接或一类请求的转发逻辑 | 针对多个后端节点的流量分配策略 |
典型场景 | 跨网络访问(如 VPN 代理)、内容过滤、缓存加速 | 分布式系统、高并发服务(如电商网站、API 集群) |
代理(Proxy):中间转发与功能增强
代理是位于客户端和目标服务器之间的中间服务器,客户端的请求先发送到代理,再由代理转发给目标服务器,响应则反向传递。其核心作用是 “代表客户端访问目标”,并可附加额外功能。
核心功能:
流量转发:跨网络(如内部网络→外部网络)或跨协议(如 HTTP→HTTPS)转发请求。
网络隔离:隐藏客户端或服务器的真实地址(如反向代理隐藏服务器 IP)。
功能增强:缓存数据、过滤内容(如广告拦截)、身份验证、加密传输等。
分类与举例:
正向代理:代理客户端,帮助客户端访问无法直接访问的资源。
举例:科学上网工具(如 Shadowsocks):客户端通过代理服务器访问外网,目标服务器只看到代理的 IP,看不到客户端真实 IP。
反向代理:代理服务器,客户端不知道目标服务器的存在,请求先到反向代理,再由其转发给后端服务器。
举例:Nginx 作为反向代理:用户访问www.example.com
时,请求先到 Nginx,Nginx 再转发给后端的 Tomcat 服务器,用户感知不到 Tomcat 的存在。Nginx 还可在此过程中缓存静态资源(如图片、CSS),减少后端压力。
负载均衡(Load Balancer):流量分配与高可用
负载均衡是将客户端的请求 “均匀分配” 到多个后端服务器的技术,避免单台服务器过载,提高系统的可用性和吞吐量。其核心作用是“分流”,确保服务稳定运行。
核心功能:
流量分配:根据策略(如轮询、权重、IP 哈希)将请求分发到不同服务器。
健康检查:监测后端服务器状态,自动剔除故障节点。
扩展性支持:通过增加服务器节点提升系统容量,无需修改客户端配置。
举例:
电商网站集群:某电商平台有 3 台服务器处理订单请求,负载均衡器(如 F5 硬件负载均衡器)接收用户的下单请求后,按 “轮询” 策略依次分配给 3 台服务器,避免单台服务器因请求过多崩溃。若其中 1 台服务器故障,负载均衡器会自动将请求转发给另外 2 台,确保服务不中断。
云服务负载均衡:AWS 的 ELB(弹性负载均衡):当用户访问一个高并发 API 时,ELB 会根据后端 EC2 实例的负载(如 CPU 使用率)动态分配请求,负载高的实例会被分配更少的流量。
区别:
目标不同:代理的核心是 “转发 + 附加功能”(如隔离、缓存);负载均衡的核心是 “分流 + 高可用”。
处理对象不同:代理可针对单台后端服务器(如反向代理仅转发到特定服务器);负载均衡必须面对多台后端服务器,目标是 “分配流量”。
依赖关系:负载均衡器通常会集成反向代理功能(如 Nginx 既可以做反向代理,也可以做负载均衡),但代理不一定具备负载均衡能力(如正向代理仅转发到单一目标)。
代理更侧重 “中间层的功能扩展”,而负载均衡更侧重 “多服务器的流量分配”,两者在复杂架构中常结合使用(如负载均衡器先接收流量,再通过反向代理转发到具体服务器)
三、MySQL B+树与跳表对比
数据结构本质
跳表:通过在链表上增加多层 “快速通道” 来加速查询。每个节点的层级由随机函数决定。
4层: 1 ----------------------------> 7
3层: 1 ---------> 3 ----------------> 7
2层: 1 ----> 2 ---> 3 ----> 5 -----> 7
1层: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 (原始链表)
B + 树:所有数据都存储在叶子节点,非叶子节点仅用于索引。
磁盘 I/O 优化
跳表:节点随机分布,导致磁盘访问分散,每次查询可能产生多次随机 I/O。
B + 树:
节点大小设计为与磁盘页(通常 4KB)对齐,一次 I/O 能读取一个完整节点。
非叶子节点不存储数据,可容纳更多索引项,减少树的高度。
例如:一个高度为 3 的 B + 树可存储约 10 亿条记录,但只需 3 次 I/O。
范围查询效率
跳表:从起始节点开始逐层下降,然后在底层链表中顺序遍历。例如查询 [3,7]:
从顶层找到3 → 下降到第1层 → 遍历3→4→5→6→7
B + 树:直接定位到左边界,通过叶子节点的链表指针顺序访问。例如:
找到3 → 通过链表指针依次访问4,5,6,7
并发性能
跳表:使用 CAS(Compare-And-Swap)操作实现无锁插入 / 删除。
例如:Redis 的有序集合在并发环境下表现优异。
B + 树:需要实现复杂的锁机制(如 InnoDB 的意向锁、行锁)。
写操作可能导致整页锁定,影响并发度。
总结
跳表是内存场景下的高效选择,尤其适合高并发、小规模数据。
B+树是磁盘存储的标准方案,通过优化磁盘 I/O 提升整体性能。
MySQL 的 InnoDB 存储引擎选择 B + 树作为索引结构,正是为了适应磁盘存储的特性。而 Memory 引擎则可能使用跳表实现内存索引。
四、什么是三次握手四次挥手?tcp为什么要三次握手?
为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误
三次握手
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包 (syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据
客户端先发送FIN,进入FIN_WAIT1状态,用来关闭Client到Server的数据传送
服务端收到FIN,发送ACK,进入CLOSE_WAIT状态,客户端收到这个ACK,进入FIN_WAIT2状态
服务端发送FIN,进入LAST_ACK状态,用来关闭Server到Client的数据传送
客户端收到FIN,发送ACK,进入TIME_WAIT状态,服务端收到ACK,进入CLOSE状态(等待2MSL时 间,约4分钟。主要是防止最后一个ACK丢失。)
四次挥手
第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不 会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的 ack确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可 以接受数据。
第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。
第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。
第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。
五、TCP和UDP的区别以及应用场景
1、概念
TCP(传输控制协议)和 UDP(用户数据报协议)是 TCP/IP 协议族中两种核心的传输层协议,它们在数据传输方式、可靠性、效率等方面存在显著差异,适用于不同的应用场景。
传输层的核心作用
- 提供进程间通信:通过端口号(如 HTTP 的 80 端口、SSH 的 22 端口)区分同一主机上的不同应用程序,实现进程间的数据传输。
- 可靠性控制:
- TCP 通过确认机制、重传机制、流量控制等保证可靠传输。
- UDP 不提供可靠性,仅尽最大努力交付数据。
- 数据分段与重组:将上层(应用层)的报文分割为适合传输的段(Segment),或在接收端将接收到的段重组为完整数据。
对比其他层
- 网络层(Network Layer):如 IP 协议,负责将数据包从源主机传输到目标主机,但不保证可靠性和顺序。
- 应用层(Application Layer):如 HTTP、SMTP、DNS 等,直接为用户应用程序提供服务。
- 链路层(Link Layer):负责物理网络的帧传输,如以太网、Wi-Fi 等。
2、核心对比
对比维度 | TCP | UDP |
---|---|---|
连接方式 | 面向连接(需三次握手建立连接,四次挥手关闭) | 无连接(直接发送数据,无需建立 / 关闭连接) |
可靠性 | 可靠传输(通过确认机制、重传机制、流量控制等保证数据不丢失、不重复、按序到达) | 不可靠传输(无确认 / 重传机制,数据可能丢失、乱序) |
数据边界 | 无(数据被视为字节流,接收方需自行划分边界) | 有(数据以数据报为单位,发送和接收的边界一致) |
拥塞控制 | 支持(通过慢启动、拥塞避免等算法调整发送速率,适应网络负载) | 不支持(发送速率不受网络状态影响,可能加剧拥塞) |
传输效率 | 较低(因连接建立、确认、重传等机制,开销大) | 较高(无额外控制机制,头部开销小,传输速度快) |
适用数据量 | 适合大量数据传输(如文件、视频流) | 适合少量数据传输(如实时指令、消息) |
3、应用场景分析
1. TCP 的典型应用场景
TCP 的可靠性使其适用于对数据准确性要求高、允许一定延迟的场景:
-
文件传输:如 FTP(文件传输协议)、HTTP/HTTPS(网页传输)。文件传输需保证数据完整,不能丢失或损坏,TCP 的重传机制可确保这一点。
-
邮件发送:如 SMTP(简单邮件传输协议)。邮件内容的完整性和顺序至关重要,TCP 能避免邮件内容错乱或丢失。
-
远程登录:如 SSH(安全外壳协议)、Telnet。远程操作指令需要准确执行,TCP 的按序传输可保证指令顺序正确。
-
数据库交互:如 MySQL 的 TCP 连接。数据库查询和修改需确保数据一致性,TCP 的可靠性可防止数据同步错误。
2. UDP 的典型应用场景
UDP 的高效性使其适用于对实时性要求高、可容忍少量数据丢失的场景:
-
实时通信:如视频通话(Skype)、语音通话(VoIP)。实时传输中,延迟比偶尔的数据包丢失更影响体验,UDP 的低延迟特性更适合。
-
流媒体播放:如直播(RTSP/RTP 协议常用 UDP)。直播中,丢失个别帧不会影响整体观看,但若用 TCP 可能因重传导致画面卡顿。
-
游戏数据传输:如多人在线游戏的实时位置、操作指令。游戏需要低延迟响应,少量数据包丢失可通过本地预测补偿,而 TCP 的重传可能导致操作延迟。
-
物联网通信:如传感器数据上报(CoAP 协议)。传感器数据通常周期性发送,少量丢失不影响整体分析,UDP 的低开销更适合资源有限的设备。
-
DNS 查询:域名解析(DNS 协议)通常用 UDP。查询数据量小,且即使丢失可快速重发,UDP 的高效性能缩短解析时间。
4、总结
- TCP是 “可靠但低效” 的协议,适合需要保证数据完整性的场景,如文件传输、邮件、数据库交互等。
- UDP是 “高效但不可靠” 的协议,适合需要低延迟、可容忍少量丢失的场景,如实时音视频、游戏、物联网等。
六、用户输入网址到响应界面操作中间发生了什么?
1、DNS 解析:将域名转换为 IP 地址
-
浏览器缓存检查:浏览器首先检查本地缓存中是否有该域名对应的 IP 地址(缓存时间由 DNS 记录的 TTL 值控制)。
-
系统缓存检查:若浏览器缓存未命中,则检查操作系统的 hosts 文件或本地 DNS 缓存(如 Windows 的 DNS Client 服务)。
-
本地 DNS 服务器查询:若仍未命中,请求本地 DNS 服务器(通常由 ISP 提供)。本地 DNS 服务器会先检查自身缓存,若没有则进行递归查询。
-
递归查询流程:
-
根 DNS 服务器(.com、.cn 等顶级域名服务器的地址)。
-
顶级域 DNS 服务器(如.com 域名服务器)。
-
权威 DNS 服务器(如example.com的具体 DNS 服务器)。
-
-
获取 IP 地址:最终从权威 DNS 服务器获取目标网站的 IP 地址,并逐级返回给浏览器。
2、TCP 连接:建立与服务器的可靠通信
-
TCP 三次握手:
-
客户端发送 SYN 包,请求建立连接,并携带初始序列号(ISN)。
-
服务器返回 SYN+ACK 包,确认请求并发送自己的初始序列号。
-
客户端发送 ACK 包,完成连接建立。
-
-
TCP 参数协商:双方协商 MSS(最大段大小)、窗口大小等参数,优化数据传输。
3、HTTP 请求:发送网页资源请求
-
构建 HTTP 请求报文:包含请求行(如 GET /index.html HTTP/1.1)、请求头(如 User-Agent、Cookie 等)和请求体(如 POST 请求的数据)。
-
HTTPS 额外步骤(若启用):
-
TLS 握手:协商加密算法、验证服务器证书、生成会话密钥。
-
数据加密:后续 HTTP 数据通过对称加密传输。
-
4、服务器处理请求
-
负载均衡(若存在):请求先到达负载均衡器(如 Nginx、AWS ELB),被转发到合适的后端服务器。
-
Web 服务器接收请求:如 Apache、Nginx 处理 HTTP 请求,解析请求头和 URL。
-
应用服务器处理:
-
静态资源:直接返回文件(如 HTML、CSS、JS)。
-
动态资源:调用应用程序(如 PHP、Python、Java)生成响应。
-
-
数据库交互(若需要):应用程序查询数据库获取数据(如用户信息、文章内容)。
-
生成 HTTP 响应:包含状态码(如 200 OK、404 Not Found)、响应头(如 Content-Type、Cache-Control)和响应体(网页内容)。
5、HTTP 响应:返回数据到客户端
-
服务器发送响应:将 HTTP 响应通过 TCP 连接返回给客户端。
-
客户端接收响应:
-
解析响应头:获取内容类型、缓存策略等信息。
-
处理压缩数据:若内容被压缩(如 gzip),先解压。
-
6、浏览器解析渲染页面
-
解析 HTML:构建 DOM 树(文档对象模型)。
-
资源加载:
-
解析 HTML 中的资源引用(如 CSS、JS、图片)。
-
并行请求这些资源(HTTP/1.1 通过多个 TCP 连接,HTTP/2 通过多路复用)。
-
-
构建 CSSOM:解析 CSS 文件,构建 CSS 对象模型。
-
合并渲染树:将 DOM 树和 CSSOM 合并为渲染树(只包含可见元素)。
-
布局(Layout):计算每个元素在屏幕上的位置和大小。
-
绘制(Painting):将渲染树转换为屏幕上的像素。
-
合成(Compositing):处理层叠和动画,优化渲染性能。
7、TCP 连接关闭(可选)
-
四次挥手:
-
客户端发送 FIN 包,表示请求关闭发送方向。
-
服务器返回 ACK 包,确认关闭请求。
-
服务器发送 FIN 包,表示请求关闭接收方向。
-
客户端返回 ACK 包,确认关闭请求。
-
-
连接复用:HTTP/1.1 默认使用持久连接(Connection: keep-alive),多个请求可复用同一个 TCP 连接;HTTP/2 进一步优化了连接复用效率。
概括总结如下:
- DNS 解析:浏览器将域名(如www.example.com)转换为服务器 IP 地址(如 192.168.1.1)。
- 建立连接:通过 TCP 三次握手与服务器建立连接(若为 HTTPS,还需额外完成 TLS 加密握手)。
- 发送请求:浏览器向服务器发送 HTTP 请求(如获取首页内容)。
- 服务器响应:服务器处理请求后,返回 HTTP 响应(包含网页 HTML、CSS、JS 等数据)。
- 渲染页面:浏览器解析响应内容,构建 DOM 树和样式,最终渲染出可视化页面。
- 关闭连接:完成后通过 TCP 四次挥手关闭连接(或复用连接处理后续请求)。
七、redis的缓存穿透、缓存击穿、缓存雪崩
1、什么是redis
redis是一个单线程的支持网络、可基于内存也可持久化的日志型、K-V数据库,并提供多种语言的API。支持多种的数据类型:string hash 列表、集合等,支持事务读写速度非常快
2、缓存穿透
2.1描述:
用户想要查询某个数据,在 Redis 中查询不到,即没有缓存命中,这时就会直接访问数据库进行查询。当请求量超出数据库最大承载量时,就会导致数据库崩溃。这种情况一般发生在非 正常 URL 访问,目的不是为了获取数据,而是进行恶意攻击。
2.2现象:
1、应用服务器压力变大
2、Redis缓存命中率降低
3、一直查询数据库
2.3原因:
一个不存在缓存及查询不到的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果 从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查 询,失去了缓存的意义。
2.4解决方法:
① 对空值缓存:如果一个查询数据为空(不管数据是否存在),都对该空结果进行缓存,其 过期时间会设置非常短。
② 设置可以访问名单:使用bitmaps类型定义一个可以访问名单,名单id作为bitmaps的偏移量,每次访问时与bitmaps中的id进行比较,如果访问id不在bitmaps中,则进行拦截,不允 许访问。
③ 采用布隆过滤器:布隆过滤器可以判断元素是否存在集合中,他的优点是空间效率和查询 时间都比一般算法快,缺点是有一定的误识别率和删除困难。
④ 进行实时监控:当发现 Redis 缓存命中率急速下降时,迅速排查访问对象和访问数据,将其设置为黑名单。
3、缓存击穿
3.1描述
key中对应数据存在,当key中对应的数据在缓存中过期,而此时又有大量请求访问该数据, 由于缓存中过期了,请求会直接访问数据库并回设到缓存中,高并发访问数据库会导致数据库崩溃。
3.2现象
1、数据库访问压力瞬时增加
2、Redis中没有出现大量 Key 过期
3、Redis正常运行
4、数据库崩溃
3.3原因:
由于 Redis 中某个 Key 过期,而正好有大量访问使用这个 Key,此时缓存无法命中,因此就会直接访问数据层,导致数据库崩溃。 最常见的就是非常“热点”的数据访问。
3.4解决方法
① 预先设置热门数据:在redis高峰访问时期,提前设置热门数据到缓存中,或适当延长缓存 中key过期时间。
② 实时调整:实时监控哪些数据热门,实时调整key过期时间。
③ 对于热点key设置永不过期。
4、缓存雪崩
4.1描述
key中对应数据存在,在某一时刻,缓存中大量key过期,而此时大量高并发请求访问,会直 接访问后端数据库,导致数据库崩溃。
4.2现象
数据库压力变大导致数据库和 Redis 服务崩溃
4.3原因
短时间内大量的key过期,恰好大量的访问使用这些过期的key,此时缓存无法命中,导致大量的请求直接打到数据库中,导致宕机。
4.4解决方法
① 构建多级缓存机制:nginx缓存 + redis缓存 + 其他缓存。
② 设置过期标志更新缓存:记录缓存数据是否过期,如果过期会触发另外一个线程去在后台 更新实时key的缓存。
③ 将缓存可以时间分散:如在原有缓存时间基础上增加一个随机值,这个值可以在1-5分钟随 机,这样过期时间重复率就会降低,防止大量key同时过期。
④ 使用锁或队列机制:使用锁或队列保证不会有大量线程一次性对数据库进行读写,从而避 免大量并发请求访问数据库,该方法不适用于高并发情况。