文章目录
- [一、Nginx 简介与特性](#一、Nginx 简介与特性)
-
- [1.1 Nginx 简介](#1.1 Nginx 简介)
- [1.2 架构与工作原理](#1.2 架构与工作原理)
- 二、安装与基本使用
- 三、核心配置指令详解
-
- 3.1全局块指令
- [3.2 events 块指令](#3.2 events 块指令)
- [3.3 http 块常用指令](#3.3 http 块常用指令)
- [3.4 server 块指令](#3.4 server 块指令)
- [3.5 location 块与匹配规则](#3.5 location 块与匹配规则)
- 四、反向代理与负载均衡配置
- 五、静态文件服务与缓存
- [六、SSL/TLS 配置](#六、SSL/TLS 配置)
- 七、日志与内置变量
- 八、常见优化参数
- 九、完整配置示例
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/Debian :
sudo apt install nginxCentOS/RHEL :
sudo yum install nginx或sudo 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:添加自定义响应头。
sendfile和tcp_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;
}
}
}