【Day 50 】Linux-nginx反向代理与负载均衡

概述

        在现代 Web 架构中,Nginx 作为高并发、高性能的 HTTP 和反向代理服务器,被广泛应用于提升服务性能、增强系统安全性和实现负载均衡。其中,反向代理能够隐藏后端服务器信息并优化请求处理流程,负载均衡则可将请求分发到多个后端节点,大幅提升系统并发能力。

一、反向代理(proxy 模块)

1. 作用

  • 性能优化:增加业务并发量。Nginx 可缓存静态资源,减少后端服务器处理压力,提升响应速度;同时通过连接复用,提高并发处理能力。
  • 提高业务安全性:隐藏后端业务服务器的真实 IP 和端口信息,避免直接暴露在公网中,降低被攻击风险,
  • 功能扩展:可实现请求过滤、URL 重写、SSL 终结等功能,简化后端服务器的配置复杂度。

2. 核心配置语法

反向代理的核心是通过location 块配合proxy_pass 指令,将特定请求转发至后端服务器。

location URI {proxy_pass 后端服务器地址; 
}
  • URI:匹配路径:指定需要代理的客户端请求路径(如/mp3、/download);

  • proxy_pass 后端服务器地址; 指定请求转发的后端服务器地址(可包含 IP、端口及路径)

  • 后端服务器地址:实际访问地址

明确目标:代理服务器正确转发 + 后端服务器正确响应

(1)路径拼接规则

        Nginx 会自动将location中的匹配路径与proxy_pass的后端地址拼接,拼接方式取决于后端地址是否以斜杠结尾:

  • 若后端地址无斜杠(如http://192.168.140.11/music),客户端请求路径会直接拼接在后端路径后;
  • 若后端地址有斜杠(如http://192.168.140.11/music/),客户端请求路径会替换location的匹配路径后拼接。
  • location /test1 {

            proxy_pass http://aa.linux.com;   //nginx的反向代理,hosts文件需要加上dns解析

    }

    192.168.140.10/music    // 192.168.140.10的网页目录(/var/www/html)下的music文件

    192.168.140.10:8088/music   //若nginx换端口   

(2)不同场景下的配置示例

    场景 1:带 URI 的精确匹配转发
    当访问 Nginx 的任意路径时,代理到后端服务器的/music3 路径:

    location / {proxy_pass http://192.168.140.20/music3;
    }
    # 说明:当客户端访问 Nginx 服务器的任意路径(例如http://你的Nginx地址/xxx)时,
    # Nginx 会将该请求转发到 http://192.168.140.20/music3 对应的服务,
    # 并将后端服务的响应返回给客户端。

    场景 2:不带 URI 的路径转发
    当后端服务器没有特定 URI 时,Nginx 会将 location 中的 URI 拼接到后端地址:

    location /test {proxy_pass http://192.168.140.10;
    }
    # 说明:此时请求http://nginx-ip/test/xyz会被转发为http://192.168.140.10:9000/test/xyz
    

    场景 3:正则表达式匹配的特殊规则
    当 location 使用正则表达式(~~*)匹配请求时,proxy_pass后的后端地址不允许包含任何 URI,否则会报错:

    # 正确配置(无URI)
    location ~ /music {proxy_pass http://192.168.140.10;
    }# 错误配置(包含URI,会导致Nginx启动失败)
    # location ~ /music {
    #     proxy_pass http://192.168.140.10/project;  # 此处错误
    # }
    

    3. 后端服务器记录客户端真实 IP

    默认情况下,后端服务器会将 Nginx 的 IP 识别为客户端 IP,如需记录真实客户端 IP,需通过以下配置实现:

    (1)Nginx 反向代理添加标识字段

    在代理规则中添加X-REAL-IPX-Forwarded-For字段,传递客户端真实 IP:

    location /mp3 {proxy_pass http://192.168.140.11/music;# 传递客户端真实IP给后端proxy_set_header X-REAL-IP $remote_addr;# 若后端为多代理架构,使用X-Forwarded-For记录代理链proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    
    (2)
    ① 后端为 Apache(httpd)时的配置

    修改 Apache 的日志格式,使其解析X-REAL-IP字段:

    # 在httpd.conf中修改combined日志格式
    LogFormat "%{X-REAL-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    
    ② 后端为 Nginx 时的配置

    修改后端 Nginx 的日志格式,使用$http_x_forwarded_for获取真实 IP:

    # 在后端Nginx的main日志格式中添加
    log_format main '$http_x_forwarded_for [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent"';

    二、负载均衡(upstream 模块)

            Nginx 的 upstream 模块是用于管理后端服务器集群的核心组件,通过它可以实现对多台后端服务器的统一调度、状态监控和故障处理。

    1、 作用

    • 提升并发能力:将客户端请求分发到多个后端服务器,避免单节点压力过大,提高系统整体吞吐量。
    • 增强可用性:通过健康检查自动剔除故障节点,确保服务持续可用;同时支持备用节点,进一步提升可靠性。
    • 灵活扩展:可根据业务需求动态增减后端节点,实现无缝扩容。

    2、工作流程

    (以 Nginx 为负载均衡器为例)

    1. 定义后端服务器组:通过upstream块定义一组后端服务器(如192.168.1.10:8080、192.168.1.11:8080),并配置调度算法和节点参数。
    2. 接收客户端请求:客户端请求首先到达 Nginx 负载均衡器(通常是前端入口服务器)。
    3. 选择后端节点:Nginx 根据upstream中配置的调度算法(如轮询、IP 哈希等),从服务器组中选择一台 “合适” 的后端服务器。
    4. 转发请求并返回响应:Nginx 将客户端请求转发到选中的后端服务器,后端处理后将响应返回给 Nginx,再由 Nginx 返回给客户端。

    3、 调度算法 / 策略

    Nginx 提供多种负载均衡算法,可根据业务场景选择:

    ① rr(Round Robin,轮询)

    upstream app_servers {server 192.168.140.10:9000 weight=3;  # 权重3,接收3/5的请求server 192.168.140.11:9000 weight=2;  # 权重2,接收2/5的请求
    }
    
    • 默认算法,请求按顺序轮流分配到后端节点。
    • 支持通过 weight 设置权重(权重越高,分配的请求越多),适用于后端节点性能不均的场景。
    • 会话持久问题(见补充)

    ② sh(Source Hash,源哈希)

    upstream app_servers {ip_hash;  # 启用源哈希算法server 192.168.140.10:9000;server 192.168.140.11:9000;
    }
    
    • 根据客户端 IP 计算哈希值,将同一客户端的请求固定分配到同一后端节点。
    • 适用于需要会话保持的场景(如未使用分布式会话的系统)。

    ③ lc(Least Connections,最少连接)

    upstream app_servers {least_conn;  # 启用最少连接算法server 192.168.140.10:9000;server 192.168.140.11:9000;
    }
    
    • 优先将请求分配到当前连接数最少的后端节点,适用于请求处理时间差异较大的场景。

    4、健康状态检查与故障隔离

    自动检测后端服务器的可用性,对故障节点进行隔离,避免请求转发到不可用的服务器,保障服务稳定性。

    5、配置语法与示例

    # 定义后端服务器组
    upstream 服务器组名称 {[调度算法];  # 可选,默认rrserver IP:port [参数];  # 后端节点及可选参数server IP:port [参数];
    }# 引用服务器组
    location URI {proxy_pass http://服务器组名称;
    }
    
    常用参数说明
    • weight=数值:设置节点权重(默认 1),数值越大优先级越高。
    • max_fails=次数:允许请求失败的最大次数(默认 1),超过则标记节点为不可用。
    • fail_timeout=秒数:标记节点不可用的时间(默认 10 秒),超时后会重新检测节点。
    • backup:标记为备用节点,仅当所有非备用节点不可用时才接收请求。
    • down:标记节点为永久不可用(手动下线时使用)。
    完整配置示例
    # 定义Java应用服务器组(使用轮询算法)
    upstream java_servers {server 192.168.140.10:9000 weight=1 max_fails=2 fail_timeout=3s;  # 权重1,失败2次后3秒内不分配server 192.168.140.10:9001 weight=1 max_fails=2 fail_timeout=3s;server 127.0.0.1:8000 backup;  # 备用节点,主节点全故障时启用
    }# 转发所有根路径请求到java_servers
    location / {proxy_pass http://java_servers/project/;proxy_set_header X-REAL-IP $remote_addr;  # 传递真实客户端IPproxy_set_header Host $host;  # 传递原始请求的Host头
    }# 转发/music路径请求到java_servers的/music目录
    location /mp3 {proxy_pass http://java_servers/music/;proxy_set_header X-REAL-IP $remote_addr;
    }# 备用节点的本地服务配置(当主节点故障时提供降级页面)
    server {listen 8000;server_name localhost;location / {root /usr/share/nginx/sorry;  # 存放降级页面的目录index index.html;  # 降级页面}
    }

    演示:

    环境准备

    假设有 3 台机器,IP 分别为:

    • 负载均衡器(Nginx)192.168.140.20(接收客户端请求,分发到后端)

    • 后端服务器 1(nginx)192.168.140.10

    • 后端服务器 2(httpd)192.168.140.30

    步骤 1:配置后端服务器(10 和 30)

    在 10 和 30 上安装 Nginx/httpd(模拟 Web 服务)

    创建测试页面(区分两台服务器,方便验证负载均衡效果)

    • echo "This is backend server 10 "  > /usr/local/nginx/html/index.html     //在 10 上执行
    • echo "This is backend server 30" > /usr/share/nginx/html/index.html     //在 30 上执行

    验证后端服务

            分别访问 http://192.168.140.10 和 http://192.168.140.30, 应显示各自的测试内容。

    步骤 2:配置负载均衡器(100)

            在负载均衡器上安装 Nginx,并通过 upstream 模块定义后端服务器集群,实现请求分发。

    安装 Nginx:

            修改 Nginx 配置文件(/usr/local/nginx/conf/nginx.conf),在http块中添加 upstream(后端集群)和server(负载均衡规则):

    http {# ... 其他默认配置(保留不动)# 1. 定义后端服务器集群(包含101和102)upstream backend_servers {# 调度算法:默认轮询(可按需改为weight、ip_hash等)server 192.168.1.101:80;  # 后端服务器1server 192.168.1.102:80;  # 后端服务器2server 127.0.0.1:8000 backup;  # 备用节点,主节点全故障时启用# 可选:添加健康检查参数(自动剔除故障节点)# max_fails=2:允许2次请求失败# fail_timeout=10s:失败后隔离10秒# server 192.168.1.101:80 max_fails=2 fail_timeout=10s;}# 2. 配置负载均衡入口(接收客户端请求)server {listen 80;  # 监听80端口(客户端访问的端口)server_name 192.168.1.100;  # 负载均衡器的IP# 所有请求转发到后端集群location / {proxy_pass http://backend_servers;  # 转发到upstream定义的集群proxy_set_header Host $host;  # 传递客户端访问的Host(如192.168.1.100)proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;  # 传递协议(http/https)}}server {listen 8000;  # 备用服务端口server_name 127.0.0.1;location / {root /usr/local/nginx/backup_html;  # 备用服务的网页目录index index.html;}}
    }
    

    # 创建备用服务的测试页面:
    mkdir -p /usr/local/nginx/backup_html
    # 写入备用内容(如“主节点故障,已切换至备用服务”)
    echo "This is backup server (local 8000)" > /usr/local/nginx/backup_html/index.html

    // 加权轮询:若后端服务器性能不同,可通过weight分配请求比例(值越高,接收请求越多):

    upstream backend_servers {server 192.168.1.101:80 weight=3;  # 承担3/5的请求server 192.168.1.102:80 weight=2;  # 承担2/5的请求
    }
    

    // 若需同一客户端请求固定到同一后端(如未做会话共享),使用ip_hash:

    upstream backend_servers {ip_hash;  # 基于客户端IP哈希server 192.168.1.101:80;server 192.168.1.102:80;
    }

    检查配置并重启 Nginx

    步骤 3:修改httpd/nginx配置文件

    • vim /etc/httpd/conf/httpd.conf 
    • vim /usr/local/nginx/conf/nginx.conf

    步骤 4:测试负载均衡效果

    通过客户端访问负载均衡器的 IP(192.168.140.20),验证请求是否被分发到两台后端服务器。

    1、多次访问测试:
    在浏览器或终端多次访问 http://192.168.140.20,应交替显示:

    • This is backend server 10

    • This is backend server 30

    • (默认轮询算法下,请求会依次分发到 10 和 30)。

    2、模拟故障测试:

    • 停止后端10 的 Nginx(systemctl stop nginx),再次访问 http://192.168.140.20,应始终显示 30 的内容(Nginx 会自动剔除故障节点)。
    • 停止后端10 和20的,再次访问 http://192.168.140.20,应始终显示备用节点

    特殊的:如果负载均衡如此设置

    • echo "This is backend server 10/ab "  > /usr/local/nginx/html/ab/index.html 
    • echo "This is backend server 30/ab" > /var/www/html/ab/index.html 

    此时搜索192.168.140.20依次显示This is backend server 10/ab、This is backend server 20/ab


    一、什么是会话?

            在计算机网络和 Web 开发中,会话(Session) 指的是用户与系统(通常是服务器)之间的一次连续交互过程,核心作用是记录用户的状态信息,解决 HTTP 协议 “无状态” 的问题。

    二、为什么需要会话?

            HTTP 协议本身是 “无状态” 的:每次客户端(如浏览器)向服务器发送请求时,服务器无法默认记住 “这个请求来自哪个用户”“用户之前做过什么操作”。例如:

    • 你在电商网站登录后,浏览商品、加入购物车,如果没有会话,服务器会 “忘记” 你已登录,也记不住你的购物车内容;
    • 你在论坛发帖时,服务器需要知道 “你是谁” 才能关联到你的账号。

            会话的出现,就是为了让服务器 “记住” 用户的状态(如登录信息、操作历史、偏好设置等),让交互更连贯。

            会话的核心逻辑:会话的实现依赖 “会话标识(Session ID)”,流程大致如下:

    • 创建会话:用户第一次访问服务器时,服务器生成一个唯一的 Session ID(如一串随机字符串),并创建一个对应的 “会话空间”(存储用户状态,如登录状态、购物车数据等);
    • 传递标识:服务器将 Session ID 通过Cookie(主流方式)或 URL 参数返回给客户端,客户端后续请求时会自动携带这个 ID;
    • 识别用户:服务器收到请求后,通过 Session ID 找到对应的 “会话空间”,从而识别用户身份和状态,继续处理请求(如确认 “已登录”、读取购物车内容);
    • 销毁会话:当用户主动退出(点击 “退出登录”)或会话超时(如 30 分钟未操作),服务器会删除对应的会话数据,Session ID 失效。

    二、什么是 “会话持久问题”?

            在负载均衡(多后端服务器)环境中,用户的请求会被分发到不同的服务器。但默认情况下,用户的会话信息(如登录状态、临时数据)是存储在单个服务器的本地内存 / 文件中的。这会导致一个问题:

    • 用户第一次请求被分到服务器 A,登录状态保存在 A 的本地;
    • 第二次请求被负载均衡器分到服务器 B,B 没有用户的登录状态,用户需要重新登录。

    这种 “用户状态无法在多服务器间共享” 的问题,就是会话持久问题。

    三、如何解决?—— 会话共享

            核心思路:将用户的会话信息从 “单服务器本地存储” 迁移到 “所有服务器都能访问的集中式存储”,让所有后端服务器都能读取到相同的会话数据。

    NoSQL 数据库非关系型数据库(如 Redis、MongoDB、memached)实现会话共享。

    • 高性能:NoSQL(尤其是 Redis)支持内存存储,读写速度极快,适合会话这种高频访问的数据;(对内存要求高)
    • 键值结构适配:会话数据通常是 “会话 ID→用户信息” 的键值对形式,与 NoSQL 的存储模型天然匹配;
    • 支持过期时间:可直接为会话数据设置过期时间(如 2 小时),自动清理无效会话,无需手动维护;
    • 高可用:NoSQL 可通过集群部署(如 Redis 主从、哨兵)避免单点故障,确保会话数据不丢失。

    四、基于 NoSQL 的会话共享流程

    以最常用的 Redis 为例,完整流程如下:

    用户首次登录:

    • 用户在浏览器输入账号密码,请求被负载均衡器分发到某台后端服务器(如服务器 A);
    • 服务器 A 验证通过后,生成一个唯一的会话 ID(如session_id=xxxx);
    • 将用户的会话数据(如用户 ID、登录时间、权限等)以session_id为键,存储到 Redis 中(例如:SET session:xxxx "{user_id:100, status:login}" EX 7200,设置 2 小时过期);
    • 服务器 A 将session_id通过 Cookie 或 URL 参数返回给客户端(浏览器),客户端后续请求会自动携带该session_id。

    用户后续请求:

    • 客户端携带 session_id 发送请求,被负载均衡器分发到任意服务器(如服务器 B);
    • 服务器 B 收到请求后,从 Redis 中通过session_id查询会话数据(GET session:xxxx);
    • 若查询到有效数据,说明用户已登录,直接返回请求结果;若未查询到(过期或无效),则要求用户重新登录。

    会话过期 / 注销:

    • 若用户主动退出登录,服务器删除 Redis 中对应的session_id数据;
    • 若用户长时间未操作,Redis 会自动根据预设的过期时间删除会话数据,实现 “自动登出”。

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

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

    相关文章

    vue中配置 ts

    在 Vue 项目中配置 TypeScript(TS)可以提升代码的类型安全性和开发体验。以下是在 Vue 项目(基于 Vite)中配置 TypeScript 的详细步骤和关键配置: 一、创建支持 TypeScript 的 Vue 项目 如果是新建项目,推…

    阿里云镜像地址获取,并安装 docker的mysql和nginx等服务,java,python,ffmpeg,go等环境

    阿里云那个镜像地址获取 阿里云镜像加速器不是一个通用的 registry.cn-hangzhou.aliyuncs.com,而是你账号专属的,比如这样: https://abcd1234.mirror.aliyuncs.com👉 登录阿里云控制台获取: 阿里云镜像加速器 然后替…

    conda环境导出

    1. 激活你想要打包的环境首先,确保你激活了你要打包的 conda 环境:conda activate qwen2. 导出环境配置使用 conda 命令将当前环境的配置导出为一个 .yml 文件,记录下环境中所有的依赖和版本:conda list --export > techgpt_en…

    openEuler2403安装部署Kafka

    文章目录 openEuler2403安装部署Kafka with KRaft一、前言1.简介2.架构3.环境 二、正文1.部署服务器2.基础环境1)JDK 安装部署2)关闭防火墙 3.单机部署1)下载软件包2)修改配置文件3)格式化存储目录4)单机启…

    发布工业智能体,云从科技打造制造业AI“运营大脑”

    近日,在2025世界智能产业博览会重庆市工业智能体首发仪式现场,云从科技重磅发布经营决策-产线运营智能体,为制造业的智能化转型提供了全新的解决方案。该智能体的亮相,不仅代表着人工智能技术在工业领域的深度应用,更标…

    【Linux基础】parted命令详解:从入门到精通的磁盘分区管理完全指南

    目录 前言 1 parted命令概述 1.1 什么是parted 1.2 parted与fdisk的对比 1.3 parted的主要优势 2 parted命令的安装与基本语法 2.1 在不同Linux发行版中安装parted 2.2 parted的基本语法 2.3 parted的工作模式 3 parted交互式命令详解 3.1 交互式操作流程 3.2 主要…

    如何在路由器上配置DHCP服务器?

    在路由器上配置DHCP服务器的步骤因品牌(如TP-Link、华为、小米、华硕等)略有差异,但核心流程一致,主要包括登录管理界面、开启DHCP功能、设置IP地址池及相关参数。以下是通用操作指南: 一、准备工作 确保电脑/手机已连…

    HTML和CSS学习

    HTML学习 注释 <!-- -->组成 告诉浏览器我是html文件<!DOCTYPE html> <title>浏览器标签</title> <body> <!--- 其中是主要内容 ---> <p> 段落 </p> </body> </html> (结束点…

    OpenTenBase vs MySQL vs Oracle,企业级应用数据库实盘对比分析

    摘要 因为工作久了的缘故&#xff0c;接触过不少数据库。公司的管理系统用的MySQL&#xff0c;财务系统用的Oracle。随着时代发展&#xff0c;国产开源数据库已经在性能上能与这些国际知名顶尖数据库品牌相媲美&#xff0c;其中OpenTenBase以其开放环境和优越性能脱颖而出&…

    Oracle 备份与恢复常见的七大问题

    为了最大限度保障数据的安全性&#xff0c;同时能在不可预计灾难的情况下保证数据的快速恢复&#xff0c;需要根据数据的类型和重要程度制定相应的备份和恢复方案。在这个过程中&#xff0c;DBA的职责就是要保证数据库&#xff08;其它数据由其它岗位负责&#xff09;的高可用和…

    StringBuilder类的数据结构和扩容方式解读

    目录 StringBuilder是什么 核心特性&#xff1a; StringBuilder数据结构 1. 核心存储结构&#xff08;基于父类 AbstractStringBuilder&#xff09; 2. 类定义与继承关系 3. 数据结构的核心特点 StringBuilder数据结构的初始化方式 1. 无参构造&#xff1a;默认初始容量…

    LangChain实战(十七):构建与PDF/PPT文档对话的AI助手

    本文是《LangChain实战课》系列的第十七篇,将专篇深入讲解如何构建能够与PDF和PPT文档进行智能对话的AI助手。通过学习本文,您将掌握复杂格式文档的解析技巧、文本与表格处理技术,以及实现精准问答的系统方法。 前言 在日常工作和学习中,PDF和PPT文档是我们最常接触的文档…

    鱼眼相机模型

    鱼眼相机模型 最近涉及鱼眼相机模型、标定使用等&#xff0c;作为记录&#xff0c;更新很久不曾更新的博客。 文章目录鱼眼相机模型1 相机成像2 鱼眼模型3 畸变3.1 适用针孔和MEI3.2 Kannala-Brandt鱼眼模型4 代码实现1 相机成像 针孔相机&#xff1a;所有光线从一个孔&#xf…

    大语言模型提示词工程详尽实战指南

    引言&#xff1a;与大型语言模型&#xff08;LLM&#xff09;高效对话的艺术大型语言模型&#xff08;LLM&#xff09;——例如我们熟知的GPT系列、Claude、Llama等——在自然语言处理&#xff08;NLP&#xff09;领域展现了惊人的能力&#xff0c;能够执行文本摘要、翻译、代码…

    HTTP 请求体格式详解

    1. 概览与概念 Content-Type&#xff1a;HTTP 请求/响应头&#xff0c;表示消息体的媒体类型&#xff08;MIME type&#xff09;。服务端用它决定如何解析请求体。常见场景&#xff1a; 纯结构化数据&#xff08;JSON&#xff09; → application/json表单 文件上传 → multip…

    事务设置和消息分发

    事务 RabbitMQ是基于AMQP协议实现的&#xff0c;该协议实现了事务机制&#xff0c;因此RabbitMQ也支持事务机制. SpringAMQP也提供了对事务相关的操作&#xff0c;RabbitMQ事务允许开发者确保消息的发送和接收是原子性的&#xff0c;要么 全部成功&#xff0c;要么全部失败.| 前…

    Python 中 try / except / else / finally 异常处理详解

    1. 基本结构 try:# 可能会抛出异常的代码 except SomeException as e:# 捕获并处理异常 else:# 如果 try 中代码没有异常&#xff0c;就执行这里 finally:# 无论是否发生异常&#xff0c;最后都会执行这里2. 各部分的作用 try 用途&#xff1a;包含可能发生异常的代码段。如果代…

    冰火岛 Tech 传:Apple Foundation Models 心法解密(下集)

    引子 上集说到冰火岛冰屋内,谢逊、张翠山、殷素素三人亲见 “指令(Instructions)” 如何让 AI 脱胎换骨,从木讷报地名的 “愣头青”,变身为文采斐然的 “旅行作家”。 正当素素惊叹这 AI 武学的奇妙时,谢逊却突然神色一凛,指着手腕上用冰屑刻的 “4096” 字样道:“这等…

    Qt信号与槽机制全面解析

    ✨ 1. 核心概念信号与槽是Qt独创的一种对象间通信机制&#xff0c;它使得一个对象的状态变化或事件发生能够自动通知其他对象作出响应&#xff0c;从而实现高度解耦的代码设计。1.1 信号&#xff08;Signals&#xff09;定义&#xff1a;信号是由对象在特定事件发生时发出&…

    2025年COR SCI2区,基于近似细胞分解的能源高效无人机路径规划问题用于地质灾害监测,深度解析+性能实测

    目录1.摘要2.问题描述与数学模型3.能源网格混合元启发式算法4.结果展示5.参考文献6.代码获取7.算法辅导应用定制读者交流1.摘要 本文提出了一种能源高效的无人机路径规划方法&#xff08;EURP&#xff09;用于监测分散的地质灾害易发区域&#xff0c;通过建立无人机飞行模式的…