当前位置: 首页 > news >正文

Nginx 负载均衡实现上游服务健康检查

Nginx 负载均衡实现上游服务健康检查

NGINX_resized

Author:Arsen
Date:2024/06/20


目录

  • Nginx 负载均衡实现上游服务健康检查
    • 前言
    • 一、Nginx 部署并新增模块
    • 二、健康检查配置
      • 2.1 准备 nodeJS 应用程序
      • 2.2 Nginx 配置负载均衡健康检查
    • 小结


前言

如果你使用云负载均衡(如阿里云 CLB),我们可以通过配置健康检查来实现后端服务故障转移(通过 4/7 层实现)。而如果你使用 Nginx 作为负载均衡器时,又如何实现后端(上游)服务器的健康检查呢?要解决这个问题,就需要使用到 Nginx 的 nginx_upstream_check_module 模块,因为在不使用 nginx_upstream_check_module 模块的情况下,Nginx 的常规负载均衡机制并不具备自动移除不健康服务器的功能。默认情况下,Nginx 不会主动检查上游服务器的健康状态,因此无法在服务器出现故障时自动将其从负载均衡池中移除。

接下来将演示如何通过 nginx_upstream_check_module 实现负载均衡上游服务器的故障转移。

注意:nginx_upstream_check_module 是一个第三方模块,不属于官方 NGINX 发行版的一部分,因此需要我们手动将其集成到 NGINX 中,而不是通过官方预编译的 NGINX 包来使用它。

一、Nginx 部署并新增模块

1、下载 nginx、nginx_upstream_check_module 源码包

nginx_upstream_check_module 模块地址:https://github.com/yaoweibin/nginx_upstream_check_module

image-20240620104245743

wget http://nginx.org/download/nginx-1.18.0.tar.gz
wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/refs/tags/v0.4.0.tar.gz

2、解压安装包

tar xzf v0.4.0.tar.gz
tar xzf nginx-1.18.0.tar.gz

image-20240620104806192

3、为 NGINX 源码打补丁

# 安装补丁工具
yum install -y patch

补丁列表(在我们上面下载的第三方模块中):

image-20240620105257476

在补丁文件列表中,没有直接与 nginx-1.18.4 对应的补丁文件。通常情况下,选择一个版本号最接近但不高于你的 NGINX 版本的补丁文件会是最佳选择。如上图,使用 check_1.16.1+.patch,因为它是最接近 1.18.0 的可用补丁且不高于1.18.0

# 开始打补丁
cd nginx-1.18.0/
patch -p1 < ../nginx_upstream_check_module-0.4.0/check_1.16.1+.patch

image-20240620110232269

4、开始编译安装

关于模块安装注意事项,可以查看有道云笔记 nginx 编译安装部分。

# 安装nginx编译安装的依赖环境yum -y install make gcc gcc-c++ pcre pcre-devel gd-devel openssl openssl-devel zlib zlib-devel
./configure \
--with-http_gzip_static_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-pcre \
--with-file-aio \
--with-http_realip_module \
--without-http_scgi_module \
--without-http_uwsgi_module \
--without-http_fastcgi_module \
--with-compat --add-module=../nginx_upstream_check_module-0.4.0# --with-compat 是一个用于构建兼容模块的选项,它允许你编译 NGINX 时,使其模块在不同版本的 NGINX 上保持兼容。
# 这里仅仅是测试使用,我就不具体规划路径了(如安装路径、日志路径等),使用默认即可

image-20240620112148670

如上图,Nginx 编译完成,默认输出了相关的工作路径,接下来就根据上图路径开始安装了:

make && make install

image-20240620112620821

此时我们需要验证新增的第三方模块是否被成功集成:

image-20240620114128136

二、健康检查配置

2.1 准备 nodeJS 应用程序

1、node 安装

过程略.

image-20240620123738935

image-20240620123804989

2、安装 pm2 守护进程管理器

npm install -g pm2

3、创建测试项目并启动项目

vim /data/nginx-test-projects/node-js-demo/app-1.js

const http = require('http');const server = http.createServer((req, res) => {res.setHeader("Content-Type", "application/json");res.writeHead(200);res.end(`{ "status": "success", "message": "app-1 请求成功!\n" }`);
});server.listen(3001, 'localhost', () => {console.log('running on http://localhost:3001/');
});

vim /data/nginx-test-projects/node-js-demo/app-2.js

const http = require('http');const server = http.createServer((req, res) => {res.setHeader("Content-Type", "application/json");res.writeHead(200);res.end(`{ "status": "success", "message": "app-2 请求成功!\n" }`);
});server.listen(3002, 'localhost', () => {console.log('running on http://localhost:3002/');
});

vim /data/nginx-test-projects/node-js-demo/app-3.js

const http = require('http');const server = http.createServer((req, res) => {res.setHeader("Content-Type", "application/json");res.writeHead(200);res.end(`{ "status": "success", "message": "app-3 请求成功!\n" }`);
});server.listen(3003, 'localhost', () => {console.log('running on http://localhost:3003/');
});

启动应用:

pm2 start /data/nginx-test-projects/node-js-demo/app-1.js
pm2 start /data/nginx-test-projects/node-js-demo/app-2.js
pm2 start /data/nginx-test-projects/node-js-demo/app-3.js

image-20240620130518251

2.2 Nginx 配置负载均衡健康检查

1、nginx 配置

vim /usr/local/nginx/conf/nginx.conf
http {upstream backend {server 127.0.0.1:8080;server 127.0.0.1:8081;check interval=3000 rise=2 fall=5 timeout=1000 type=http;check_http_send "HEAD / HTTP/1.0\r\n\r\n";check_http_expect_alive http_2xx http_3xx;}server {listen 80;location / {proxy_pass http://backend;}}
}

配置说明:

  • upstream backend { ... }: 定义名为 backend 的上游服务器组。

  • server 127.0.0.1:8080;: 定义一个地址为 127.0.0.1:8080 的上游服务器。

  • check interval=3000 rise=2 fall=5 timeout=1000 type=http;
    配置健康检查参数:
    • interval=3000: 每隔 3000 毫秒(3 秒)进行一次健康检查。
    • rise=2: 如果服务器连续通过 2 次健康检查,则认为它是健康的。
    • fall=5: 如果服务器连续 5 次健康检查失败,则认为它是故障的。
    • timeout=1000: 每次健康检查必须在 1000 毫秒(1 秒)内完成。
    • type=http: 指定进行 HTTP 健康检查。
  • check_http_send "HEAD / HTTP/1.0\r\n\r\n";: 向服务器发送 HTTP HEAD 请求。

  • check_http_expect_alive http_2xx http_3xx;: 如果服务器返回的状态码在 2xx 或 3xx 范围内,则认为服务器是健康的。

2、健康检查验证

while sleep 0.5; do curl http://192.168.56.120; done

后端服务健康情况时,是正常的负载均衡的:

image-20240620131633437

这里我分两种情况来验证:

1)未配置 nginx_upstream_check_module 的情况

此时,我停掉 app-1

pm2 stop app-1

image-20240620132738027

看看 nginx 的错误日志是否持续输出,如果持续输出,说明 nginx 一直在轮询请求后端上游服务,且请求不到,这就证明默认的 nginx 负载均衡模式下,并不能实现后端上游服务的健康检查,客户的请求依然会打到坏掉的 app-1 服务上。如下图,正符合我们的假设。

image-20240620132315052

2)配置了 nginx_upstream_check_module 的情况

这里,我们先恢复后端服务,使 3 台都正常工作。然后我们保持请求不要断,继续将 app-1 stop 掉,看会不会故障转移到其他节点:判断是否转移其实就是你看 nginx 是否有如上图相同的错误日志持续输出,如果有,那证明这个检测模块我们就没配置正确,否则证明我们的检测模块生效,且将坏掉的 app-1 从负载均衡中摘掉,恢复时自动加入负载均衡。

停掉 app-1

pm2 stop app-1

再看看 Nginx 的错误日志:

image-20240620135539019

这里你会注意到,此时的错误日志与上一张图的错误日志不同了,那他们的区别是什么呢?

1)未配置 nginx_upstream_check_module 的错误日志分析:

由于我们没有配置了 Nginx 健康检查,在连接已建立后,NGINX 尝试连接到上游服务器时,连接被拒绝而抛出如下错误日志:

2024/06/20 13:19:55 [error] 14553#0: *510 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.56.120, server: localhost, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:3001/", host: "192.168.56.120"

这通常是由于上游服务器未能正常启动或者未响应

客户端请求处理:

  • 如果 NGINX 配置中没有健康检查,或者健康检查无法检测到上游服务器的问题,客户端的请求可能会继续被发送到无法处理请求的上游服务器。
  • 这种情况下,客户端请求可能会因为上游服务器的问题而遭遇连接失败或者长时间的等待响应。

2)配置了 nginx_upstream_check_module 的错误日志分析:

由于我们配置了 Nginx 健康检查,在连接已建立后,NGINX 尝试发送数据到上游服务器时,连接被拒绝而抛出如下错误日志:

2024/06/20 13:35:06 [error] 15030#0: send() failed (111: Connection refused)
2024/06/20 13:35:09 [error] 15030#0: send() failed (111: Connection refused)
2024/06/20 13:35:12 [error] 15030#0: send() failed (111: Connection refused)
2024/06/20 13:35:15 [error] 15030#0: send() failed (111: Connection refused)

在连接建立后,即使上游服务器通过了健康检查确认为健康状态,但在实际发送数据时,服务器可能由于负载过高、连接限制或其他原因拒绝处理请求。

客户端请求处理:

  • 配置了健康检查后,NGINX 会在发送实际请求之前先检查上游服务器的健康状态。
  • 如果上游服务器在健康检查时被标记为不可用,NGINX 将不会将客户端的请求发送到该上游服务器。
  • 这种情况下,客户端的请求不会被打到处于故障状态的上游服务器,因为 NGINX 在发送请求之前会先确认上游服务器的可用性。

小结

1、nginx 未设置健康检查报错

这类报错是在连接建立阶段出现连接被拒绝的错误,通常因为上游服务器未能正常启动或者未响应。

2、nginx 设置了健康检查报错

康状态,但在实际发送数据时,服务器可能由于负载过高、连接限制或其他原因拒绝处理请求。

3、健康检查的目的

实现高可用。

—END

相关文章:

Nginx 负载均衡实现上游服务健康检查

Nginx 负载均衡实现上游服务健康检查 Author&#xff1a;Arsen Date&#xff1a;2024/06/20 目录 Nginx 负载均衡实现上游服务健康检查 前言一、Nginx 部署并新增模块二、健康检查配置2.1 准备 nodeJS 应用程序2.2 Nginx 配置负载均衡健康检查 小结 前言 如果你使用云负载均衡…...

小程序使用接口wx.getLocation配置

开通时需详细描述业务&#xff0c;否则可能审核不通过 可能需要绑定腾讯位置服务&#xff0c;新建应该&#xff0c;绑定到小程序 配置 权限声明&#xff1a;在使用wx.getLocation前&#xff0c;需要在app.json的permission字段中声明对用户位置信息的使用权限&#xff0c;并提…...

Protobuf安装配置--附带每一步截图

Protobuf Protobuf&#xff08;Protocol Buffers&#xff09;协议是一种由 Google 开发的二进制序列化格式和相关的技术&#xff0c;它用于高效地序列化和反序列化结构化数据&#xff0c;通常用于网络通信、数据存储等场景。 为什么要使用Protobuf Protobuf 在许多领域都得到…...

力扣1019.链表中的下一个更大节点

力扣1019.链表中的下一个更大节点 从左到右 每个数确定下一个更大节点后 弹出栈中存下标 即res.size() class Solution {public:vector<int> nextLargerNodes(ListNode* head) {vector<int> res;stack<int> st;for(auto ihead;i;ii->next){while(!st.e…...

查询mysql库表的几个语句

1、查询某个数据库的所有表 SELECTtable_name FROMinformation_schema.TABLES WHEREtable_schema database_namedatabase_name替换成你需要查询的数据库名称 2、查询某张表的所有字段名称 SELECTCOLUMN_NAME,column_comment FROMinformation_schema.COLUMNS WHEREtable…...

【CT】LeetCode手撕—103. 二叉树的锯齿形层序遍历

目录 题目1- 思路2- 实现⭐103. 二叉树的锯齿形层序遍历——题解思路 2- ACM实现 题目 原题连接&#xff1a;103. 二叉树的锯齿形层序遍历 1- 思路 二叉树的层序遍历&#xff0c;遇到奇数时&#xff0c;利用 Collections.reverse() 翻转即可 2- 实现 ⭐103. 二叉树的锯齿形层…...

1958springboot VUE宿舍管理系统开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot VUE宿舍管理系统是一套完善的完整信息管理类型系统&#xff0c;结合springboot框架和VUE完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09; &#xff0c;系统具有完整的源代码和数…...

LVS DR模式

Linux Virtual Server&#xff08;LVS&#xff09;是一个由Linux内核支持的负载均衡解决方案&#xff0c;旨在通过集群技术来提高服务器的可扩展性、可靠性和高可用性。LVS通过将客户端的请求分发到多个服务器上&#xff0c;从而实现负载均衡和容错。 目录 LVS的工作模式 DR模…...

myslql事务示例

在 MySQL 中&#xff0c;事务&#xff08;Transaction&#xff09;是一组要么全部执行&#xff0c;要么全部不执行的SQL语句。这可以确保数据的一致性和完整性。事务管理的核心包括四个属性&#xff0c;即原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consiste…...

解决Flutter应用程序的兼容性问题

哈喽呀&#xff0c;大家好呀&#xff0c;淼淼又来和大家见面啦&#xff0c;Flutter作为一个跨平台的移动应用开发框架&#xff0c;极大地简化了开发者同时在Android和iOS平台上构建应用的难度。然而&#xff0c;由于不同设备、操作系统版本以及Flutter框架本身的变化&#xff0…...

整合微信支付一篇就够了

需要的工具 微信开发小程序工具 需要的材料 关键步骤 postman获取微信access_token https://api.weixin.qq.com/cgi-bin/token?appid=wxfssafa629021&grant_type=client_credential&secret=701d213dsfsdfsfdss4fb274生成h5跳转小程序的链接 https://api.weixin.…...

视创云展为企业虚拟展厅搭建,提供哪些功能?

在当下数字化浪潮中&#xff0c;如何为用户创造更富生动性和真实感的展示体验&#xff0c;已成为企业营销策略的核心。借助视创云展的线上虚拟3D企业展厅搭建服务&#xff0c;利用3D空间漫游和VR技术的融合&#xff0c;可以为用户呈现出一个既真实又充满想象力的全景图或三维模…...

c++ 常用的锁及用法介绍和示例

2024/6/21 14:20:10 在 C++ 中,常用的锁主要包括以下几种:std::mutex、std::recursive_mutex、std::timed_mutex 和 std::shared_mutex。这些锁可以帮助我们在多线程编程中保护共享数据,避免竞争条件。以下是每种锁的介绍及其用法示例: std::mutex std::mutex 是最基本的互…...

PostgreSQL源码分析——口令认证

认证机制 对于数据库系统来说&#xff0c;其作为服务端&#xff0c;接受来自客户端的请求。对此&#xff0c;必须有对客户端的认证机制&#xff0c;只有通过身份认证的客户端才可以访问数据库资源&#xff0c;防止非法用户连接数据库。PostgreSQL支持认证方法有很多&#xff1…...

Stability-AI(图片生成视频)

1.项目地址 GitHub - Stability-AI/generative-models: Generative Models by Stability AI 2.模型地址 魔搭社区 3.克隆项目后&#xff0c;按照教程安装 conda create --name Stability python3.10 conda activate Stability pip3 install -r requirements/pt2.txt py…...

Linux机器通过Docker-Compose安装Jenkins发送Allure报告

目录 一、安装Docker 二、安装Docker Compose 三、准备测试用例 四、配置docker-compose.yml 五、启动Jenkins 六、配置Jenkins和Allure插件 七、创建含pytest的Jenkins任务 八、项目结果通知 1.通过企业微信通知 2.通过邮件通知 九、配置域名DNS解析 最近小编接到一…...

基于Gunicorn+Flask+Docker模型高并发部署

关于猫头虎 大家好&#xff0c;我是猫头虎&#xff0c;别名猫头虎博主&#xff0c;擅长的技术领域包括云原生、前端、后端、运维和AI。我的博客主要分享技术教程、bug解决思路、开发工具教程、前沿科技资讯、产品评测图文、产品使用体验图文、产品优点推广文稿、产品横测对比文…...

java:类型变量(TypeVariable)解析--基于TypeResolver实现将类型变量替换为实际类型

上一篇博客《java:类型变量(TypeVariable)解析–获取泛型类(Generic Class)所有的类型变量(TypeVariable)的实际映射类型》中介绍如何如何正确解析泛型类的类型变量(TypeVariable)&#xff0c;获取对应的实际类型。 有了类型变量(TypeVariable)–实际类型的映射&#xff0c;我们…...

ru俄罗斯域名如何申请SSL证书?

我们日常看到的都是com这种国际域名比较普遍&#xff0c;尤其是主流网站&#xff0c;主要原因考虑的其通用性&#xff0c;那么对于地方性的域名大家很少看到&#xff0c;比如俄罗斯国家域名.ru大家还是有些陌生的&#xff0c;但要说中国.CN域名那你就很熟悉了。 有用户在申请过…...

python实现购物车的功能

模拟购物车&#xff0c;准备一个列表 goodList [{name:笔记本电脑,price:8000}, {name:鼠标, price:100}] 5个函数 1.加入购物车 2.收藏商品 3.去结算 4.删除购物车商品 5.清空购物车 购物车 cartList [] 收藏列表 collectSet {笔记本电脑,鼠标} 数据示例 去结算计算出总价…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...