Nginx 从入门到精通:配置、原理与实战详解

文章目录

Nginx(engine x)是一款高性能的 HTTP 和反向代理服务器,同时也支持 IMAP/POP3/SMTP 代理。凭借其高并发、低资源消耗和灵活的配置,Nginx 已成为现代 Web 架构中不可或缺的组件。本文将从基础概念讲起,逐步深入配置原理和高级用法,帮助你全面掌握 Nginx。

一、Nginx 简介与特性

1.1 Nginx 简介

Nginx 由俄罗斯程序员 Igor Sysoev 开发,其设计目标是解决 C10K 问题(同时处理上万个并发连接)。与传统的 Apache 相比,Nginx 采用了事件驱动和异步非阻塞的架构,使得它在高并发场景下性能卓越,内存占用更低。

主要特性

高并发 :单个 worker 进程可处理数万并发连接。

低内存消耗 :每个连接仅占用约 2.5KB 内存。

模块化设计 :核心模块 + 可扩展的第三方模块。

反向代理与负载均衡 :内置强大的代理和负载均衡能力。

静态文件服务 :高效处理静态文件,支持 sendfile 和缓存。

SSL/TLS 支持 :可作为 HTTPS 终端,支持 HTTP/2。

热部署 :支持平滑升级,不中断服务。

丰富的功能:支持 WebSocket、gRPC、流媒体等。

1.2 架构与工作原理

Master-Worker 进程模型

Nginx 启动后会包含两类进程:

  • master 进程:负责读取和解析配置文件、管理 worker 进程的创建和销毁、处理信号(如 reload、stop)。
  • worker 进程:实际处理客户端请求。每个 worker 是独立的单进程,互不影响。
    通过 worker_processes 指令设置 worker 数量,通常设为 CPU 核心数或 auto。

事件驱动与非阻塞 I/O

Nginx 使用 epoll (Linux)或 kqueue(FreeBSD)等事件模型。worker 进程在一个事件循环中同时监听多个连接的事件(如可读、可写),避免了为每个连接创建线程或进程的开销。
当请求到达时,worker 将其加入事件队列;若处理过程中需要等待 I/O(如读取磁盘、访问后端),则注册回调后继续处理其他事件;当 I/O 完成后,事件被触发,worker 继续处理该请求。
这种设计使得 Nginx 能够以极少的资源支撑极高的并发。

反向代理与负载均衡原理

反向代理 :客户端请求先到达 Nginx,Nginx 根据配置将请求转发给后端应用服务器(如 Django、Tomcat),并将响应返回给客户端。客户端只与 Nginx 通信,后端结构被隐藏。

负载均衡:Nginx 通过 upstream 定义后端服务器组,根据预设算法(轮询、IP 哈希、最少连接等)将请求分发到不同的后端服务器,实现横向扩展和高可用。

二、安装与基本使用

安装方法

源码编译安装(适合定制模块)

bash 复制代码
# 安装依赖(以 CentOS 为例)
yum install -y gcc pcre-devel zlib-devel openssl-devel

# 下载源码并解压
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0

# 配置(可添加模块)
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module
make
make install

包管理器安装(简单快捷)

Ubuntu/Debiansudo apt install nginx

CentOS/RHELsudo yum install nginxsudo dnf install nginx
安装后配置文件通常位于 /etc/nginx/nginx.conf,二进制文件为 /usr/sbin/nginx

启动、停止与重载

bash 复制代码
nginx                  # 启动(若已启动会报错)
nginx -s stop          # 快速停止(立即终止)
nginx -s quit          # 优雅停止(等待请求处理完成后退出)
nginx -s reload        # 重载配置文件(不中断服务)
nginx -t               # 测试配置文件语法是否正确
nginx -V               # 查看版本和编译参数

配置文件结构

默认配置文件路径:/etc/nginx/nginx.conf/usr/local/nginx/conf/nginx.conf
Nginx 配置文件采用块(block) 结构,层级如下:

bash 复制代码
# 全局块
user  nginx;
worker_processes  auto;

# events 块
events {
    worker_connections  1024;
}

# http 块
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile      on;
    keepalive_timeout  65;

    # server 块(虚拟主机)
    server {
        listen       80;
        server_name  example.com;

        # location 块
        location / {
            root   /var/www/html;
            index  index.html index.htm;
        }
    }
}

全局块 :影响 Nginx 整体运行的配置,如运行用户、进程数、日志路径等。

events 块 :配置网络连接处理方式,如最大连接数、事件模型。

http 块 :HTTP 服务器相关配置,可包含多个 server 块。

server 块 :定义虚拟主机,监听端口和域名。

location 块:根据请求 URI 匹配不同的处理规则。

三、核心配置指令详解

3.1全局块指令

指令 语法 默认值 说明
user user username groupname; nobody 定义 worker 进程运行的用户和组,建议使用非特权用户。
worker_processes worker_processes number | auto; 1 worker 进程数量,建议设为 CPU 核心数或 auto。
error_log error_log file level; logs/error.log error 错误日志文件路径和级别(debug/info/notice/warn/error/crit)。
pid pid file; logs/nginx.pid 存储 master 进程 PID 的文件路径。
worker_rlimit_nofile worker_rlimit_nofile number; 系统限制 每个 worker 进程能打开的最大文件描述符数,应大于 worker_connections。
bash 复制代码
user www-data;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;
worker_rlimit_nofile 65535;

3.2 events 块指令

指令 语法 默认值 说明
use use method; 自动选择 指定事件处理方法,如 epoll、kqueue、select 等,通常无需设置。
worker_connections worker_connections number; 512 每个 worker 进程能同时处理的最大连接数。
multi_accept multi_accept on | off; off 是否一次接受多个新连接,开启可提高吞吐量。
bash 复制代码
events {
    worker_connections 4096;
    multi_accept on;
}

3.3 http 块常用指令

基础设置

指令 语法 默认值 说明
include include file; --- 包含其他配置文件,如 mime.types。
default_type default_type mime-type; text/plain 无法识别文件类型时使用的默认 MIME 类型。
server_tokens server_tokens on | off; on 是否在响应头中显示 Nginx 版本号,建议关闭。
sendfile sendfile on | off; off 使用 sendfile() 系统调用发送文件,提升静态文件性能。
tcp_nopush tcp_nopush on | off; off 仅在 sendfile on 时有效,减少网络包数量。
tcp_nodelay tcp_nodelay on | off; on 禁用 Nagle 算法,适用于需要实时性的连接。
keepalive_timeout keepalive_timeout timeout header_timeout; 75s 客户端保持连接的超时时间。
client_max_body_size client_max_body_size size; 1m 客户端请求体最大大小,常用于限制上传文件大小。
gzip gzip on | off; off 开启 gzip 压缩。
gzip_types gzip_types mime-type ...; text/html 指定需要压缩的 MIME 类型。
bash 复制代码
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile      on;
    tcp_nopush    on;
    keepalive_timeout  65;
    client_max_body_size 20m;
    gzip  on;
    gzip_types text/plain text/css application/json application/javascript;
}

日志配置

指令 语法 默认值 说明
log_format log_format name format ...; combined 定义日志格式,可自定义变量组合。
access_log access_log path format \[buffer=size]; logs/access.log combined 访问日志路径和格式,access_log off; 可关闭。
bash 复制代码
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;

MIME 类型

使用 include mime.types; 加载文件扩展名与 MIME 类型的映射表,该文件通常位于 Nginx 安装目录的 conf/mime.types。

3.4 server 块指令

指令 语法 默认值 说明
listen listen address:port options; 80 监听地址和端口,支持 ssl、http2 等参数。
server_name server_name name ...; "" 虚拟主机名称,支持精确匹配、通配符、正则。
root root path; html 定义请求的根目录。
index index file ...; index.html 默认索引文件。
error_page error_page code ... =\[response] uri; --- 为指定错误码定义错误页面。
bash 复制代码
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/html;
    index index.html index.php;
    error_page 404 /404.html;
}

3.5 location 块与匹配规则

location 语法

bash 复制代码
location [ = | ~ | ~* | ^~ ] uri { ... }

= :精确匹配,优先级最高。

~ :区分大小写的正则匹配。

~ *:不区分大小写的正则匹配。

^~ :前缀匹配,若匹配成功则不再进行正则匹配。

无修饰符:普通前缀匹配,最长匹配优先。
匹配顺序

首先检查 = 精确匹配。

检查 ^~ 前缀匹配,若匹配则停止搜索。

存储所有普通前缀匹配,选择最长匹配。

按顺序检查正则匹配(~ 或 ~*),若匹配则使用。

若没有正则匹配,则使用第3步的最长前缀匹配。
location 常用指令

指令 语法 说明
proxy_pass proxy_pass URL; 将请求转发给后端服务器(反向代理)。
try_files try_files file ... uri; 按顺序检查文件是否存在,若都不存在则执行最后一个 URI 跳转。
alias alias path; 替换 location 匹配部分为指定路径,与 root 不同。
return return code text; 或 return URL; 返回状态码或重定向。
rewrite rewrite regex replacement flag; 重写 URI,支持 last、break、redirect、permanent 标志。
bash 复制代码
location /static/ {
    alias /var/www/static/;
    expires 30d;
}

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

location /api/ {
    proxy_pass http://backend;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

四、反向代理与负载均衡配置

反向代理基础

bash 复制代码
location / {
    proxy_pass http://127.0.0.1:8000;
    proxy_set_header Host $host;
    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;
}
指令 说明
proxy_pass URL 后端服务器地址,可以是 http://host:port、upstream 组名等。
proxy_set_header field value 设置转发给后端的请求头。
proxy_connect_timeout 与后端建立连接的超时时间(默认 60s)。
proxy_send_timeout 向后端发送请求的超时时间(默认 60s)。
proxy_read_timeout 从后端读取响应的超时时间(默认 60s)。
proxy_buffering 是否开启代理缓冲(默认 on)。
proxy_buffers 缓冲区的数量和大小。
proxy_buffer_size 响应头缓冲区大小。
proxy_redirect 修改后端返回的 Location 头。

负载均衡(upstream)

bash 复制代码
upstream backend {
    server 192.168.1.10:8000 weight=3;
    server 192.168.1.11:8000;
    server 192.168.1.12:8000 backup;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

负载均衡算法

轮询(默认) :按顺序依次分配。

加权轮询 :server ... weight=number; 权重越高分配越多。

IP 哈希 :ip_hash; 根据客户端 IP 分配,同一 IP 始终访问同一后端(会话保持)。

最少连接 :least_conn; 将请求分配给活动连接数最少的服务器。

URL 哈希 :hash $request_uri; 根据 URL 分配,适合缓存场景。

fair(第三方):按响应时间分配。

bash 复制代码
upstream backend {
    least_conn;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
}

后端服务器参数

参数 说明
weight=number 设置权重,默认为 1。
max_fails=number 允许请求失败的最大次数,超过后标记为不可用。
fail_timeout=time 在 max_fails 次失败后,服务器被暂停的时间。
backup 标记为备用服务器,当所有主服务器不可用时才启用。
down 标记服务器为永久不可用。

五、静态文件服务与缓存

静态文件优化

bash 复制代码
location /static/ {
    root /var/www;
    expires 30d;               # 设置缓存过期时间
    add_header Cache-Control "public, max-age=2592000";
    access_log off;            # 关闭日志
    sendfile on;
    tcp_nopush on;
}

expires:设置 Expires 和 Cache-Control 头,浏览器缓存时间。

add_header:添加自定义响应头。

sendfiletcp_nopush 提升文件发送效率。

缓存指令详解

指令 说明
expires modified time; 或 expires epoch | max| off; 设置缓存过期时间,如 30d、24h。
add_header Cache-Control "public, max-age=..."; 手动设置缓存控制。
etag 默认开启,生成 ETag 用于验证缓存。
if_modified_since 支持 If-Modified-Since 请求头。

六、SSL/TLS 配置

基本 HTTPS 配置

bash 复制代码
server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    location / {
        root /var/www/html;
    }
}

SSL 常用指令

指令 说明
ssl_certificate 证书文件路径(PEM 格式)。
ssl_certificate_key 私钥文件路径。
ssl_protocols 允许的 TLS 协议版本。
ssl_ciphers 加密套件列表。
ssl_prefer_server_ciphers 优先使用服务器端加密套件。
ssl_session_cache SSL 会话缓存,可提高重复连接速度。
ssl_session_timeout 会话缓存超时时间。
ssl_stapling 开启 OCSP Stapling。

七、日志与内置变量

常用内置变量

变量 说明
$remote_addr 客户端 IP 地址。
$remote_user 认证用户名。
$time_local 本地时间。
$request 完整请求行(方法 + URI + 协议)。
$status 响应状态码。
$body_bytes_sent 发送给客户端的字节数(不含响应头)。
$http_referer 来源页面 URL。
$http_user_agent 用户浏览器信息。
$http_x_forwarded_for 经过代理时的真实客户端 IP(需配合 proxy_set_header)。
$request_uri 原始请求 URI(含查询字符串)。
$uri 当前 URI(可能被改写,不含查询字符串)。
$host 请求头中的 Host 字段。
$server_name 匹配的 server_name。
$scheme 协议(http 或 https)。
$request_time 请求处理时间(秒)。
$upstream_response_time 后端响应时间(秒)。

日志格式示例

bash 复制代码
log_format json escape=json '{"time":"$time_iso8601",'
                            '"remote_addr":"$remote_addr",'
                            '"request":"$request",'
                            '"status":$status,'
                            '"body_bytes_sent":$body_bytes_sent,'
                            '"http_user_agent":"$http_user_agent",'
                            '"request_time":$request_time}';
access_log /var/log/nginx/access.log json;

八、常见优化参数

连接与超时优化

bash 复制代码
http {
    keepalive_timeout 65;
    keepalive_requests 1000;       # 单个 keep-alive 连接的最大请求数
    client_header_timeout 10s;     # 客户端请求头超时
    client_body_timeout 10s;       # 客户端请求体超时
    send_timeout 10s;              # 发送响应超时
    reset_timedout_connection on;  # 超时后重置连接
}

文件描述符与连接数

bash 复制代码
worker_rlimit_nofile 65535;
events {
    worker_connections 65535;
    use epoll;
    multi_accept on;
}

缓冲区与压缩

bash 复制代码
http {
    client_body_buffer_size 128k;
    client_max_body_size 20m;
    large_client_header_buffers 4 32k;
    gzip on;
    gzip_comp_level 5;             # 压缩级别(1-9),建议 4-6
    gzip_min_length 1000;          # 仅压缩大于此长度的响应
    gzip_types text/plain text/css application/json application/javascript;
    gzip_vary on;                  # 添加 Vary: Accept-Encoding
}

九、完整配置示例

bash 复制代码
user www-data;
worker_processes auto;
worker_rlimit_nofile 65535;

events {
    use epoll;
    worker_connections 65535;
    multi_accept on;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    client_max_body_size 20m;

    gzip on;
    gzip_vary on;
    gzip_min_length 1000;
    gzip_comp_level 5;
    gzip_types text/plain text/css application/json application/javascript;

    upstream app_servers {
        least_conn;
        server 10.0.0.1:8000 weight=5;
        server 10.0.0.2:8000 weight=3;
        server 10.0.0.3:8000 backup;
    }

    server {
        listen 80;
        server_name example.com;
        return 301 https://$host$request_uri;   # 强制跳转 HTTPS
    }

    server {
        listen 443 ssl http2;
        server_name example.com;

        ssl_certificate     /etc/nginx/ssl/example.com.crt;
        ssl_certificate_key /etc/nginx/ssl/example.com.key;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        root /var/www/html;
        index index.html;

        location /static/ {
            alias /var/www/static/;
            expires 30d;
            access_log off;
        }

        location /api/ {
            proxy_pass http://app_servers;
            proxy_set_header Host $host;
            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;
            proxy_connect_timeout 10s;
            proxy_send_timeout 30s;
            proxy_read_timeout 30s;
        }

        location / {
            try_files $uri $uri/ =404;
        }
    }
}
相关推荐
玖石书33 分钟前
WSL2 手动安装 Ubuntu 24.04 到指定磁盘位置
linux·运维·ubuntu·wsl
随便做点啥1 小时前
32卡-64G-910B4-16后端-(Qwen3.8-27B-W8A8)集群部署报告
运维·服务器·经验分享·docker·vllm
2601_962218478 小时前
万象生鲜系统区块链溯源技术帮助生鲜企业搭建食品安全数字化体系
大数据·运维·微服务·云原生·架构
智塑未来8 小时前
中小公司在线文档选型:从协作入口到安全边界
运维·安全
新时代牛马8 小时前
Linux 内核入门地图:架构、源码目录与五大子系统
linux·运维·架构
智购科技无人售货机厂家8 小时前
2026自动售货机制冷系统维护指南:从散热器清洁到压缩机换油的工程实践~YH
运维·redis·物联网·缓存·架构
剑客的茶馆8 小时前
开发者,运维怎样转行FDE?
运维·ai·开发·fde
Julien20048 小时前
控制 SELinux 文件上下文
linux·运维·服务器
众壹新能源科技9 小时前
功率预测误差考核怎么降?从气象源到上报口径的排查清单
运维·人工智能·自动化