接入 Nginx: nginx.conf 三层结构与块级作用域
纲要
「Nginx 配置文件整体结构」,把 conf/nginx.conf 从逻辑上拆开:
- 三大块 :全局块、
events块、http块各自负责什么 http块的两层嵌套 :http全局块 →server块 →location块- 对照真实配置逐行讲 :以
nginx-1.16.1自带的默认nginx.conf为例 - 固定指令 vs 可配置值:哪些是关键字不能动,哪些可以改
- 多
server、多location:虚拟主机与路径匹配的组织方式 - 语法规则:分号、花括号、注释、相对路径基准
#mermaid-svg-wAqnNfx8IxPhcU8b{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-wAqnNfx8IxPhcU8b .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wAqnNfx8IxPhcU8b .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wAqnNfx8IxPhcU8b .error-icon{fill:#552222;}#mermaid-svg-wAqnNfx8IxPhcU8b .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wAqnNfx8IxPhcU8b .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wAqnNfx8IxPhcU8b .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wAqnNfx8IxPhcU8b .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wAqnNfx8IxPhcU8b .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wAqnNfx8IxPhcU8b .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wAqnNfx8IxPhcU8b .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wAqnNfx8IxPhcU8b .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wAqnNfx8IxPhcU8b .marker.cross{stroke:#333333;}#mermaid-svg-wAqnNfx8IxPhcU8b svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wAqnNfx8IxPhcU8b p{margin:0;}#mermaid-svg-wAqnNfx8IxPhcU8b .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wAqnNfx8IxPhcU8b .cluster-label text{fill:#333;}#mermaid-svg-wAqnNfx8IxPhcU8b .cluster-label span{color:#333;}#mermaid-svg-wAqnNfx8IxPhcU8b .cluster-label span p{background-color:transparent;}#mermaid-svg-wAqnNfx8IxPhcU8b .label text,#mermaid-svg-wAqnNfx8IxPhcU8b span{fill:#333;color:#333;}#mermaid-svg-wAqnNfx8IxPhcU8b .node rect,#mermaid-svg-wAqnNfx8IxPhcU8b .node circle,#mermaid-svg-wAqnNfx8IxPhcU8b .node ellipse,#mermaid-svg-wAqnNfx8IxPhcU8b .node polygon,#mermaid-svg-wAqnNfx8IxPhcU8b .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wAqnNfx8IxPhcU8b .rough-node .label text,#mermaid-svg-wAqnNfx8IxPhcU8b .node .label text,#mermaid-svg-wAqnNfx8IxPhcU8b .image-shape .label,#mermaid-svg-wAqnNfx8IxPhcU8b .icon-shape .label{text-anchor:middle;}#mermaid-svg-wAqnNfx8IxPhcU8b .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wAqnNfx8IxPhcU8b .rough-node .label,#mermaid-svg-wAqnNfx8IxPhcU8b .node .label,#mermaid-svg-wAqnNfx8IxPhcU8b .image-shape .label,#mermaid-svg-wAqnNfx8IxPhcU8b .icon-shape .label{text-align:center;}#mermaid-svg-wAqnNfx8IxPhcU8b .node.clickable{cursor:pointer;}#mermaid-svg-wAqnNfx8IxPhcU8b .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wAqnNfx8IxPhcU8b .arrowheadPath{fill:#333333;}#mermaid-svg-wAqnNfx8IxPhcU8b .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wAqnNfx8IxPhcU8b .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wAqnNfx8IxPhcU8b .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wAqnNfx8IxPhcU8b .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wAqnNfx8IxPhcU8b .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wAqnNfx8IxPhcU8b .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wAqnNfx8IxPhcU8b .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wAqnNfx8IxPhcU8b .cluster text{fill:#333;}#mermaid-svg-wAqnNfx8IxPhcU8b .cluster span{color:#333;}#mermaid-svg-wAqnNfx8IxPhcU8b div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wAqnNfx8IxPhcU8b .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wAqnNfx8IxPhcU8b rect.text{fill:none;stroke-width:0;}#mermaid-svg-wAqnNfx8IxPhcU8b .icon-shape,#mermaid-svg-wAqnNfx8IxPhcU8b .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wAqnNfx8IxPhcU8b .icon-shape p,#mermaid-svg-wAqnNfx8IxPhcU8b .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wAqnNfx8IxPhcU8b .icon-shape .label rect,#mermaid-svg-wAqnNfx8IxPhcU8b .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wAqnNfx8IxPhcU8b .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wAqnNfx8IxPhcU8b .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wAqnNfx8IxPhcU8b :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} http块
server块
server 全局块
listen / server_name
location 块
root / index
http 全局块
include / sendfile / keepalive_timeout
server 块
events块
worker_connections 1024;
全局块
#user nobody;
worker_processes 1;
#error_log / #pid
一、为什么要先理解结构
Nginx 的能力全部通过 conf/nginx.conf 表达。这个文件默认有 117 行,其中大量是注释,但初次打开依然会觉得无从下手。
理解结构后你会知道:改配置就是往正确的块里放正确的指令。后面的三件事------部署静态资源、反向代理、负载均衡------本质上分别是:
| 要做的事 | 改哪里 |
|---|---|
| 部署静态资源 | server 块里的 location,配 root + index |
| 反向代理 | server 块里新增 location,配 proxy_pass |
| 负载均衡 | http 块里新增 upstream,再在 location 的 proxy_pass 里引用 |
二、默认配置文件全貌
下面是 nginx-1.16.1 安装后的默认 conf/nginx.conf,已去掉注释,这是它真正的骨架:
nginx
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
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 logs/access.log main;
sendfile on;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
只有 40 行左右。去掉注释是读 nginx.conf 的第一步 ------注释占了原文件的三分之二,且绝大多数是 PHP/HTTPS 的示例模板,与当前场景无关。
三、全局块
范围
从文件开头到 events { 之前,全部属于全局块。
nginx
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
职责
配置与 Nginx 运行本身相关的全局参数,与具体请求处理无关。
| 指令 | 作用 | 说明 |
|---|---|---|
user |
运行 worker 进程的用户 |
默认被注释,即 nobody |
worker_processes |
worker 进程数 |
默认 1,建议设为 auto 或 CPU 核数 |
error_log |
错误日志路径与级别 | 级别可选 debug/info/notice/warn/error/crit |
pid |
pid 文件路径 |
默认 logs/nginx.pid |
关于被注释的指令
注意这些行前面都有 #。被注释不代表不重要,而是表示"使用默认值"。
比如 #pid logs/nginx.pid; 被注释,但启动时依然会生成 logs/nginx.pid------因为 pid 指令的默认值就是这个。把它打开并改成别的值,才会变。
error_log 是值得显式打开的:
nginx
error_log logs/error.log;
error_log logs/error.log notice;
两行都写是常见写法(不同级别记到不同文件)。调试阶段可以开 info 甚至 debug(debug 需要编译时加 --with-debug)。
一个易错点
worker_processes 与后面 events 块里的 worker_connections 共同决定理论最大连接数:
txt
最大连接数 ≈ worker_processes × worker_connections
默认 1 × 1024 = 1024。这是"同时保持的连接数",不是 QPS。反向代理场景下,一个客户端连接会占用一个到后端的连接,所以作为反向代理时实际承载的客户端连接数要除以 2。
四、events 块
范围
nginx
events {
worker_connections 1024;
}
职责
配置与网络连接相关的参数。
| 指令 | 作用 |
|---|---|
worker_connections |
每个 worker 进程能同时处理的最大连接数 |
use |
指定事件驱动模型,如 use epoll;(Linux 下推荐) |
multi_accept |
是否一次接受多个新连接 |
accept_mutex |
是否用互斥锁均衡各 worker 的新连接分配 |
默认配置里只有 worker_connections。Linux 下 Nginx 会自动选择最高效的模型(epoll),通常不需要手写 use epoll;。
worker_connections 调大时的配套操作 :Linux 单进程默认最多打开 1024 个文件描述符(ulimit -n),连接数超过它会报 too many open files。需要同时调整系统限制:
nginx
worker_rlimit_nofile 65535; # 放在全局块
events {
worker_connections 65535;
}
bash
# /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
五、http 块
范围与职责
http { ... } 及其内部全部内容。这是配置量最大、操作最频繁的块 ,代理、缓存、日志、虚拟主机(server)都在这里配。
http 块在逻辑上再分为两部分:
http全局块 :http {之后到第一个server {之前server块:可以有一个或多个
http 全局块
nginx
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#gzip on;
server { ... }
}
这里的指令对所有 server 生效 (server 内可以覆盖):
| 指令 | 作用 | 为什么重要 |
|---|---|---|
include mime.types |
引入 MIME 类型映射 |
决定 Content-Type,删了会导致 CSS/JS 失效 |
default_type |
未匹配 MIME 时的默认值 |
默认 application/octet-stream(下载) |
sendfile |
开启零拷贝文件传输 | 静态资源性能关键,直接内核态发送,不经用户态 |
tcp_nopush |
配合 sendfile,攒够一个包再发 |
提高网络利用率 |
keepalive_timeout |
长连接超时秒数 | 默认 65 秒,减少 TCP 握手开销 |
gzip |
响应压缩 | 默认关闭,开启可显著减小文本类响应体积 |
access_log / log_format |
访问日志 | 默认被注释但生效(使用默认路径与格式) |
sendfile on 是 Nginx 静态资源性能强于 Tomcat 的核心原因之一 。传统读文件发送要经历:磁盘 → 内核缓冲区 → 用户缓冲区 → 内核 socket 缓冲区 → 网卡,两次 CPU 拷贝、两次上下文切换。sendfile 让数据直接在内核态从文件描述符传到 socket,省掉用户态中转。
server 块
nginx
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server 块即虚拟主机 (Virtual Host)------一台机器上的一个"站点"。
一个 http 块可以配多个 server ,这是 Nginx 托管多站点的基础:
nginx
server {
listen 80;
server_name localhost;
location / { root html; index index.html; }
}
server {
listen 81;
server_name localhost;
location / { root html81; index index.html; }
}
http 块从逻辑上分为:
server全局块 :listen、server_name等location块:可有一个或多个
| 指令 | 作用 | 说明 |
|---|---|---|
listen |
监听端口 | 可写 80、81、443 ssl、127.0.0.1:80 |
server_name |
服务器名/域名 | 学习阶段写 localhost;生产写真实域名 |
server_name 的作用 :多个 server 监听同一个端口时,Nginx 依据请求头里的 Host 与 server_name 匹配来决定交给哪个 server 处理。这就是"一台服务器用 80 端口托管多个域名"的原理。
location 块
nginx
location / {
root html;
index index.html index.htm;
}
location 用于匹配请求的 URI 路径。
| 指令 | 作用 | 说明 |
|---|---|---|
root |
静态资源根目录 | html 是相对路径,基准是安装目录 /usr/local/nginx |
index |
默认首页 | 可配多个,空格分隔,依次查找,都找不到返回 403/404 |
proxy_pass |
反向代理目标地址 | 下一篇的核心 |
alias |
路径别名 | 与 root 的拼接规则不同,见后文 |
一个 server 可以配多个 location,这是路径分发的基础:
nginx
location / {
root html; # 静态资源走本地
}
location /api/ {
proxy_pass http://192.168.138.101:8080; # /api 前缀走后端
}
root 与 alias 的区别
这是配置静态资源时最容易踩的坑。
nginx
# root:最终路径 = root + 完整 URI
location /static/ {
root /usr/local/nginx/html;
}
# 请求 /static/logo.png → /usr/local/nginx/html/static/logo.png
# alias:最终路径 = alias + (URI 去掉 location 前缀后的部分)
location /static/ {
alias /usr/local/nginx/html/;
}
# 请求 /static/logo.png → /usr/local/nginx/html/logo.png
root 会拼上完整的 location 路径 ,alias 会替换掉 location 匹配的部分。用错会导致 404,且报错信息不会告诉你是路径拼错了。
六、固定指令与可配置值
nginx.conf 里有两种内容:
固定指令(关键字,不能改) :server、listen、server_name、location、root、index、include、error_page、proxy_pass、upstream......
可配置值(按需修改) :端口号、域名、URI 匹配规则、目录名、首页文件名、代理地址......
nginx
server { # server 是固定指令
listen 80; # ← 80 可改
server_name localhost; # ← localhost 可改
location / { # ← / 可改(匹配规则)
root html; # ← html 可改(目录名)
index index.html; # ← index.html 可改(文件名)
}
}
改配置时只动"值",不动"指令名"。把 server_name 写成 servername、listen 写成 listen_port,都会报 unknown directive。
七、语法规则
| 规则 | 说明 | 违反的后果 |
|---|---|---|
每条指令以分号 ; 结尾 |
worker_processes 1; |
directive is not terminated by ";" |
块用花括号 {} 包裹 |
http { ... } |
unexpected "}" 或 is not terminated by "}" |
注释用 # |
#gzip on; |
--- |
| 指令与值之间用空格分隔 | 至少一个空格 | invalid number of arguments |
| 相对路径基准是安装目录 | root html; → /usr/local/nginx/html |
--- |
| 缩进不影响语义 | 只为可读性 | --- |
漏写分号是最高频的报错 。课程演示中就出现过:把 index index.html; 改成 index hello.html(漏了分号),nginx -s reload 报:
txt
nginx: [emerg] unexpected "}" in /usr/local/nginx/conf/nginx.conf:46
报错行号是 46(花括号所在行),但真正的问题在上一行漏了分号------报错位置往往滞后一行,这是排查时的经验点。
用 vim 打开时可以用 :set nu 显示行号,快速定位:
bash
vim /usr/local/nginx/conf/nginx.conf
:set nu
八、作用域与继承
指令在不同块中的生效范围不同,子块可以覆盖父块:
#mermaid-svg-HrkwzxQ6MT9UgwKS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HrkwzxQ6MT9UgwKS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HrkwzxQ6MT9UgwKS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HrkwzxQ6MT9UgwKS .error-icon{fill:#552222;}#mermaid-svg-HrkwzxQ6MT9UgwKS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HrkwzxQ6MT9UgwKS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HrkwzxQ6MT9UgwKS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HrkwzxQ6MT9UgwKS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HrkwzxQ6MT9UgwKS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HrkwzxQ6MT9UgwKS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HrkwzxQ6MT9UgwKS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HrkwzxQ6MT9UgwKS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HrkwzxQ6MT9UgwKS .marker.cross{stroke:#333333;}#mermaid-svg-HrkwzxQ6MT9UgwKS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HrkwzxQ6MT9UgwKS p{margin:0;}#mermaid-svg-HrkwzxQ6MT9UgwKS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-HrkwzxQ6MT9UgwKS .cluster-label text{fill:#333;}#mermaid-svg-HrkwzxQ6MT9UgwKS .cluster-label span{color:#333;}#mermaid-svg-HrkwzxQ6MT9UgwKS .cluster-label span p{background-color:transparent;}#mermaid-svg-HrkwzxQ6MT9UgwKS .label text,#mermaid-svg-HrkwzxQ6MT9UgwKS span{fill:#333;color:#333;}#mermaid-svg-HrkwzxQ6MT9UgwKS .node rect,#mermaid-svg-HrkwzxQ6MT9UgwKS .node circle,#mermaid-svg-HrkwzxQ6MT9UgwKS .node ellipse,#mermaid-svg-HrkwzxQ6MT9UgwKS .node polygon,#mermaid-svg-HrkwzxQ6MT9UgwKS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HrkwzxQ6MT9UgwKS .rough-node .label text,#mermaid-svg-HrkwzxQ6MT9UgwKS .node .label text,#mermaid-svg-HrkwzxQ6MT9UgwKS .image-shape .label,#mermaid-svg-HrkwzxQ6MT9UgwKS .icon-shape .label{text-anchor:middle;}#mermaid-svg-HrkwzxQ6MT9UgwKS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-HrkwzxQ6MT9UgwKS .rough-node .label,#mermaid-svg-HrkwzxQ6MT9UgwKS .node .label,#mermaid-svg-HrkwzxQ6MT9UgwKS .image-shape .label,#mermaid-svg-HrkwzxQ6MT9UgwKS .icon-shape .label{text-align:center;}#mermaid-svg-HrkwzxQ6MT9UgwKS .node.clickable{cursor:pointer;}#mermaid-svg-HrkwzxQ6MT9UgwKS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-HrkwzxQ6MT9UgwKS .arrowheadPath{fill:#333333;}#mermaid-svg-HrkwzxQ6MT9UgwKS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-HrkwzxQ6MT9UgwKS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-HrkwzxQ6MT9UgwKS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HrkwzxQ6MT9UgwKS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-HrkwzxQ6MT9UgwKS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HrkwzxQ6MT9UgwKS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-HrkwzxQ6MT9UgwKS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-HrkwzxQ6MT9UgwKS .cluster text{fill:#333;}#mermaid-svg-HrkwzxQ6MT9UgwKS .cluster span{color:#333;}#mermaid-svg-HrkwzxQ6MT9UgwKS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-HrkwzxQ6MT9UgwKS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-HrkwzxQ6MT9UgwKS rect.text{fill:none;stroke-width:0;}#mermaid-svg-HrkwzxQ6MT9UgwKS .icon-shape,#mermaid-svg-HrkwzxQ6MT9UgwKS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HrkwzxQ6MT9UgwKS .icon-shape p,#mermaid-svg-HrkwzxQ6MT9UgwKS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-HrkwzxQ6MT9UgwKS .icon-shape .label rect,#mermaid-svg-HrkwzxQ6MT9UgwKS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HrkwzxQ6MT9UgwKS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-HrkwzxQ6MT9UgwKS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-HrkwzxQ6MT9UgwKS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} http 块
keepalive_timeout 65
gzip on
server 块 A
listen 80
server 块 B
listen 81
keepalive_timeout 120 ← 覆盖
location /
root html
location /api/
proxy_pass ...
location /
root html81
规则:
http块的配置对该http内所有server生效server块的配置对该server内所有location生效- 子块中重复定义同一指令,子块优先
- 有些指令只能出现在特定块中,放错位置会报
"xxx" directive is not allowed here
常见指令的允许位置:
| 指令 | 可出现的位置 |
|---|---|
worker_processes |
全局块 |
worker_connections |
events 块 |
include / sendfile / gzip / upstream |
http 块 |
listen / server_name |
server 块 |
root / index / proxy_pass / alias |
location 块(也可在 server/http 中作为默认值) |
九、最小可用配置模板
理解了结构后,一个能跑起来的最小配置只需要这些:
nginx
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
}
}
后面所有的功能扩展,都是在这个骨架上加 upstream、加 location、加指令。
API 速览
| 指令 | 所属块 | 作用 |
|---|---|---|
user |
全局 | 指定 worker 进程运行的用户 |
worker_processes |
全局 | worker 进程数,建议 auto |
worker_rlimit_nofile |
全局 | worker 进程可打开的最大文件描述符数 |
error_log |
全局 / http / server / location |
错误日志路径与级别 |
pid |
全局 | master 进程 ID 文件路径 |
worker_connections |
events |
单个 worker 最大连接数 |
use |
events |
事件驱动模型(epoll / select / poll) |
include |
任意 | 引入其他配置文件 |
default_type |
http / server / location |
默认 MIME 类型 |
sendfile |
http / server / location |
零拷贝文件传输 |
tcp_nopush |
http / server / location |
攒包发送,配合 sendfile |
keepalive_timeout |
http / server / location |
长连接超时时间 |
gzip |
http / server / location |
响应压缩 |
listen |
server |
监听端口 |
server_name |
server |
虚拟主机域名 |
error_page |
http / server / location |
错误页映射 |
location |
server / location |
URI 路径匹配块 |
root |
http / server / location |
静态资源根目录(拼接完整 URI) |
alias |
location |
路径别名(替换 location 前缀) |
index |
http / server / location |
默认首页,可多个,空格分隔 |
官方文档
Nginx配置文件结构(Beginner's Guide):https://nginx.org/en/docs/beginners_guide.htmlNginx核心模块(全局块与events指令):https://nginx.org/en/docs/ngx_core_module.htmlNginxhttp核心模块:https://nginx.org/en/docs/http/ngx_http_core_module.htmlNginx指令字母索引:https://nginx.org/en/docs/dirindex.htmlNginxlocation匹配规则:https://nginx.org/en/docs/http/ngx_http_core_module.html#location
总结
整个 nginx.conf 就三个块:全局块、events 块、http 块 。前两个通常不动,日常 90% 的工作都在 http 块里。
http 块内部是两层嵌套 :http 全局块(对所有站点生效的公共配置)→ 若干 server 块(虚拟主机,靠 listen + server_name 区分)→ 每个 server 内若干 location 块(靠 URI 前缀区分)。这个"多 server + 多 location"的组织方式,正是 Nginx 能同时托管多个站点、同时处理静态资源与反向代理的结构基础。
读配置的第一件事是删注释 。默认文件 117 行里三分之二是注释和 PHP/HTTPS 模板,删完只剩 40 行骨架,结构立刻清晰。
每个指令只能出现在特定块中,放错会报 directive is not allowed here ;子块可以覆盖父块的同名指令。改配置前先想清楚"这条指令该放哪一层"------比如 gzip 放 http 是对所有站点生效,放某个 location 就只对匹配的路径生效。
漏分号是最高频报错,且报错行号通常滞后一行 。看到 unexpected "}" 时往上翻一行找分号。
root 与 alias 的拼接规则不同 :root 是"根目录 + 完整 URI",alias 是"别名 + 去掉 location 前缀后的剩余部分"。配静态资源 404 时优先怀疑这里。
下一篇用这个结构做第一件实事:把外卖平台的静态页面部署到 Nginx,并逐条解释 listen、server_name、location、root、index 的实际作用。