云原生(企业高性能 Web 服务器(Nginx 核心))

一、Web 服务基础介绍

1.1 Apache 经典 Web 服务端

Apache 历经 1.X、2.X 两大版本,支持编译安装定制功能,核心有三种工作模型,均基于多进程 / 线程架构,各有适用场景:

模型 核心原理 优点 缺点 适用场景
prefork(预派生) 主进程生成多个独立子进程,单进程单线程,select 模型,最大并发 1024 稳定性极高,进程独立互不影响 内存占用大,并发能力弱,每个请求对应一个进程 访问量小、对稳定性要求高的场景
worker(多进程多线程) 主进程启动子进程,子进程包含固定线程,线程处理请求,线程不足时新建子进程 内存占用比 prefork 少,并发能力更高 keepalive 长连接会占用线程至超时,高并发下易无可用线程 中等访问量场景
event(事件驱动) 2.4.X 版本正式支持,epoll 模型,与 worker 类似,新增专门线程管理 keepalive 线程 单线程响应多请求,内存占用最低,高并发表现优秀,解决 keepalive 线程资源浪费 无线程安全控制 高并发访问场景

Apache prefork 模型

Apache worker 模型

Apache event模型

1.2 Nginx 高性能 Web 服务端

1.2.1 基础信息
  • 开发者:伊戈尔・赛索耶夫,为俄罗斯rambler.ru开发,2004 年首次公开发布,2019 年被 F5 以 6.7 亿美元收购。
  • 版本分类:开发版、稳定版、过期版,核心模块代码量约 19.8 万行。
  • 官网:www.nginx.org
  • 行业应用:天猫、淘宝、京东、小米等一线互联网公司均使用或二次开发。
1.2.2 核心优势与功能
  • 高性能:解决 C10K(万级连接)问题,低内存消耗(10000 个 keep-alive 非活动连接仅需 2.5M 内存)。
  • 功能丰富:可作为 HTTP/HTTPS 服务器、反向代理、邮件代理、TCP/UDP 代理;支持 FastCGI、SSL、虚拟主机、URL 重写、Gzip、负载均衡(1.9 + 开启 stream 模块),支持第三方扩展。
  • 高可靠性:模块化设计、支持热部署(不停机更新配置 / 升级 / 换日志)。
1.2.3 典型工作场景

Nginx 前置处理请求,静态资源直接返回,动态资源转发至 Tomcat 等应用服务器,数据存储至 MySQL,图片等资源由专用存储服务器提供,实现动静分离与服务分层。

1.3 服务端 I/O 流程

1.3.1 核心概念
  • I/O:Input/Output,指用户空间进程与内核空间的数据交换,需将内核内存数据复制到用户进程内存。
  • IOPS:每秒输入输出量,衡量磁盘性能的核心指标,指单位时间内处理的读 / 写请求数。
  • 服务器 I/O 类型:磁盘 I/O(进程请求磁盘资源,内核加载后复制至进程)、网络 I/O(对 socket 文件的读写,网络协议栈与用户进程的数据交换)。
1.3.2 通用 I/O 阶段

无论磁盘 / 网络 I/O,均分为两个阶段:

  1. 数据从文件 / 网卡加载至内核内存缓冲区,等待数据准备完成(耗时较长);
  2. 数据从内核缓冲区复制至用户空间进程内存(耗时较短)。

1.4 I/O 模型

I/O 模型的核心区分维度为同步 / 异步 (消息通信机制,是否主动通知处理结果)、阻塞 / 非阻塞(等待结果时的进程状态,是否被挂起),主流有 5 种网络 I/O 模型,前 4 种为同步 I/O,仅异步 I/O 为纯异步。

1.4.1 核心概念
  • 同步:被调用者不主动通知结果,调用者需主动查询;
  • 异步:被调用者通过状态 / 通知 / 回调主动告知调用者运行状态;
  • 阻塞:IO 操作完成前,进程被挂起,无法执行其他操作;
  • 非阻塞:IO 操作调用后立即返回状态,进程不挂起,可执行其他操作。
1.4.2 5 种网络 I/O 模型详解
  1. 阻塞型 I/O(blocking IO)
    • 原理:用户线程发起系统调用后,全程阻塞,直至数据从内核复制至用户空间;
    • 优点:程序简单,阻塞期间基本不占用 CPU;
    • 缺点:单连接单进程 / 线程,并发高时内存、线程切换开销大(Apache prefork 基于此)。
  2. 非阻塞型 I/O(nonblocking IO)
    • 原理:用户线程发起调用后立即返回,无数据则返回错误,通过轮询反复发起调用,直到获取数据;
    • 缺点:轮询消耗大量 CPU,上下文切换频繁,实际极少单独使用。
  3. 信号驱动式 I/O(signal-driven IO)
    • 原理:通过 sigaction 注册信号处理函数,进程继续执行,内核数据就绪时发送 SIGIO 信号,进程在回调中获取数据;
    • 优点:等待数据时进程不阻塞,资源利用率高;
    • 缺点:大量 IO 操作时信号队列易溢出,无法通知。
  4. 异步 I/O(asynchronous IO)
    • 原理:用户线程发起 aio_read 后立即返回,内核完成数据准备 + 复制全流程后,主动通知进程;
    • 优点:充分利用 DMA 特性,I/O 与计算重叠,全程非阻塞;
    • 缺点:操作系统实现复杂,Linux 2.6 才引入,AIO 不完善,常用开源库(libevent、libev)实现。
  5. 多路复用 I/O(I/O multiplexing)
    • 原理:单个线程通过 select/poll/epoll 系统调用,同时监控多个文件描述符(socket),内核发现任一描述符就绪后通知线程,线程再处理对应请求;
    • 核心实现:select(数组,最大连接 1024/2048)、poll(链表,无连接上限)、epoll(哈希表,无连接上限,事件回调);
    • 优点:单线程处理多连接,节省系统资源;
    • 缺点:连接数少时效率低于多线程 + 阻塞 I/O,需两次系统调用;
    • 适用场景:多连接、多协议、多服务的服务器场景(Nginx 核心模型)。
1.4.3 select/poll/epoll 对比
特性 select poll epoll
操作方式 线性遍历 线性遍历 事件回调
底层实现 数组 链表 哈希表
IO 效率 O(n) O(n) O(1)
最大连接数 1024(x86)/2048(x64) 无上限 无上限
IO 拷贝 每次调用均从用户态拷贝至内核态 每次调用均从用户态拷贝至内核态 仅 epoll_ctl 时拷贝,epoll_wait 不拷贝

1.5 零拷贝

1.5.1 传统 Linux I/O 问题

标准 I/O 接口(read/write)基于数据拷贝,需经过用户态 - 内核态多次切换,数据拷贝耗时占比达 57.1%,严重消耗 CPU,降低传输性能。

1.5.2 零拷贝核心思想

并非真正 "0 拷贝",而是通过减少用户态与内核态之间的拷贝、降低上下文切换,缓解 CPU 压力,核心技术为 MMAP 和 SENDFILE。

1.5.3 核心零拷贝技术
  1. MMAP(内存映射) :将磁盘文件映射至进程虚拟地址空间,进程可直接访问内核缓冲区(page cache),减少一次内核态到用户态的拷贝,适合大量数据传输;
  2. SENDFILE :数据直接在内核缓冲区与 socket 缓冲区之间传输,全程不经过用户态,彻底消除用户态 - 内核态的拷贝,适合静态文件传输(Nginx 默认启用)。

二、Nginx 架构和安装

2.1 Nginx 概述

  1. 命名:engine X,轻量级高性能服务器,分为社区版 (开源免费)和商业版(Nginx Plus)
  2. 二次发行版:
    • Tengine:淘宝发起,基于 Nginx 添加高级功能,适用于大访问量网站;
    • OpenResty:章亦春团队开发,基于 Nginx+Lua,高性能 Web 平台,支持超高并发;
  3. 核心定位:HTTP/HTTPS 服务器、反向代理、TCP/UDP 代理、邮件代理,解决 C10K 问题。

2.2 Nginx 核心功能

  1. 静态资源服务:高效处理 HTML、图片、JS、CSS 等静态文件;
  2. 反向代理:支持 HTTP/HTTPS、TCP/UDP、FastCGI/uWSGI/SCGI、imap4/pop3 等协议;
  3. 基础特性:模块化设计、高可靠性、热部署、低内存消耗、事件驱动(epoll)+AIO+MMAP+SENDFILE;
  4. Web 相关功能:虚拟主机、keep-alive、访问日志、URL 重写、IP / 用户访问控制、速率 / 并发限制、在线升级。

2.3 Nginx 进程架构

Nginx 采用Master-Worker多进程模型,主进程与工作进程分工明确,进程间通过管道、共享内存通信,支持平滑升级和故障重启。

2.3.1 进程结构与功能

进程类型 核心功能
Master(主进程) 读取 / 验证配置、管理 Worker 进程、监控 Worker 状态(异常自动重启)、绑定 / 关闭 socket、接收外部指令(重启 / 升级 / 退出)、实现平滑升级、开启日志文件
Worker(工作进程) 处理实际网络请求、平等竞争新连接、I/O 调用、与后端服务器通信、缓存数据、发送响应结果、接收主进程指令;数量一般等于 CPU 核心数,避免进程竞争 CPU
2.3.2 进程间通信
  1. Master 与 Worker:Master 通过单向管道向 Worker 发送指令,Worker 捕获管道可读事件并执行操作;Master 通过 fork () 生成 Worker,维护工作进程表;
  2. Worker 之间:通过 Master 转发管道信息实现通信,或通过共享内存 (如 upstream zone、limit_req)通信。
2.3.3 Nginx 启动与 HTTP 连接建立
  1. Master 进程加载配置文件,初始化监听 socket;
  2. Master fork 出多个 Worker 进程;
  3. Worker 进程竞争新连接,获胜方通过 TCP 三次握手建立连接,处理请求。

2.4 Nginx 模块体系

Nginx 高度模块化,模块是功能实现的核心,1.9.11 版本开始支持动态装载 / 卸载,模块分为五大类:

模块类型 核心功能 示例
核心模块 Nginx 运行必备,负责基础功能 错误日志、配置解析、事件驱动、进程管理
标准 HTTP 模块 HTTP 协议解析,基础 Web 功能 端口配置、网页编码、HTTP 响应头设置
可选 HTTP 模块 扩展 HTTP 功能,需编译指定 Gzip 压缩、SSL、GeoIP 解析、Flash 传输
邮件服务模块 支持邮件代理协议 POP3、IMAP、SMTP 协议处理
Stream 服务模块 实现 TCP/UDP 反向代理 四层负载均衡、TCP 协议转发
第三方模块 开发者自定义功能 Lua 支持、Json 解析、Rds-json

2.5 Nginx 安装

推荐源码编译安装(可自定义路径、功能,yum 版本较旧),需提前安装依赖库,编译后生成四大核心目录。

2.5.1 编译安装准备
  1. 依赖库:GCC(编译器)、pcre-devel(rewrite 功能)、zlib-devel(gzip 功能)、openssl-devel(SSL 功能)、Automake(自动生成 Makefile);
  2. 源码下载:https://nginx.org/en/download.html
  3. 创建运行用户:useradd -s /sbin/nologin -M nginx
2.5.2 编译安装步骤
复制代码
# 安装依赖
dnf install gcc pcre-devel zlib-devel openssl-devel -y
# 解压源码
tar zxf nginx-1.24.0.tar.gz && cd nginx-1.24.0
# 配置编译参数(自定义路径、功能)
./configure --prefix=/usr/local/nginx \
--user=nginx --group=nginx \
--with-http_ssl_module --with-http_v2_module \
--with-http_realip_module --with-http_stub_status_module \
--with-http_gzip_static_module --with-pcre --with-stream
# 编译并安装
make && make install
2.5.3 核心目录说明
目录 功能
/usr/local/nginx/conf 所有配置文件,核心为 nginx.conf
/usr/local/nginx/html 静态 Web 文件,包含默认错误页面(50x.html)
/usr/local/nginx/logs 访问日志、错误日志、PID 文件
/usr/local/nginx/sbin 二进制启动脚本(nginx),支持多种命令参数
2.5.4 Nginx 常用命令
复制代码
nginx -v # 查看版本
nginx -V # 查看版本+编译参数
nginx -t # 测试配置文件有效性
nginx -s reload # 平滑重载配置
nginx -s quit # 优雅退出
nginx -s stop # 强制停止
nginx -g "worker_processes 6;" # 临时指定全局指令
2.5.5 系统服务配置(systemd)

创建/lib/systemd/system/nginx.service,实现 systemctl 管理:

复制代码
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target

启用服务:systemctl daemon-reload && systemctl enable --now nginx

2.6 Nginx 平滑升级和回滚

无需停机,实现版本升级 / 回滚,核心通过信号控制(SIGUSR2、WINCH、QUIT、HUP),保证业务不中断。

2.6.1 平滑升级流程
  1. 备份旧版 Nginx 二进制文件:cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
  2. 编译新版本源码(仅 make,不 make install),将新二进制文件替换旧文件;
  3. 向旧 Master 进程发送SIGUSR2:旧 Master 重命名 PID 文件为 nginx.pid.oldbin,启动新 Master 进程;
  4. 向旧 Master 发送WINCH:旧 Worker 进程平滑停止,新请求由新 Worker 处理;
  5. 验证升级成功后,向旧 Master 发送QUIT:关闭旧 Master,完成升级。
2.6.2 回滚流程
  1. 将备份的旧版二进制文件替换新版文件;
  2. 向旧 Master(nginx.pid.oldbin)发送HUP:重新拉起旧 Worker 进程;
  3. 向新 Master 发送WINCH:新 Worker 进程平滑停止;
  4. 向新 Master 发送QUIT:关闭新 Master,完成回滚。

三、Nginx 核心配置详解

Nginx 配置文件为纯文本格式 ,采用指令 + 指令块 结构,支持 include 引入子配置、注释(#)、变量($),核心分为四大配置段:main(全局)、event(事件驱动)、http(HTTP/HTTPS)、stream(TCP/UDP),mail(邮件)为可选段。

3.1 配置文件基础规则

  1. 指令以分号; 结尾,指令与值之间用空格分隔;
  2. 指令块以 **{}** 包裹,支持嵌套(如 http 包含 server,server 包含 location);
  3. include 语句:组合多个配置文件,提升可维护性(如include conf.d/*.conf);
  4. 变量:内置变量(模块提供,直接使用)、自定义变量(set $变量名 值;),引用方式为$变量名
  5. 部分指令支持正则表达式,用于 URL 匹配、条件判断。

3.2 全局配置段(main)

对所有配置段生效,核心为 Nginx 运行的基础配置,分为必备配置性能优化配置调试配置三类。

3.2.1 核心配置指令
指令 功能 推荐值
user nginx nginx; 启动 Worker 进程的用户和组 专用 nginx 用户
worker_processes n; Worker 进程数量 等于 CPU 核心数(或 auto)
worker_cpu_affinity 掩码; 将 Worker 进程绑定到指定 CPU 核心 如 4 核心:0001 0010 0100 1000
error_log 路径 级别; 错误日志路径与级别 /usr/local/nginx/logs/error.log error
pid 路径; PID 文件保存路径 /usr/local/nginx/logs/nginx.pid
worker_priority n; Worker 进程优先级 0(范围 - 20~20,值越高优先级越高)
worker_rlimit_nofile n; Worker 进程最大打开文件数 65536(与系统 ulimit -n 一致)
daemon on/off; 是否以守护进程运行 on(生产)/off(测试 / 容器)
master_process on/off; 是否启用 Master-Worker 模型 on(生产)/off(调试)

3.3 事件驱动配置段(event)

仅用于配置事件驱动相关功能,决定 Nginx 与客户端的网络连接方式,是高并发优化的核心配置段。

3.3.1 核心配置指令
指令 功能 推荐值
worker_connections n; 单个 Worker 进程最大并发连接数 65535
use 模型; 事件驱动模型 epoll(Linux)/kqueue(FreeBSD)
accept_mutex on/off; 连接互斥锁,防止惊群效应 on
multi_accept on/off; 单个 Worker 进程是否同时接受多个连接 on
3.3.2 高并发配置要点
  1. 调整系统内核:ulimit -n 65536(临时),修改/etc/security/limits.conf(永久);
  2. 配置worker_rlimit_nofile 65536:突破文件数限制;
  3. 关闭不必要的模块,减少资源占用;
  4. 开启epollaccept_mutexmulti_accept

3.4 HTTP 配置段(http)

处理所有 HTTP/HTTPS 协议相关配置 ,是 Nginx 配置的核心,包含虚拟主机、缓存、代理、日志、压缩等功能,可嵌套多个server指令块(虚拟主机)。

3.4.1 核心基础配置指令
指令 功能 推荐值
include mime.types; 引入 MIME 类型映射文件 必加
default_type 类型; 未匹配 MIME 类型的默认文件类型 application/octet-stream(下载)/text/html
sendfile on/off; 启用零拷贝 SENDFILE 技术 on
keepalive_timeout n [m]; keep-alive 长连接超时时间 65 60(服务器 65s,告知客户端 60s)
keepalive_requests n; 单条长连接最大请求数 500(默认 100)
log_format 名称 格式; 定义访问日志格式 包含、request、$status 等
access_log 路径 格式; 访问日志路径与格式 /usr/local/nginx/logs/access.log main

3.5 虚拟主机配置段(server)

属于http子配置段,一个http可包含多个server,每个server对应一个虚拟主机 ,通过listen(端口)、server_name(域名 / IP)区分,核心用于部署多站点。

3.5.1 核心配置指令
复制代码
server {
    listen 80; # 监听端口(可加IP,如192.168.1.100:80)
    server_name lee.timinglee.org www.timinglee.org; # 虚拟主机域名,支持多个、通配符、正则
    root /webdata/nginx/timinglee.org/html; # 站点根目录
    index index.html index.htm index.php; # 默认首页文件
    error_page 404 500 502 /error.html; # 自定义错误页面
    access_log /var/log/nginx/timinglee.access.log main; # 独立访问日志
}

3.6 路径匹配配置段(location)

属于server子配置段,一个server可包含多个location,根据用户请求的 URI进行匹配,实现路径映射、访问控制、反向代理等功能,是 Nginx 配置最灵活的部分。

3.6.1 location 匹配语法与优先级

语法:location [ = | ~ | ~* | ^~ ] uri { ... }匹配优先级从高到低=(精确匹配) > ^~(前缀匹配,终止正则) > ~(正则,区分大小写)/~*(正则,不区分大小写) > 普通前缀匹配(无符号)

修饰符 功能 示例
= 精确匹配 URI,匹配成功立即停止 location = /logo.png { ... }
^~ 前缀匹配,匹配成功后终止后续正则匹配 location ^~ /static/ { ... }
~ 正则匹配,区分大小写 location ~ .php$ { ... }
~* 正则匹配,不区分大小写 location ~* .(jpg png gif)$ { ... }
普通前缀匹配,按匹配度最高匹配 location /web/ { ... }
3.6.2 root 与 alias(路径映射)

均用于指定文件路径,核心区别:

  1. rootroot 路径,文件绝对路径 = root 路径 + location URI(默认方式);示例:location /dirtest { root /mnt; } → 访问/dirtest对应/mnt/dirtest
  2. aliasalias 路径,直接替换 location URI 为指定路径,仅适用于 location;示例:location /alias { alias /mnt/dirtest; } → 访问/alias对应/mnt/dirtest

3.7 核心配置实战案例

3.7.1 多虚拟主机配置

基于域名部署两个站点,通过 include 引入子配置:

复制代码
# 创建子配置目录
mkdir /usr/local/nginx/conf.d
# 主配置文件引入子配置
echo 'include conf.d/*.conf;' >> /usr/local/nginx/conf/nginx.conf
# 创建站点配置文件
vim /usr/local/nginx/conf.d/lee.conf
server {
    listen 80;
    server_name lee.timinglee.org;
    root /webdata/nginx/lee/html;
    index index.html;
}
vim /usr/local/nginx/conf.d/www.conf
server {
    listen 80;
    server_name www.timinglee.org;
    root /webdata/nginx/www/html;
    index index.html;
}
3.7.2 自定义错误页面
复制代码
server {
    listen 80;
    server_name lee.timinglee.org;
    root /webdata/nginx/lee/html;
    error_page 404 /404.html; # 404错误指向404.html
    error_page 500 502 503 504 /50x.html; # 服务器错误指向50x.html
    # 错误页面独立路径
    location = /404.html {
        root /webdata/nginx/lee/errors;
    }
    location = /50x.html {
        root /webdata/nginx/lee/errors;
    }
}
3.7.3 文件存在检测(try_files)

按顺序检查文件 / 目录是否存在,返回第一个存在的,否则重定向至最后一个参数:

复制代码
server {
    listen 80;
    server_name lee.timinglee.org;
    root /webdata/nginx/lee/html;
    # 检查$uri → $uri.html → $uri/index.html,均不存在则指向/error/default.html
    try_files $uri $uri.html $uri/index.html /error/default.html;
}
3.7.4 下载服务器配置(autoindex)

启用自动目录索引,支持文件下载,可限速、显示文件信息:

复制代码
server {
    listen 80;
    server_name lee.timinglee.org;
    root /webdata/nginx/lee;
    location /download {
        autoindex on; # 启用自动索引
        autoindex_exact_size off; # 显示文件近似大小(K/M/G)
        autoindex_localtime on; # 显示服务器本地时间
        limit_rate 1024k; # 限速1MB/s
    }
}
3.7.5 账户认证(auth_basic)

基于ngx_http_auth_basic_module实现 HTTP 基本认证,需生成密码文件:

复制代码
# 安装htpasswd,生成密码文件
yum install httpd-tools -y
htpasswd -cmb /usr/local/nginx/conf/.htpasswd admin 123456

location /admin {
    root /webdata/nginx/lee/html;
    auth_basic "Admin Login"; # 认证提示语
    auth_basic_user_file /usr/local/nginx/conf/.htpasswd; # 密码文件路径
}

四、Nginx 高级配置

4.1 Nginx 状态页(stub_status)

基于ngx_http_stub_status_module实现,查看 Nginx 运行状态(需编译时添加--with-http_stub_status_module),显示全局状态,非单个虚拟主机。

4.1.1 配置示例
复制代码
location /nginx_status {
    stub_status; # 启用状态页
    auth_basic "Nginx Status"; # 认证保护
    auth_basic_user_file /usr/local/nginx/conf/.htpasswd;
    allow 192.168.1.0/24; # 允许指定IP段访问
    allow 127.0.0.1;
    deny all; # 拒绝其他IP
}
4.1.2 状态页核心指标
复制代码
Active connections: 291 # 当前活动连接数(Reading+Writing+Waiting)
server accepts handled requests
 16630948 16630948 31070465 # 接受连接数/处理连接数/总请求数
Reading: 6 Writing: 179 Waiting: 106 # 读取请求/发送响应/空闲等待连接数
  • Waiting :开启 keep-alive 时的空闲连接数,Waiting = Active - (Reading+Writing)
  • handled :一般等于 accepts,除非因worker_connections限制被拒绝。

4.2 Nginx 压缩功能(gzip)

基于ngx_http_gzip_module实现,对指定类型文件压缩后传输,降低带宽消耗(需消耗少量 CPU),默认内置模块,无需额外编译。

4.2.1 核心配置指令
复制代码
http {
    gzip on; # 启用gzip压缩
    gzip_comp_level 5; # 压缩级别1-9,5为平衡值(值越高压缩比越高,CPU消耗越大)
    gzip_min_length 1k; # 最小压缩文件大小,小于1k不压缩
    gzip_types text/plain text/html text/css application/javascript application/json image/png; # 压缩的文件类型
    gzip_vary on; # 响应头添加Vary: Accept-Encoding,告知浏览器支持压缩
    gzip_disable "MSIE [1-6]\."; # 禁用IE6及以下压缩(不支持)
    gzip_static on; # 启用预压缩(直接使用.gz文件,无需实时压缩)
}
4.2.2 验证压缩

使用 curl 命令验证,响应头包含Content-Encoding: gzip即为压缩成功:

复制代码
curl --head --compressed http://lee.timinglee.org/data.txt

4.3 Nginx 版本隐藏

隐藏响应头中的 Nginx 版本号,提升安全性,需修改源码重新编译

复制代码
# 编辑源码头文件
vim nginx-1.26.1/src/core/nginx.h
# 修改版本号
#define NGINX_VERSION "1.0"
# 可选:修改服务器标识
#define NGINX_VER "HAHA/" NGINX_VERSION
# 重新编译安装
make && make install

4.4 Nginx 变量使用

Nginx 变量分为内置变量 (模块提供,获取请求 / 服务器信息)和自定义变量 (用户定义,set指令),用于配置判断、日志、URL 重写等场景。

4.4.1 常用内置变量
变量 功能
$remote_addr 客户端 IP 地址
$request_uri 包含参数的完整 URI(如 /var?id=1)
$document_uri 不包含参数的 URI(如 /var)
$host 客户端请求的主机名
$server_name 虚拟主机名
$server_port 监听端口
$http_user_agent 客户端浏览器信息
$args URL 中的所有参数
$scheme 请求协议(http/https)
4.4.2 自定义变量

通过set $变量名 值;定义,支持拼接内置变量:

复制代码
location /var {
    default_type text/html;
    set $name lee; # 自定义变量
    set $web_addr $scheme://$host:$server_port; # 拼接内置变量
    echo $name; # 输出变量(需ngx_http_echo_module)
    echo $web_addr;
}

4.5 Nginx Rewrite 功能

基于ngx_http_rewrite_module实现,通过正则表达式 匹配 URI 并修改,支持 URL 重定向、地址伪装、防盗链等,核心依赖 PCRE 库(编译时需--with-pcre)。

4.5.1 核心指令
  1. if 指令 :条件判断,支持正则匹配、文件检测,不支持 else/elif;示例:if ($scheme = http) { rewrite ^(.*)$ https://$host$1 permanent; }
  2. set 指令:定义变量,用于条件判断和 Rewrite;
  3. break 指令:中断当前 location 的后续 Rewrite 规则,继续执行其他指令;
  4. return 指令 :直接返回响应状态码 / 重定向,后续指令全部不执行;示例:return 301 http://www.baidu.com;(永久重定向)、return 403 "Forbidden";(禁止访问);
  5. rewrite 指令 :核心 Rewrite 指令,语法:rewrite regex replacement [flag];
4.5.2 Rewrite Flag(标志位)

控制 Rewrite 的循环机制,分为跳转型 (客户端重定向)和代理型(服务器内部跳转):

Flag 类型 功能
redirect 跳转型 临时重定向(302),客户端重新发起请求,适用于临时调整
permanent 跳转型 永久重定向(301),客户端缓存重定向记录,适用于永久域名变更
break 代理型 停止当前 location 的后续 Rewrite,直接执行后续配置,结束循环
last 代理型 停止当前 location 的后续 Rewrite,对新 URI 启动新一轮 Rewrite 检查
4.5.3 Rewrite 实战案例
  1. 域名永久重定向 :将lee.timinglee.org永久重定向至www.timinglee.org

    复制代码
    server {
        listen 80;
        server_name lee.timinglee.org;
        rewrite ^(.*)$ http://www.timinglee.org$1 permanent;
    }
  2. HTTP 自动跳转 HTTPS :全站强制 HTTPS,避免死循环(添加 $scheme 判断):

    复制代码
    server {
        listen 80;
        listen 443 ssl;
        server_name www.timinglee.org;
        ssl_certificate /usr/local/nginx/certs/cert.pem;
        ssl_certificate_key /usr/local/nginx/certs/key.pem;
        if ($scheme = http) {
            rewrite ^(.*)$ https://$host$1 redirect;
        }
        root /webdata/nginx/www/html;
    }
  3. 文件不存在重定向首页 :访问不存在的 URL 时,重定向至网站首页:

    复制代码
    server {
        listen 80;
        server_name www.timinglee.org;
        root /webdata/nginx/www/html;
        if (!-e $request_filename) {
            rewrite .* /index.html redirect;
        }
    }

4.6 Nginx 防盗链

基于ngx_http_referer_module实现,通过检查请求头的Referer 字段(记录请求来源),阻止其他网站直接链接本站资源(图片、视频、文件等)。

4.6.1 Referer 有效值
类型 功能
none 无 Referer(用户直接输入域名访问)
blocked Referer 无有效值(如为空)
server_names Referer 包含本站域名($server_name)
通配符 自定义域名,如 *.timinglee.org
正则 正则匹配 Referer,如~/.baidu/(允许百度搜索)
4.6.2 防盗链配置示例
复制代码
server {
    listen 80;
    server_name www.timinglee.org;
    root /webdata/nginx/www/html;
    # 对图片资源防盗链
    location ~* \.(jpg|png|gif|jpeg)$ {
        # 允许的Referer
        valid_referers none blocked server_names *.timinglee.org ~/.baidu/ ~/.google/;
        # 无效Referer返回404或重定向至防盗链图片
        if ($invalid_referer) {
            # return 404;
            rewrite ^/ http://www.timinglee.org/daolian.png permanent;
        }
    }
}

五、Nginx 反向代理功能

反向代理是 Nginx 的核心功能之一,指代理服务器接收客户端请求,转发至后端服务器处理,将结果返回给客户端,代表服务端利益,与正向代理(代表客户端利益,如翻墙)本质区别。

Nginx 支持七层反向代理 (HTTP/HTTPS,基于ngx_http_proxy_module)和四层反向代理 (TCP/UDP,基于ngx_stream_proxy_module,1.9 + 支持),同时支持负载均衡、缓存、会话保持。

5.1 核心概念

  1. 同构代理:客户端请求通过 HTTP/TCP 协议直接转发至后端同类服务器(如 Nginx→Apache);
  2. 异构代理:客户端请求通过专用协议转发至后端应用服务器(如 Nginx→PHP-FPM,FastCGI 协议);
  3. 负载均衡:将客户端请求均匀分发至多个后端服务器,提升并发能力、实现故障转移;
  4. 动静分离:静态资源(HTML、图片、JS)由 Nginx 直接返回,动态资源(PHP、Java)转发至后端应用服务器,提升整体性能。

5.2 七层反向代理(HTTP/HTTPS)

基于ngx_http_proxy_module实现,核心指令为proxy_pass,支持配置代理参数、缓存、会话保持。

同构代理:用户不需要其他程序的参与,直接通过http协议或者tcp协议访问后端服务器

异构代理:用户访问的资源时需要经过处理后才能返回的,比如php,Python,等等,这种访问资源需 要经过处理才能被访问

5.2.1 核心代理指令
指令 功能
proxy_pass 地址; 核心指令,转发请求至后端服务器(IP: 端口 / 域名 /upstream 组)
proxy_set_header 头名 值; 修改 / 添加请求头,转发至后端服务器
proxy_connect_timeout n; Nginx 与后端服务器的连接超时时间
proxy_read_timeout n; Nginx 等待后端服务器响应的超时时间
proxy_hide_header 头名; 隐藏后端服务器的响应头,不返回给客户端
proxy_pass_header 头名; 透传后端服务器的响应头,返回给客户端
5.2.2 关键配置:proxy_pass 末尾 / 的影响

proxy_pass末尾是否加 **/**,决定 URI 的转发规则,核心区别:

  1. 不加 / :将 location 的 URI 拼接至后端地址后;示例:location /web { proxy_pass http://172.25.254.30:8080; } → 访问/web/index.html转发至http://172.25.254.30:8080/web/index.html
  2. 加 / :将 location 的 URI 替换为后端地址的 /,不拼接;示例:location /web { proxy_pass http://172.25.254.30:8080/; } → 访问/web/index.html转发至http://172.25.254.30:8080/index.html
5.2.3 客户端真实 IP 透传

Nginx 作为反向代理时,后端服务器获取的 IP 为 Nginx 的 IP,需通过proxy_set_header透传客户端真实 IP:

复制代码
location / {
    proxy_pass http://172.25.254.30;
    # 透传客户端真实IP
    proxy_set_header X-Forwarded-For $remote_addr;
    # 透传请求主机名
    proxy_set_header Host $host;
    # 透传请求协议
    proxy_set_header X-Forwarded-Proto $scheme;
}

后端服务器需配置日志格式,记录X-Forwarded-For字段。

5.2.4 反向代理缓存

启用代理缓存,将后端服务器的响应结果缓存至 Nginx 本地,减少后端请求,提升响应速度,核心指令为proxy_cache

5.2.4.1 核心缓存指令
复制代码
http {
    # 定义缓存池,配置在http段
    proxy_cache_path /var/cache/nginx/proxy_cache \
    levels=1:2:2 \ # 缓存目录层次
    keys_zone=proxycache:20m \ # 内存缓存区(20M,存放key和元数据)
    inactive=120s \ # 缓存非活动时间,超时清理
    max_size=10g; # 缓存最大磁盘占用
    server {
        listen 80;
        server_name www.timinglee.org;
        location / {
            proxy_pass http://172.25.254.30;
            proxy_cache proxycache; # 启用缓存池
            proxy_cache_key $request_uri; # 缓存key(基于URI)
            proxy_cache_valid 200 302 10m; # 200/302状态码缓存10分钟
            proxy_cache_valid 404 1m; # 404状态码缓存1分钟
            proxy_cache_valid any 1m; # 其他状态码缓存1分钟
            proxy_cache_use_stale error http_502 http_503; # 后端错误时使用过期缓存
        }
    }
}

5.3 七层负载均衡(http_upstream)

基于ngx_http_upstream_module实现,通过upstream指令定义后端服务器组,实现请求分发,支持多种调度算法后端服务器状态管理,是高可用架构的核心。

5.3.1 upstream 核心配置
复制代码
http {
    # 定义后端服务器组,名称为webserver
    upstream webserver {
        server 172.25.254.20:80 weight=2; # 权重2,优先级更高
        server 172.25.254.30:80 weight=1; # 权重1
        server 172.25.254.40:80 backup; # 备份服务器,主服务器不可用时启用
        server 172.25.254.50:80 down; # 标记为下线,平滑移除
    }
    server {
        listen 80;
        server_name www.timinglee.org;
        # 转发至upstream组
        location / {
            proxy_pass http://webserver;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    }
}
5.3.2 后端服务器参数
参数 功能
weight=n 调度权重,默认为 1,值越高被调度的概率越大
max_fails=n 连续失败 n 次后,标记服务器为不可用
fail_timeout=n 服务器不可用后,每隔 n 秒检测一次,恢复后重新加入调度
backup 备份服务器,所有主服务器不可用时启用
down 标记服务器为下线,不参与调度
max_conns=n 服务器最大并发连接数,默认为 0(无限制)
5.3.3 调度算法

Nginx 内置多种调度算法,适用于不同场景:

算法 原理 适用场景
轮询(默认) 按顺序依次分发请求至后端服务器 后端服务器配置一致
加权轮询 按权重分发,权重越高分发越多 后端服务器配置不一致(性能差异)
ip_hash 基于客户端 IP 哈希,固定 IP 转发至固定服务器 需会话保持的场景(如登录状态)
least_conn 分发至当前并发连接数最少的服务器 后端服务器请求处理时间差异大
hash $key 基于自定义 key 哈希(如、cookie) 缓存服务器、需按 URL/COOKIE 会话保持
fair 基于后端服务器响应时间分发,响应越快优先级越高 第三方模块,需单独编译

5.4 四层反向代理(TCP/UDP)

基于ngx_stream_proxy_module实现(编译时需--with-stream),工作在TCP/IP 四层协议栈,不解析应用层协议,支持 TCP/UDP 协议的负载均衡,适用于 MySQL、Redis、DNS 等非 HTTP 服务。

5.4.1 TCP 负载均衡(以 MySQL 为例)
复制代码
# 四层配置段,与http同级
stream {
    # 定义MySQL后端服务器组
    upstream mysql_server {
        server 172.25.254.20:3306 max_fails=3 fail_timeout=30s;
        server 172.25.254.30:3306 max_fails=3 fail_timeout=30s;
    }
    # 监听TCP 3306端口,转发至MySQL组
    server {
        listen 172.25.254.10:3306 tcp;
        proxy_pass mysql_server;
        proxy_connect_timeout 30s; # 连接超时
        proxy_timeout 300s; # 转发超时
    }
}
5.4.2 UDP 负载均衡(以 DNS 为例)
复制代码
stream {
    # 定义DNS后端服务器组
    upstream dns_server {
        server 172.25.254.20:53;
        server 172.25.254.30:53;
    }
    # 监听UDP 53端口,转发至DNS组
    server {
        listen 172.25.254.10:53 udp;
        proxy_pass dns_server;
        proxy_timeout 1s;
        proxy_responses 1; # UDP协议,响应1个报文后终止会话
    }
}

六、Nginx 与 FastCGI 集成(LNMP 架构)

LNMP(Linux+Nginx+MySQL+PHP)是主流的动态网站架构,Nginx 不支持直接运行 PHP,需通过FastCGI 协议 将 PHP 请求转发至PHP-FPM(FastCGI 进程管理器)处理,实现动态资源解析。

6.1 核心概念

  1. CGI:通用网关接口,Web 服务器与外部应用程序的通信标准,每请求创建一个进程,效率低;
  2. FastCGI :CGI 的升级版,采用长连接,进程处理完请求后不销毁,可重复使用,大幅提升效率;
  3. PHP-FPM:FastCGI 的 PHP 实现,负责管理 PHP 进程(Master+Worker),监听端口接收 Nginx 的 FastCGI 请求;
  4. LNMP 工作流程:客户端→Nginx(处理静态资源)→FastCGI→PHP-FPM(处理 PHP 代码)→MySQL(获取数据)→Nginx→客户端。

6.2 核心配置指令(ngx_http_fastcgi_module)

Nginx 通过fastcgi_pass指令转发 PHP 请求至 PHP-FPM,核心指令如下:

指令 功能
fastcgi_pass 地址; 转发 PHP 请求至 PHP-FPM(127.0.0.1:9000 / 本地套接字)
fastcgi_index index.php; PHP 默认首页文件
fastcgi_param 键 值; 设置 FastCGI 参数,传递给 PHP-FPM
include fastcgi_params; 引入 FastCGI 默认参数文件(必加)

6.3 LNMP 架构实战配置

6.3.1 PHP-FPM 配置

PHP-FPM 默认监听127.0.0.1:9000,需确保配置正确,启动 PHP-FPM 服务。

6.3.2 Nginx 配置
复制代码
server {
    listen 80;
    server_name php.timinglee.org;
    root /webdata/nginx/php/html; # PHP站点根目录
    index index.html index.php; # 支持PHP首页
    # 匹配所有.php文件,转发至PHP-FPM
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000; # PHP-FPM监听地址
        fastcgi_index index.php;
        # 定义PHP脚本文件路径,必须正确
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params; # 引入默认参数
    }
    # 处理静态资源,Nginx直接返回
    location ~ \.(jpg|png|gif|css|js)$ {
        expires 30d; # 浏览器缓存30天
    }
}
6.3.3 测试 PHP 解析

在 PHP 站点根目录创建info.php,访问测试 PHP 是否解析成功:

复制代码
<?php
phpinfo();
?>

访问http://php.timinglee.org/info.php,显示 PHP 信息页面即为配置成功。

6.4 PHP 性能优化:缓存模块

为 PHP 添加内存缓存(如 Memcache、Redis),减少数据库请求,提升 PHP 处理效率,以 Memcache 为例:

  1. 安装 PHP Memcache 扩展;
  2. 部署 Memcached 服务;
  3. Nginx 配置缓存转发,PHP 代码调用 Memcache。

七、Nginx 二次开发版本

7.1 OpenResty

7.1.1 基础介绍

OpenResty 是由章亦春团队 开发的高性能 Web 平台,基于Nginx+LuaJIT实现,将 Lua 虚拟机嵌入 Nginx,支持通过 Lua 脚本扩展 Nginx 功能,无需修改 Nginx 源码。

核心优势:

  • 超高并发:支持 10K~1000K 单机并发连接;
  • 灵活扩展:通过 Lua 脚本快速实现自定义功能(如限流、鉴权、缓存);
  • 丰富生态:内置大量 Lua 库和第三方模块,无需单独编译;
  • 低延迟:LuaJIT 即时编译,性能接近 C 语言。

官网:http://openresty.org/cn/

7.1.2 编译安装 OpenResty
复制代码
# 安装依赖
dnf install gcc pcre-devel openssl-devel perl -y
# 创建运行用户
useradd -r -s /sbin/nologin nginx
# 下载源码并解压
wget https://openresty.org/download/openresty-1.17.8.2.tar.gz
tar xf openresty-1.17.8.2.tar.gz && cd openresty-1.17.8.2
# 配置编译参数
./configure --prefix=/apps/openresty \
--user=nginx --group=nginx \
--with-http_ssl_module --with-http_v2_module \
--with-http_realip_module --with-http_stub_status_module
# 编译并安装
make && make install
# 配置环境变量
ln -s /apps/openresty/bin/* /usr/bin/
# 启动服务
openresty

7.2 Tengine

淘宝网 发起的 Nginx 二次开发版本,基于 Nginx 添加了大量高级功能(如动态模块、请求过滤、性能监控),专门针对大访问量网站优化,稳定性和性能经过淘宝、天猫等生产环境验证,开源免费。

官网:http://tengine.taobao.org/

相关推荐
国产化创客1 小时前
ESP32平台嵌入式Web前端框架选型分析
前端·物联网·前端框架·智能家居
是欢欢啊2 小时前
全新的table组件,vue3+element Plus
前端·javascript·vue.js
liu****2 小时前
5.Linux CGroups 资源控制实战(CPU+内存)超详细教程
linux·运维·服务器·docker
GitCode官方3 小时前
DevUI 组织 2025 年度运营报告:扎根 AtomGit,开源前端再启新程
前端·开源·atomgit
恋猫de小郭10 小时前
Flutter 正在计划提供 Packaged AI Assets 的支持,让你的包/插件可以更好被 AI 理解和选择
android·前端·flutter
小小前端--可笑可笑10 小时前
Vue / React 单页应用刷新 /login 无法访问问题分析
运维·前端·javascript·vue.js·nginx·react.js
小林敲代码778811 小时前
记一次 Vue 项目首屏优化:从 7.1s 到 0.9s,深挖 Gzip 的力量
前端·javascript·vue.js
前端大卫11 小时前
写给年轻程序员的几点小建议
前端
IP搭子来一个11 小时前
2026年动态IP代理怎么选:共享好还是独享好?
服务器·网络协议·tcp/ip