Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Web服务器-Nginx负载均衡

Web服务器-Nginx负载均衡

作者头像
运维小路
发布于 2025-04-07 01:44:33
发布于 2025-04-07 01:44:33
25500
代码可运行
举报
文章被收录于专栏:运维小路运维小路
运行总次数:0
代码可运行

作者介绍:简历上没有一个精通的运维工程师,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

我们上一大章介绍了Kubernetes的知识,本章节我们进入中间件的讲解,这里会包含很多不同的类型组件,中间件的第一个大类我这里定义的是Web服务器。由于目前使用最广泛的Web服务器是Nginx,所以我们这里的讲解主要以Nginx服务器为主。

上2个小节,我们介绍了Nginx的核心功能反向代理。但是他的一个规则只能对应一个后端,如果后端有多个同样服务跑在多个服务器上,我们Nginx这里应该如何来配置,让他支持多个后端,并实现负载均衡功能呢?

负载均衡实现

我们这里用一台后端服务器启动2个同样的服务,采用不同的端口来代替2台服务器,然后前端使用Nginx来代理这2个服务。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
server {
    listen 80;
    server_name 192.168.31.120;
    location / {
        proxy_pass http://backend_servers; 
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
upstream backend_servers {
    server 192.168.31.121:8080;
    server 192.168.31.121:9090;
}

这里我们把代理的后端地址从一个具体的地址换成了我们定义的一个名字,然后在server同级的upstream模块里面定义后端的地址,这里只定义2个,实际可多个。默认情况下他他会把请求轮流转发到后端的2个服务。

负载均衡算法

如果不做任何配置的情况下就是轮询(轮流),依次向后端配置的服务转发请求。当然除了默认的轮询还有多种算法。

1. 加权轮询 (Weighted Round Robin)

  • 说明:按权重分配请求,权重越高分配越多。
  • 适用场景:服务器性能不均(如 CPU/内存差异)。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
upstream backend {
    server 192.168.1.101 weight=5;  # 50% 流量
    server 192.168.1.102 weight=3;  # 30% 流量
    server 192.168.1.103 weight=2;  # 20% 流量
}

2. 最少连接数 (Least Connections)

  • 说明:优先将请求分配给当前连接数最少的服务器。
  • 适用场景:长连接服务(如 WebSocket、数据库连接池)。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
upstream backend {
    least_conn;
    server 192.168.1.101;
    server 192.168.1.102;
}

3. IP 哈希 (IP Hash)

  • 说明:基于客户端 IP 计算哈希值固定分配到某台服务器。
  • 适用场景:需要会话保持的应用(如购物车、登录状态)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
upstream backend {
    ip_hash;
    server 192.168.1.101;
    server 192.168.1.102;
}

4. URI 哈希 (URI Hash) - 需第三方模块

  • 说明:根据请求 URI 分配流量,相同 URI 始终到同一服务器。
  • 适用场景:缓存优化(如 CDN 边缘节点)。
  • 配置(需编译安装 ngx_http_upstream_hash_module):
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
upstream backend {
    hash $request_uri consistent;  # consistent 表示一致性哈希
    server 192.168.1.101;
    server 192.168.1.102;
}

健康检查逻辑

前面我们介绍他通过多种负载均衡算法转发到后端,但是后端的服务也可能出现异常,如果后端服务异常以后,Nginx还会把流量转发过去吗?默认我们只要配置负载均衡,他就会自动给我们添加健康检查,剔除不健康的节点。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#默认值
max_fails  1
fail_timeout=10s
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
upstream backend {
    server 192.168.1.101:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.102:8080 max_fails=3 fail_timeout=30s;
}

正常状态

两个后端服务器 101102 均处于健康状态。Nginx 使用默认的轮询策略分发请求到这两个服务器。每个请求会交替发送到101 和 102所有请求均返回

2xx3xx 等正常状态码。失败计数器(max_fails)保持为 0

故障状态

假设 192.168.1.101 发生故障,触发条件:当请求发送到 101 时,Nginx 检测到以下情况之一:连接超时(如 TCP 握手失败)。服务器返回 5xx 错误码(如 500、502)。主动拒绝连接(如服务崩溃)。

计数器递增

每次失败(如超时或错误响应),101 的失败计数器 +1。关键规则:计数器仅在 fail_timeout=30s 时间窗口内累计。(例如:30 秒内连续失败 3 次,或 30 秒内累计失败 3 次)。

标记为不可用

如果 30秒 内累计失败达到 3次,Nginx 将 101 标记为 unavailable。标记后,Nginx 停止 向 101 发送新请求,持续 30秒(fail_timeout 的第二个作用)。

流量切换

所有请求会被转发到剩余的健康节点 102。用户可能观察到部分请求失败,但服务整体仍可用(因 102 仍正常)。

故障恢复阶段

30秒后:Nginx 尝试恢复 101自动探测:当 fail_timeout=30s 超时后,Nginx 会重新将 101 加入负载均衡池。隐式检查:Nginx 不会主动发送健康检查请求,而是在下一个客户端请求触发时尝试 101。恢复逻辑:下一个请求到达时,Nginx 会尝试将请求发送到 101。如果请求成功:101 的失败计数器 重置为 0。101 重新成为健康节点,参与后续的负载均衡。

如果请求再次失败

失败计数器 +1,重新进入故障判断流程。若在 30秒 内再次累计 3次 失败,101 会再次被标记为不可用 30秒。

以上流程是我以前的理解,但是经过我测试发现目前的版本(v1.20.1), 如果把其中一个服务关闭,则请求转发会失败,但是他会把请求重新转发到另外一个正常的节点,这样前端请求就感知不到后端异常。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
==> access.log <==
192.168.31.120 - - [03/Apr/2025:22:30:02 +0800] "GET / HTTP/1.1" 200 42 "-" "curl/7.29.0" "-"
192.168.31.120 - - [03/Apr/2025:22:30:04 +0800] "GET / HTTP/1.1" 200 42 "-" "curl/7.29.0" "-"
==> error.log <==
2025/04/03 22:30:06 [error] 2809#2809: *1005 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.31.120, server: 192.168.31.120, request: "GET / HTTP/1.1", upstream: "http://192.168.31.121:9090/", host: "192.168.31.120"
==> access.log <==
192.168.31.120 - - [03/Apr/2025:22:30:06 +0800] "GET / HTTP/1.1" 200 42 "-" "curl/7.29.0" "-"
192.168.31.120 - - [03/Apr/2025:22:30:08 +0800] "GET / HTTP/1.1" 200 42 "-" "curl/7.29.0" "-"

正常请求是每2秒,然后轮流转发给后端2台服务器,但是我们看到06秒的时候失败,然后06秒还有一次成功的记录(这次请求是重新转发刚刚失败的请求),这样前面的请求就感知不到后端失败。

如果你想要浮现上面的逻辑,可以显示添加参数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
location / {
  proxy_pass http://backend_servers;
  proxy_next_upstream error timeout;  # 禁用重试
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-04-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维小路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MySQL8 窗口函数
MySQL8 还是有很多重量级变化的,一些底层优化大家在使用中有时候不易察觉,但是有一些用法,还是带给我们耳目一新的感觉,今天松哥和大家分享一下 MySQL8 里边的窗口函数。
程序猿川子
2024/11/08
1830
MySQL8 窗口函数
最强总结!数据库开窗函数完全指南!!
开窗函数(Window Functions)是SQL中强大的分析工具,允许我们在不改变结果集行数的情况下进行复杂的聚合和分析操作。本文将系统地介绍开窗函数的用法和实际应用场景。
SQL数据库开发
2024/11/12
5480
最强总结!数据库开窗函数完全指南!!
Hive常用窗口函数实战
本文介绍了Hive常见的序列函数,排名函数和窗口函数。结合业务场景展示了Hive分析函数的使用
Eights
2020/07/13
2.8K0
大数据学习之数据仓库代码题总结上
请编写 SQL 查询,计算从注册当天开始的每个用户在注册后第1天、第3天、第7天的学习留存率。留存率的计算方式是在注册后的特定天数内继续学习的用户数除以当天注册的用户总数。结果应包含日期、留存天数和留存率。
bxia的厨房_公众号
2024/03/05
2481
大数据学习之数据仓库代码题总结上
这些SQL排名及分析函数,你知道吗?(5)
SQL的排名函数主要有ROW_NUMBER(), RANK(), 和 DENSE_RANK(),它们分别返回行号、排名和紧密排名。这三个函数的区别在于处理并列排名的方式。
万能数据的小草
2024/07/23
2590
这些SQL排名及分析函数,你知道吗?(5)
SQL 窗口函数的优化和执行
窗口函数(Window Function)是 SQL2003 标准中定义的一项新特性,并在 SQL2011、SQL2016 中又加以完善,添加了若干处拓展。窗口函数不同于我们熟悉的普通函数和聚合函数,它为每行数据进行一次计算:输入多行(一个窗口)、返回一个值。在报表等分析型查询中,窗口函数能优雅地表达某些需求,发挥不可替代的作用。
SQL数据库开发
2024/04/24
2200
SQL 窗口函数的优化和执行
SQL 窗口函数的优化和执行
窗口函数(Window Function)是 SQL2003 标准中定义的一项新特性,并在 SQL2011、SQL2016 中又加以完善,添加了若干处拓展。窗口函数不同于我们熟悉的普通函数和聚合函数,它为每行数据进行一次计算:输入多行(一个窗口)、返回一个值。在报表等分析型查询中,窗口函数能优雅地表达某些需求,发挥不可替代的作用。
大数据老哥
2021/03/08
1.9K0
SQL 窗口函数的优化和执行
Oracle分析函数
和聚合函数相似,但是对于每一组记录,无论多少行,聚合函数只返回一行值,而分析函数对其中每一行记录都返回值
HUC思梦
2020/09/03
1.1K0
Oracle分析函数
mysql中分组排序_oracle先分组后排序
​ 窗口函数(window functions),也被称为 “开窗函数”,也叫OLAP函数(Online Anallytical Processing,联机分析处理),可对数据库数据进行实时分析处理。它是数据库的标准功能之一,主流的数据库比如Oracle,PostgreSQL都支持窗口函数功能,MySQL 直到 8.0 版本才开始支持窗口函数。
全栈程序员站长
2022/11/10
8K0
数据库:SQL 窗口函数知识介绍
窗口函数(Window Function) 是 SQL2003 标准中定义的一项新特性,并在 SQL2011、SQL2016 中又加以完善,添加了若干处拓展。窗口函数不同于我们熟悉的普通函数和聚合函数,它为每行数据进行一次计算:输入多行(一个窗口)、返回一个值。在报表等分析型查询中,窗口函数能优雅地表达某些需求,发挥不可替代的作用。
小明互联网技术分享社区
2021/05/14
7540
数据库:SQL 窗口函数知识介绍
MySQL8新特性窗口函数详解
MySQL8 窗口函数是一种特殊的函数,它可以在一组查询行上执行类似于聚合的操作,但是不会将查询行折叠为单个输出行,而是为每个查询行生成一个结果。窗口函数可以用来处理复杂的报表统计分析场景,例如计算移动平均值、累计和、排名等。其中博主认为它展现的主要威力在于「它能够让我们在不修改原有语句输出结果的基础上,直接添加新的聚合字段」。
wayn
2023/08/28
3010
MySQL8新特性窗口函数详解
DM达梦数据库分析函数整理
在复杂的数据分析场景中,达梦数据库的分析函数扮演着至关重要的角色。它们允许用户在单个查询中对数据进行分组、排序、排名及聚合计算,极大地提升了数据分析的灵活性和效率。本篇将深入探讨达梦数据库中几种关键的分析函数,并通过具体案例SQL来解析其用法,帮助你更好地掌握这些强大的工具。
用户11147438
2024/07/02
1K0
MySQL8新特性窗口函数详解
本文博主给大家详细讲解一波 MySQL8 的新特性:「窗口函数」,相信大伙看完一定能有所收获。
wayn
2023/06/14
4760
MySQL8新特性窗口函数详解
【数据库设计和SQL基础语法】--查询数据--聚合函数
聚合函数是一类在数据库中用于对多个行进行计算并返回单个结果的函数。它们能够对数据进行汇总、统计和计算,常用于提取有关数据集的摘要信息。聚合函数在 SQL 查询中广泛应用,包括统计总数、平均值、最大值、最小值等。
喵叔
2023/12/18
8850
分析函数之窗口子句(r4笔记第3天)
关于分析函数,可能大家基本都是从row_number()开始了解到的。分析函数的使用在某种程度上可以避免自连接,使得原本较为繁琐复杂的查询一下子变得精简起来。 分析函数分为分区子句,排序子句,和窗口子句,对于窗口子句来说,可能开始比较难懂,这部分的使用也尤为重要。 还是先举个例子,然后基于例子再来简单分析一下分析函数。 我们创建一个测试表sales_fact create table sales_fact( product varchar2(200) not null, country varchar2
jeanron100
2018/03/15
5610
Hive补充之窗口函数
窗口函数 1、hive窗口函数语法 hive中的窗口函数over() ,over()窗口函数的语法结构
Maynor
2021/04/09
1.1K0
SQL干货 | 窗口函数的使用
Mysql从8.0版本开始,也和Sql Server、Oracle一样支持在查询中使用窗口函数,本文将根据官方文档,通过实例介绍窗口函数并举例分组排序函数的使用。
Python数据科学
2019/12/31
1.5K0
SQL干货 | 窗口函数的使用
MySQL 窗口函数详解:分析性查询的强大工具
MySQL 窗口函数提供了一种灵活的方式来处理 SQL 查询中的数据,它们允许你在不需要对数据进行分组的情况下对行集进行分析。窗口函数最常用于分析性操作,比如计算排名、累计和、移动平均值等。MySQL 从版本 8.0 开始支持窗口函数。以下是窗口函数的几个关键概念和常见用法:
科技新语
2024/12/17
1620
MySQL 窗口函数详解:分析性查询的强大工具
Hive 窗口函数最全讲解和实战
在深入研究Over字句之前,一定要注意:在SQL处理中,窗口函数都是最后一步执行,而且仅位于Order by子句之前 可以想象成sql的输出结果,就是窗口函数输入的结果。
kk大数据
2019/12/18
2.1K0
postgreSQL窗口函数总结
1、我们都知道在SQL中有一类函数叫做聚合函数,例如sum()、avg()、max()等等,这类函数可以将多行数据按照规则聚集为一行,一般来讲聚集后的行数是要少于聚集前的行数的,但是有时我们想要既显示聚集前的数据,又要显示聚集后的数据,这时我们便引入了窗口函数。
小徐
2020/02/16
2.8K0
postgreSQL窗口函数总结
相关推荐
MySQL8 窗口函数
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验