为什么 NGINX 的 reload 命令不是热加载?

news2025/7/22 16:25:04

这段时间在 Reddit 看到一个讨论,为什么 NGINX 不支持热加载?乍看之下很反常识,作为世界第一大 Web 服务器,不支持热加载?难道大家都在使用的 nginx -s reload 命令都用错了?带着这个疑问,让我们开始这次探索之旅,一起聊聊热加载和 NGINX 的故事。

NGINX 相关介绍

NGINX 是一个跨平台的开源 Web 服务器,使用 C 语言开发。据统计,全世界流量最高的前 1000 名网站中,有超过 40% 的网站都在使用 NGINX 处理海量请求。

NGINX 有什么优势,导致它从众多的 Web 服务器中脱颖而出,并一直保持高使用量呢?

我觉得核心原因在于,NGINX 天生善于处理高并发,能在高并发请求的同时保持高效的服务。

相比于同时代的其他竞争对手例如 Apache、Tomcat 等,其领先的事件驱动型设计和全异步的网络 I/O 处理机制,以及极致的内存分配管理等众多优秀设计,将服务器硬件资源压缩到了极致。使得 NGINX 成为高性能 Web 服务器的代名词。

当然,除此之外还有一些其他原因,比如:

  • 高度模块化的设计,使得 NGINX 拥有无数个功能丰富的官方模块和第三方拓展模块。

  • 最自由的 BSD 许可协议,使得无数开发者愿意为 NGINX 贡献自己的想法。

  • 支持热加载,能保证 NGINX 提供 7x24h 不间断的服务。

关于热加载

大家期望的热加载功能是什么样的?我个人认为,首先应该是用户端无感知的,在保证用户请求正常和连接不断的情况下,实现服务端或上游的动态更新。

那什么情况下需要热加载?在如今云原生时代下,微服务架构盛行,越来越多的应用场景有了更加频繁的服务变更需求。包括反向代理域名上下线、上游地址变更、IP 黑白名单更新等,这些都和热加载息息相关。

那么 NGINX 是如何实现热加载的?

NGINX 热加载的原理

执行 nginx -s reload 热加载命令,就等同于向 NGINX 的 master 进程发送 HUP 信号。在 master 进程收到 HUP 信号后,会依次打开新的监听端口,然后启动新的 worker 进程。

此时会存在新旧两套 worker 进程,在新的 worker 进程起来后,master 会向老的 worker 进程发送 QUIT 信号进行优雅关闭。老的 worker 进程收到 QUIT 信号后,会首先关闭监听句柄,此时新的连接就只会流进到新的 worker 进程中,老的 worker 进程处理完当前连接后就会结束进程。

从原理上看,NGINX 的热加载能很好地满足我们的需求吗?答案很可能是否定的,让我们来看下 NGINX 的热加载存在哪些问题。

NGINX 热加载的缺陷

首先,NGINX 频繁热加载会造成连接不稳定,增加丢失业务的可能性。

NGINX 在执行 reload 指令时,会在旧的 worker 进程上处理已经存在的连接,处理完连接上的当前请求后,会主动断开连接。此时如果客户端没处理好,就可能会丢失业务,这对于客户端来说明显就不是无感知的了。

其次,在某些场景下,旧进程回收时间长,进而影响正常业务。

比如代理 WebSocket 协议时,由于 NGINX 不解析通讯帧,所以无法知道该请求是否为已处理完毕状态。即使 worker 进程收到来自 master 的退出指令,它也无法立刻退出,而是需要等到这些连接出现异常、超时或者某一端主动断开后,才能正常退出。

再比如 NGINX 做 TCP 层和 UDP 层的反向代理时,它也没法知道一个请求究竟要经过多少次请求才算真正地结束。

这就导致旧 worker 进程的回收时间特别长,尤其是在直播、新闻媒体活语音识别等行业。旧 worker 进程的回收时间通常能达到半小时甚至更长,这时如果再频繁 reload,将会导致 shutting down 进程持续增加,最终甚至会导致 NGINX OOM,严重影响业务。

 
# 一直存在旧 worker 进程:nobody 6246 6241 0 10:51 ? 00:00:00 nginx: worker process nobody 6247 6241 0 10:51 ? 00:00:00 nginx: worker process nobody 6247 6241 0 10:51 ? 00:00:00 nginx: worker process nobody 6248 6241 0 10:51 ? 00:00:00 nginx: worker process nobody 6249 6241 0 10:51 ? 00:00:00 nginx: worker process nobody 7995 10419 0 10:30 ? 00:20:37 nginx: worker process is shutting down  <= here nobody 7995 10419 0 10:30 ? 00:20:37 nginx: worker process is shutting down nobody 7996 10419 0 10:30 ? 00:20:37 nginx: worker process is shutting down

从上述内容可以看到,通过 nginx -s reload方式支持的“热加载”,虽然在以往的技术场景中够用,但是在微服务和云原生迅速发展的今天,它已经捉襟见肘且不合时宜。

如果你的业务变更频率是每周或者每天,那么 NGINX 这种 reload 还是满足你的需求的。但如果变更频率是每小时、每分钟呢?假设你有 100 个 NGINX 服务,每小时 reload 一次的话,就要 reload 2400 次;如果每分钟 reload 一次,就是 864 万次。这显然是无法接受的。

因此,我们需要一个不需要进程替换的 reload 方案,在现有 NGINX 进程内可以直接完成内容的更新和实时生效。

在内存中直接生效的热加载方案

在 Apache APISIX 诞生之初,就是希望来解决 NGINX 热加载这个问题的。

Apache APISIX 是基于 NGINX + Lua 的技术栈,以  ETCD 作为配置中心实现的云原生、高性能、全动态的微服务 API 网关,提供负载均衡、动态上游、灰度发布、精细化路由、限流限速、服务降级、服务熔断、身份认证、可观测性等数百项功能。

使用 APISIX 你不需要重启服务就可以更新配置,这意味着修改上游、路由、插件时都不用重启。既然是基于 NGINX,APISIX 又是如何摆脱 NGINX 的限制实现完美热更新?我们先看下 APISIX 的架构。

通过上述架构图可以看到,之所以 APISIX 能摆脱 NGINX 的限制是因为它把上游等配置全部放到 APISIX Core 和 Plugin Runtime 中动态指定。

以路由为例,NGINX 需要在配置文件内进行配置,每次更改都需要 reload 之后才能生效。而为了实现路由动态配置,Apache APISIX 在 NGINX 配置文件内配置了单个 server,这个 server 中只有一个 location。我们把这个 location 作为主入口,所有的请求都会经过这个 location,再由 APISIX Core 动态指定具体上游。因此 Apache APISIX 的路由模块支持在运行时增减、修改和删除路由,实现了动态加载。所有的这些变化,对客户端都零感知,没有任何影响。

再来几个典型场景的描述。

比如增加某个新域名的反向代理,在 APISIX 中只需创建上游,并添加新的路由即可,整个过程中不需要 NGINX 进程有任何重启。再比如插件系统,APISIX 可以通过 ip-restriction 插件实现 IP 黑白名单功能,这些能力的更新也是动态方式,同样不需要重启服务。借助架构内的 ETCD,配置策略以增量方式实时推送,最终让所有规则实时、动态的生效,为用户带来极致体验。

总结

NGINX 的热加载在某些场景下会长时间存在新旧两套进程,导致额外消耗资源,同时频繁热加载也会导致小概率业务丢失。面对当下云原生和微服务的技术趋势下, 服务变化更加的频繁,控制 API 的策略也发生了变化,导致我们对热加载的需求提出了新需求,NGINX 的热加载已经不能满足实际业务需求。

现在是时候切换到更贴合云原生时代并且更完善的热加载策略、性能表现卓越的 API 网关——Apache APISIX,从而享受动态、统一管理等特性带来的管理效率上的极大提升。

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

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

相关文章

DiffusionDet: Diffusion Model for Object Detection

paper: https://arxiv.org/abs/2211.09788 code&#xff1a;https://github.com/ShoufaChen/DiffusionDet 探索了扩散模型在非生成类任务&#xff08;目标检测&#xff09;中的应用。相较于传统Coarse-to-fine方法&#xff0c;基于扩散思路训练有两个特点&#xff1a;1&…

网络编程/计算机网络

目录 一、网络基本概念 1.网络 2.互联网 3.ip地址 4.MAC地址 5.端口号Port 6.网络协议 二.网络分层模型 1.数据链路层 2.网络层 3.传输层 4.应用层 三、网络应用程序通信流程 四、socket 网络编程 1.主机字节序列和网络字节序列 2.套接字地址结构 &#xff08…

离群点检测和新颖性检测

引言 在异常检测领域中&#xff0c;我们常常需要决定新观测点是否属于与现有观测点相同的分布&#xff0c; &#xff08;则称它们为inlier),或被认为是不同的(outlier). 在这里&#xff0c;必须做出两个重要的区别&#xff1a; 异常值检测&#xff1a;outlier detection 训练…

List接口与实现类

目录 一、List接口 1.特点&#xff1a; 2.方法&#xff1a; 二、List接口的使用 三、List实现类 1.ArrayList&#xff08;重点&#xff09; &#xff08;1&#xff09;特点 &#xff08;2&#xff09;示例 &#xff08;3&#xff09;源码分析 2.Vector &#xff08;1…

Python列表推导式——List

目录 遍历列表 range函数 列表推导式(★★★★★)五星技能点 五万次【列表推导式】与【for】遍历计算消耗时间对照表&#xff1a; 列表推导式逻辑判断 遍历列表 通过for in循环来遍历集合列表 range函数 我们基础range函数是参数范围是range(start,stop)&#xff0c;在下…

利用天翎知识文档+群晖NAS搭建企业知识库,享用智能检索

编者按&#xff1a;检索是知识文档管理中常见切十分重要的功能&#xff0c;搭建企业知识库必不可少。本文分析了智能检索的特点&#xff0c;并介绍了其在知识文档管理系统中的实现。 关键词&#xff1a;智能检索&#xff0c;移动端&#xff0c;群晖NAS 知识管理中的检索功能 …

基于Java+SpringBoot+Mybaties+Vue 在线问卷调查系统设计与实现

一.项目介绍 本项目 可支持注册、登录 创建问卷、设置问卷内容&#xff08;支持单选、多选、问答题&#xff09; 分享问卷链接、分析问卷 查看问卷库、以及填写问卷内容 等功能 该项目采用 Springboot Mybaties Vue element UI 框架实现 二.环境需要 1.运行环境&#xff1…

教育科技创新即将崛起

随着“双减”政策的不断落实&#xff0c;真正具有创新精神和懂得教育科技的人&#xff0c;他们所创造的新模式、新生态即将崛起&#xff0c;属于教育科技和创新的春天即将到来。 那么&#xff0c;教育科技化和创新在不同的教育场景有什么体现呢&#xff1f; 我们先来看看目前…

【雷达通信】雷达探测项目仿真(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

OCR-paddleocr

PaddleOCR 分为 Detection&#xff08;文本检测&#xff09;、Direction classifier&#xff08;方向分类器&#xff09;和 Recognition&#xff08;文本识别&#xff09;三部分&#xff0c;因此需要三个模型。一、介绍 PaddleOCR是一款超轻量、中英文识别模型目标是打造丰富、…

【软件测试】测试人填坑?测试工作中的坑成长经历,填着填着就成了神......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 小刘&#xff1a; 之…

深度强化学习DRL现存问题和训练指南(D3QN(Dueling Double DQN))

目录 强化学习 问题 好用的算法标准 表现好 减小学习曲线的波动 On-Policy和off-Policy区别 学习方式 采样数据利用 学习本质 优缺点 DQN 创新点 优点 缺点 MDP和POMDP 结果图 DQN DDQN Dueling DQN 参数 iteration episode epoch Batch_Size Experime…

全新电商版本答案——全民拼购,越拼越得,白嫖产品不是梦

根据国家市场监督管理总局自2020年12月1日起发布的《规范促销暂行规定》第十二条的规定&#xff0c;为了推广自己的平台商城或商品&#xff0c;获取流量&#xff0c;采用新购买模式运营的平台通过附带给未被选中的参与者一定的奖金或者其他利益&#xff0c;属于有奖销售。 在此…

RS编码译码误码率性能matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法描述 纠错编码技术在卫星通信、移动通信及数字存储等领域已获得了广泛的应用。RS码作为其中最重要的码类之一,具有优良的纠随机错误和突发错误的能力,被空间数据系统咨询委员会(CCSDS)作为一种…

记录安装Cytoscape的过程

一、安装前的准备工作 1、先java 看了大佬们的安装教程&#xff1a; 看到说先要安装对应的Java才能下载相应的cytoscape&#xff0c;因cytoscape是基于java的软件。 cytoscape安装教程1 cytoscape安装教程2 然后&#xff0c;自查了自己电脑上的Java版本,应该为jdk 11&#x…

【js】【爬虫】fetch + json-server 快速搭建爬虫服务器环境及数据后续处理(突破session缓存大小限制)

文章目录导读需求开发环境json-server使用安装json-server创建数据文件db.json运行服务器修改默认端口json-server提供的线上服务&#xff08;不推荐&#xff09;fetch上传数据到json-server服务器通过fetch新增数据报错Error: Insert failed, duplicate id数据后续处理打开导入…

ShellBrowser Delphi,Delphi组件功能和工具

ShellBrowser Delphi,Delphi组件功能和工具 ShellBrowser基本上被描述为集合的一部分&#xff0c;它能够为用户和开发人员提供Delphi的程序员&#xff0c;以便轻松灵活地访问windows shell性能。ShellBrowserComponents Delphi的使用基本上是能够模拟windows资源管理器的变体。…

阅读源码时:idea中如何使用todo标记、活动模板 (史上最全)

接下来&#xff0c; 尼恩要带大家 完成一个 超级牛逼的 大厂offer 收割机项目—— 100Wqps 三级组件 实操&#xff0c; 实操中&#xff0c;用到 caffeine 并且&#xff0c;尼恩要带大家 穿透式 、起底式的 学习 caffeine 的源码和架构&#xff0c; caffeine 的源码 特别复杂…

Linux之service服务-实现程序脚本开机自启

一、什么是.service文件&#xff1f; Linux中.service文件是某项服务对应的配置文件&#xff0c;可用于systemd管理和控制的服务的设置。 .service 文件通常包含3个模块&#xff1a; [Unit] 控制单元&#xff0c;表示启动顺序和依赖关系。[Service] 服务&#xff0c;表示…

LeetCode HOT 100 —— 23.合并K个升序链表

题目 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 思路 在做本题之前&#xff0c;先考虑一下&#xff0c;如何合并两个有序链表&#xff0c;见 21.合并两个有序链表 最直接的思路就是&am…