写在前面
本文是 Nginx 学习笔记系列的第一篇,介绍 Nginx 的核心概念、安装方式、配置文件结构,以及静态文件托管和虚拟主机配置。基于 Nginx 1.26 稳定版。
一、Nginx 是什么
1.1 定义
Nginx(engine-x)是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。
1
2
3
4
5
6
7
|
核心能力:
- Web 服务器 — 高性能静态文件服务
- 反向代理 — 转发请求到后端应用
- 负载均衡 — 分发流量到多台服务器
- 缓存 — 缓存后端响应,降低负载
- 流媒体 — MP4、FLV 流媒体支持
- 邮件代理 — IMAP/POP3/SMTP 代理(用得少)
|
1.2 为什么选择 Nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
1. 高并发
单机支持数万并发连接(C10K 问题而设计)
官方基准:单机 5万+ 并发连接
2. 低资源
内存占用极小(相比 Apache)
1万空闲连接仅占约 2.5MB 内存
3. 高可靠性
Master/Worker 架构,Worker 崩溃不影响整体
支持热加载配置(不停机 reload)
4. 功能丰富
反向代理、负载均衡、缓存、限流、HTTPS
模块化设计,按需扩展
5. 生态成熟
全球 Top 1000 网站中超过 30% 使用 Nginx
OpenResty、Tengine 等衍生版本
|
1.3 Nginx vs Apache
1
2
3
4
5
6
7
8
9
|
对比项 Nginx Apache
───────────────────────────────────────────────
并发模型 事件驱动(epoll) 进程/线程驱动
内存占用 低(万级连接几MB) 高(每连接一线程)
静态文件 极快 快
动态内容 需要反向代理 原生支持(mod_php 等)
配置语法 简洁 复杂(.htaccess)
适用场景 高并发、反向代理 动态内容、.htaccess
市场份额 ~34%(持续增长) ~30%(缓慢下降)
|
二、安装
2.1 Linux 安装
1
2
3
4
5
6
7
8
9
10
|
# Ubuntu / Debian
sudo apt update
sudo apt install nginx
# CentOS / RHEL
sudo yum install nginx
# 查看版本
nginx -v
# nginx version: nginx/1.26.2
|
2.2 Docker 安装(推荐)
1
2
3
4
5
6
7
8
|
docker run -d \
--name nginx \
-p 80:80 \
-p 443:443 \
-v /opt/nginx/conf:/etc/nginx \
-v /opt/nginx/html:/usr/share/nginx/html \
-v /opt/nginx/logs:/var/log/nginx \
nginx:1.26
|
1
2
3
4
5
6
7
|
目录映射说明:
/etc/nginx — 配置文件目录
/usr/share/nginx/html — 默认网站根目录
/var/log/nginx — 日志目录
建议生产环境用 Docker Compose 管理:
方便升级、回滚、扩容
|
2.3 Windows 安装
1
2
3
4
5
6
|
# 方式一:winget
winget install Nginx.Nginx
# 方式二:下载解压
# https://nginx.org/en/download.html
# 解压后运行 nginx.exe 即可
|
1
2
3
4
|
Windows 注意事项:
- 仅适合开发测试,不推荐生产环境
- 性能远低于 Linux(IOCP 不如 epoll)
- 不支持某些高级功能(如 sendfile 优化)
|
2.4 验证
1
2
3
4
5
6
7
8
9
10
11
|
# 检查配置文件语法
nginx -t
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
# 查看版本和编译参数
nginx -V
# 快速测试
curl http://localhost
# 返回 Welcome to nginx! 页面
|
三、常用命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
# 启动
nginx # 直接启动
systemctl start nginx # systemd 方式
# 停止
nginx -s stop # 立即停止
nginx -s quit # 优雅停止(处理完当前请求再停)
systemctl stop nginx
# 重载配置(不停机,生产环境常用)
nginx -s reload
systemctl reload nginx
# 重新打开日志文件(日志切割后使用)
nginx -s reopen
# 检查配置
nginx -t # 检查语法
nginx -T # 检查语法 + 打印完整配置
# 指定配置文件
nginx -c /etc/nginx/nginx.conf
# 查看帮助
nginx -h
|
1
2
3
|
生产环境常用操作:
修改配置 → nginx -t 检查 → nginx -s reload 重载
永远不要用 stop + start,用 reload 实现零停机
|
四、配置文件结构
4.1 目录结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/etc/nginx/
├── nginx.conf # 主配置文件
├── conf.d/ # 额外配置(推荐放在这里)
│ └── *.conf # 每个站点一个文件
├── sites-available/ # 可用站点(Debian/Ubuntu)
│ └── default
├── sites-enabled/ # 已启用站点(符号链接)
│ └── default -> ../sites-available/default
├── modules-enabled/ # 动态模块
├── snippets/ # 可复用的配置片段
│ ├── ssl-params.conf
│ └── proxy-params.conf
├── mime.types # MIME 类型映射
├── fastcgi_params # FastCGI 参数
├── scgi_params # SCGI 参数
└── uwsgi_params # uWSGI 参数
|
4.2 主配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
# /etc/nginx/nginx.conf
# 全局块 — 影响 Nginx 整体
user www-data; # 运行用户
worker_processes auto; # Worker 进程数(auto = CPU 核心数)
error_log /var/log/nginx/error.log; # 错误日志
pid /run/nginx.pid; # PID 文件
# events 块 — 影响网络连接
events {
worker_connections 1024; # 每个 Worker 最大连接数
# 总最大并发 = worker_processes × worker_connections
# 4核 × 1024 = 4096 并发连接
}
# http 块 — HTTP 服务器配置
http {
include mime.types; # MIME 类型映射
default_type application/octet-stream;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log main;
sendfile on; # 零拷贝发送文件
tcp_nopush on; # 优化数据包发送
tcp_nodelay on; # 禁用 Nagle 算法
keepalive_timeout 65; # 长连接超时
types_hash_max_size 2048;
# gzip 压缩
gzip on;
gzip_types text/plain text/css application/json;
# 包含其他配置文件
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
|
4.3 配置层级关系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
nginx.conf
├── 全局块(main)
│ ├── user
│ ├── worker_processes
│ └── error_log
├── events 块
│ └── worker_connections
└── http 块
├── 全局 HTTP 配置
├── upstream 块(负载均衡组)
└── server 块(虚拟主机)
├── 全局 server 配置
└── location 块(URL 路由)
└── 具体处理规则
|
1
2
3
4
|
记忆口诀:
从外到内:main → events → http → server → location
嵌套关系:http 包含 server,server 包含 location
配置继承:内层可以覆盖外层的配置
|
五、静态文件托管
5.1 基本静态网站
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
server {
listen 80; # 监听端口
server_name example.com; # 域名
root /var/www/html; # 网站根目录
index index.html index.htm; # 默认首页
location / {
try_files $uri $uri/ =404; # 尝试找文件,找不到返回 404
}
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff2)$ {
expires 30d; # 浏览器缓存 30 天
add_header Cache-Control "public, immutable";
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
}
}
|
5.2 try_files 详解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# 按顺序查找文件
location / {
try_files $uri $uri/ /index.html;
# 1. 查找请求的文件($uri)
# 2. 查找请求的目录($uri/)
# 3. 都找不到则返回 /index.html(SPA 应用常用)
}
# 自定义错误页面
location / {
try_files $uri $uri/ @fallback;
}
location @fallback {
proxy_pass http://backend;
}
|
1
2
3
4
|
SPA 应用(Vue/React)的典型配置:
try_files $uri $uri/ /index.html;
所有未匹配的路径都返回 index.html
让前端路由(history 模式)来处理
|
5.3 目录列表
1
2
3
4
5
6
7
|
# 开启目录浏览(适合文件服务器)
location /files/ {
alias /data/files/;
autoindex on; # 开启目录列表
autoindex_exact_size off; # 显示人类可读的文件大小
autoindex_localtime on; # 显示本地时间
}
|
六、虚拟主机
虚拟主机允许一台 Nginx 服务器同时托管多个网站。
6.1 基于域名的虚拟主机(最常用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
# 网站 A
server {
listen 80;
server_name www.site-a.com site-a.com;
root /var/www/site-a;
index index.html;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/site-a.access.log;
error_log /var/log/nginx/site-a.error.log;
}
# 网站 B
server {
listen 80;
server_name www.site-b.com;
root /var/www/site-b;
index index.html;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/site-b.access.log;
error_log /var/log/nginx/site-b.error.log;
}
|
1
2
3
4
5
6
7
8
|
原理:
Nginx 根据请求头中的 Host 字段匹配 server_name
不同域名 → 不同的 server 块 → 不同的 root 目录
推荐做法:
每个虚拟主机一个 .conf 文件
放在 /etc/nginx/conf.d/ 目录下
如:site-a.conf、site-b.conf
|
6.2 基于端口的虚拟主机
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
# 端口 80 — 主站
server {
listen 80;
server_name example.com;
root /var/www/main;
}
# 端口 8080 — 测试站
server {
listen 8080;
server_name example.com;
root /var/www/test;
}
# 端口 9090 — 管理后台
server {
listen 9090;
server_name example.com;
root /var/www/admin;
}
|
6.3 基于IP的虚拟主机(少用)
1
2
3
4
5
6
7
8
9
10
11
|
server {
listen 192.168.1.10:80;
server_name example.com;
root /var/www/site-a;
}
server {
listen 192.168.1.11:80;
server_name example.com;
root /var/www/site-b;
}
|
七、location 匹配规则
location 是 Nginx 配置的核心,决定请求如何被处理。
7.1 匹配语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
# 精确匹配(最高优先级)
location = /exact/path {
# 只匹配 /exact/path,不匹配 /exact/path/
}
# 前缀匹配(优先级高于正则)
location ^~ /images/ {
# 匹配以 /images/ 开头的请求
# 一旦匹配,不再检查正则
}
# 正则匹配(区分大小写)
location ~ \.php$ {
# 匹配以 .php 结尾的请求
}
# 正则匹配(不区分大小写)
location ~* \.(jpg|png|gif)$ {
# 匹配以 .jpg/.png/.gif 结尾的请求(不区分大小写)
}
# 普通前缀匹配(最低优先级)
location /docs/ {
# 匹配以 /docs/ 开头的请求
}
|
7.2 匹配优先级
1
2
3
4
5
6
7
8
9
10
|
优先级从高到低:
1. = 精确匹配 location = /path
2. ^~ 前缀匹配 location ^~ /path
3. ~ 正则匹配(区分) location ~ /path
4. ~* 正则匹配(不区分) location ~* /path
5. 普通前缀匹配 location /path
记忆:先精确 > 前缀^~ > 正则 > 普通
正则之间按配置文件中的顺序匹配(先写的优先)
|
7.3 实际案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
server {
listen 80;
server_name example.com;
root /var/www/html;
# 1. 精确匹配首页
location = / {
# 只匹配 /
}
# 2. 静态资源(前缀匹配,跳过正则检查,性能更好)
location ^~ /static/ {
expires 30d;
alias /data/static/;
}
# 3. 图片(正则匹配)
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
expires 7d;
add_header Cache-Control "public";
}
# 4. PHP 文件
location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 5. 其他请求
location / {
try_files $uri $uri/ =404;
}
}
|
八、常用变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# 请求相关
$request # 完整的请求行(GET /path HTTP/1.1)
$request_method # 请求方法(GET、POST、PUT 等)
$request_uri # 完整的原始 URI(包含参数)
$uri # 当前 URI(可能被重写,不含参数)
$args # 查询参数(? 后面的部分)
$query_string # 同 $args
# 客户端相关
$remote_addr # 客户端 IP
$remote_port # 客户端端口
$http_user_agent # 用户代理(浏览器信息)
$http_referer # 来源页面
$http_cookie # Cookie
# 服务器相关
$host # 请求头中的 Host 字段
$server_name # 当前 server 块的 server_name
$server_port # 服务器监听端口
$document_root # 当前请求的 root 目录
$request_filename # 请求对应的文件完整路径
# 响应相关
$status # 响应状态码(200、404 等)
$body_bytes_sent # 发送给客户端的字节数(不含响应头)
$request_time # 请求处理时间(秒)
|
1
2
3
4
5
6
|
变量可以在以下位置使用:
- if 条件判断
- rewrite 重写规则
- access_log 日志格式
- proxy_set_header 设置请求头
- return 返回内容
|
九、rewrite 重写规则
9.1 基本语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# rewrite regex replacement [flag];
# flag:
# last — 重写后重新开始匹配 location(默认)
# break — 重写后不再匹配后续 rewrite,但继续在当前 location 中处理
# redirect — 返回 302 临时重定向
# permanent — 返回 301 永久重定向
server {
listen 80;
# HTTP 重定向到 HTTPS
return 301 https://$host$request_uri;
# 旧路径重定向到新路径
rewrite ^/old-page$ /new-page permanent;
rewrite ^/blog/(\d+)/(.*)$ /article/$2?category=$1 last;
# 域名重定向
if ($host != 'www.example.com') {
rewrite ^/(.*)$ https://www.example.com/$1 permanent;
}
}
|
9.2 if 指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
# if 可以使用的条件:
# 变量名 — 非空非0为 true
# = != — 字符串比较
# ~ ~* — 正则匹配
# -f !-f — 文件是否存在
# -d !-d — 目录是否存在
# -e !-e — 文件/目录/符号链接是否存在
location / {
# 根据UA返回不同内容
if ($http_user_agent ~* "Mobile") {
rewrite ^ /mobile$uri last;
}
# 防盗链
location ~* \.(jpg|png|gif)$ {
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403;
}
}
# 维护页面
if (-f /var/www/maintenance.html) {
return 503;
}
}
|
1
2
3
4
5
6
7
8
9
10
|
⚠️ if 的陷阱(if is evil):
Nginx 的 if 不像编程语言的 if
它属于 rewrite 模块,行为可能不符合预期
安全用法:
return、rewrite 指令
危险用法:
在 if 里使用 proxy_pass、try_files 等
建议:能用 location 匹配就不使用 if
|
十、日志配置
10.1 访问日志
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
http {
# 自定义日志格式
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time';
# 使用自定义格式
access_log /var/log/nginx/access.log detailed;
# 某个 location 不记录日志
location /health {
access_log off;
return 200 "ok";
}
}
|
10.2 错误日志
1
2
3
|
# 错误日志级别:debug | info | notice | warn | error | crit | alert | emerg
error_log /var/log/nginx/error.log warn; # 全局
error_log /var/log/nginx/error.log error; # 只记录 error 及以上
|
10.3 日志轮转
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# 手动切割日志
mv /var/log/nginx/access.log /var/log/nginx/access.log.$(date +%Y%m%d)
nginx -s reopen
# 用 logrotate 自动管理(大多数系统自带)
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid)
endscript
}
|
十一、Docker Compose 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# docker-compose.yml
version: '3.8'
services:
nginx:
image: nginx:1.26
container_name: nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./conf:/etc/nginx
- ./html:/usr/share/nginx/html
- ./logs:/var/log/nginx
restart: always
networks:
- web
networks:
web:
external: true
|
1
2
3
4
5
6
7
8
9
10
11
12
|
目录结构:
docker-compose.yml
conf/
├── nginx.conf
├── conf.d/
│ ├── site-a.conf
│ └── site-b.conf
└── mime.types
html/
├── site-a/
└── site-b/
logs/
|
十二、小结
本文学习了 Nginx 的基础:
- Nginx 是什么和为什么选择 Nginx
- 安装方式(Linux、Docker、Windows)
- 常用命令(启动、停止、重载、检查)
- 配置文件结构和层级关系
- 静态文件托管和 try_files
- 虚拟主机(基于域名、端口、IP)
- location 匹配规则和优先级
- 常用变量和 rewrite 规则
- 日志配置和轮转
下一篇将学习反向代理与负载均衡。