nginx.conf 采用分层的块状结构,主要由以下几个核心模块(上下文)构成:
# 全局块 (Main Context)
user nginx nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
...
# 事件块 (Events Context)
events {
worker_connections 1024;
use epoll;
...
}
# HTTP块 (HTTP Context)
http {
# HTTP全局块
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
sendfile on;
keepalive_timeout 65;
...
# 服务器块 (Server Context)
server {
listen 80;
server_name example.com;
...
# 位置块 (Location Context)
location / {
root /usr/share/nginx/html;
index index.html;
}
location /api/ {
proxy_pass http://backend;
}
}
# 服务器块 (Server Context)
server {
listen 80;
server_name example.com;
...
# 位置块 (Location Context)
location / {
root /usr/share/nginx/html;
index index.html;
}
location /api/ {
proxy_pass http://backend;
}
}
# 上游服务器块 (Upstream Context) - 通常位于http块内
upstream backend {
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
}
各个模块的作用:
全局块 (Main Context)
作用范围:最高层,配置影响 Nginx 全局的参数。
常见指令:
user: 设置运行 Nginx worker 进程的用户和组。
worker_processes: 定义 worker 进程的数量,通常设置为 CPU 核心数或 auto。
error_log: 全局错误日志的文件路径和日志级别(如 debug, info, warn, error)。
pid: 指定存储主进程 PID 的文件路径。
events 块 (Events Context)
作用范围:影响 Nginx 与用户网络的连接。
常见指令:
worker_connections: 单个 worker 进程能够同时处理的最大连接数。
use: 指定 Nginx 使用的事件驱动模型(如 epoll, kqueue),Linux 2.6+ 内核通常用 epoll,高性能的关键。
multi_accept: 设置一个 worker 进程是否同时接受多个新连接。
http 块 (HTTP Context)
作用范围:所有 HTTP 相关的配置都嵌套在此块内,是配置最丰富的部分。可以包含多个 server 块。
常见指令:
include: 引入其他配置文件(如 mime.types 用于文件扩展名与 MIME 类型映射)。
default_type: 默认的 MIME 类型。
access_log: 默认的访问日志路径和格式。
sendfile: 启用高效文件传输模式。
keepalive_timeout: 设置客户端与服务器保持连接的超时时间。
gzip: 启用 Gzip 压缩,减少传输数据量。
upstream: 定义后端服务器组,用于负载均衡(严格来说,upstream 是 http 块的一个子模块)。
server 块 (Server Context)
作用范围:定义一个虚拟主机(Virtual Host),用于处理到达特定 IP/端口或域名的请求。一个 http 块可以有多个 server 块。
常见指令:
listen: 监听的 IP 地址和端口。
server_name: 匹配的域名列表,支持通配符和正则表达式。用于决定由哪个 server 块来处理请求。
root: 此虚拟主机的默认网站根目录。
index: 默认的索引文件。
location 块 (Location Context)
作用范围:嵌套在 server 块内,用于匹配特定的 URI(请求路径),并定义如何处理这些请求。这是配置中最灵活和最重要的部分。
匹配机制:见下文详细说明。
upstream 块 (Upstream Context)
作用范围:定义一组后端服务器,用于负载均衡或代理。通常位于 http 块内。
常见指令:
server: 定义后端服务器的地址和可选参数(如权重 weight、健康检查等)。
load balancing method: 负载均衡策略,如 round-robin(默认)、ip_hash、least_conn 等。
二、location 模块的匹配机制及内部参数
匹配机制
Nginx 收到请求后,会首先根据 listen 和 server_name 找到对应的 server 块,然后在该 server 块中的所有 location 中寻找匹配当前 URI 的最佳块。
location 的语法:
nginx
location [修饰符] 匹配模式 {
...
}
匹配优先级(从高到低):
精确匹配 (=)
使用 = 修饰符,优先级最高。
例如:location = /exact/path 只会匹配 /exact/path 这个请求,不会匹配 /exact/path/ 或 /exact/path/another。
前缀匹配(无修饰符)
常规前缀匹配:例如 location /prefix/。会匹配以该模式开头的所有 URI。
注意:如果有多个前缀匹配,Nginx 会选择最长前缀的 location。例如,同时有 location /img/ 和 location /img/thumb/,请求 /img/thumb/photo.jpg 会由后者处理。
正则表达式匹配 (~ 或 ~*)
~:区分大小写的正则匹配。
~*:不区分大小写的正则匹配。
例如:location ~ \.php$ 会匹配所有以 .php 结尾的请求。
优先级:按配置文件中出现的顺序匹配,第一个匹配成功的正则表达式会生效。这与前缀匹配的“最长匹配”原则不同。
通用匹配 (/)
location / 会匹配所有请求,但它是所有匹配中优先级最低的。只有当没有其他任何 location 匹配时,才会使用它。
匹配流程总结:
检查所有精确匹配 (=),找到则立即使用。
检查所有前缀匹配,记录下最长匹配的前缀。
按顺序检查所有正则表达式匹配 (~ 和 ~*),找到第一个匹配的正则,立即使用。
如果没有任何正则匹配,则使用第 2 步中记录的最长前缀匹配。
如果连前缀匹配都没有,则fallback到通用匹配 location /。
location 内部常用参数(指令)作用
在 location {} 大括号内,可以配置大量指令来处理匹配到的请求
参数(指令)作用描述常见示例
root
设置请求的根目录。Nginx 会将完整的 URI 路径追加到 root 指定的路径后来寻找文件。
root /var/www/html;请求 /css/style.css 会映射到 /var/www/html/css/style.css
alias
定义路径别名。它只会将 location 中匹配的部分替换为 alias 指定的路径。末尾通常需要加 /。
location /images/ { alias /data/static/;}请求 /images/logo.png 会映射到 /data/static/logo.png
proxy_pass
将请求反向代理到指定的上游服务器。是实现负载均衡和反向代理的核心指令。
proxy_pass http://backend_server;
try_files
按顺序检查文件或目录是否存在,并返回第一个找到的文件或目录。如果都不存在,则重定向到最后一个参数指定的 fallback。
try_files $uri $uri/ /index.html;(常用于前端路由 History 模式)
index
指定默认的索引文件。当请求以目录结尾时,会尝试寻找该文件。
index index.html index.htm;
rewrite
使用正则表达式重写 URI。可以实现非常灵活的 URL 重写规则。
rewrite ^/old-url$ /new-url permanent;
return
直接返回指定的状态码或重定向。
return 404;return 301 https://$host$request_uri;
add_header
向响应头中添加自定义字段。常用于设置 CORS、安全策略等。
add_header X-Frame-Options DENY;
auth_basic
为 location 启用基本的用户名密码认证。
auth_basic "Restricted Area";auth_basic_user_file /etc/nginx/.htpasswd;
传统多页面网站:
每个URL(如 /, /about, /contact.html) 都对应服务器上的一个真实文件(index.html, about.html, contact.html)。
即使没有 try_files,Nginx 也能正确找到并返回这些文件。
现代单页面应用(SPA):
只有一个真实的入口文件:index.html。
JavaScript(如 React Router, Vue Router)接管了浏览器中的路由,根据URL路径(如 /dashboard, /user/profile)来动态渲染不同的页面内容。
这些路径(如 /dashboard)在服务器上并不存在对应的 dashboard.html 文件。
如果没有 try_files:当你直接在浏览器地址栏输入 https://your-site.com/dashboard 并回车时,浏览器会向服务器请求 /dashboard 这个路径。Nginx 在服务器上找不到名为 dashboard 的文件或目录,就会返回 404 Not Found 错误。
有了 try_files $uri $uri/ /index.html;:同样的请求,Nginx 的处理流程是:
找文件 /dashboard -> 不存在。
找目录 /dashboard/ -> 通常也不存在。
内部重定向到 /index.html -> 成功找到并返回 index.html 文件。
浏览器收到 index.html,加载其中的 JavaScript。
JavaScript 路由(如 Vue Router)看到当前地址是 /dashboard,然后正确地渲染出 Dashboard 页面。