Nginx 学习笔记(一):基础与核心配置

写在前面

本文是 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
   OpenRestyTengine 等衍生版本

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 规则
  • 日志配置和轮转

下一篇将学习反向代理与负载均衡。