Java 项目实战: 外卖平台优化-Nginx配置文件结构与块层级

接入 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.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 的实际作用。

相关推荐
2601_962071571 小时前
类变量和全局变量的查找路径有什么区别?
开发语言·python
\光辉岁月/2 小时前
5.java-数组
java·开发语言
Java后端的Ai之路2 小时前
Python进阶探索29_eval内置函数
开发语言·python·探索·eval·内置函数
谢亮_vipxieliang3 小时前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot
时间的拾荒人3 小时前
Qt 多线程详解:从 QThread 到实战
开发语言·qt·面试
郑州光合科技余经理3 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
2601_962071573 小时前
类变量和全局变量的生命周期有什么区别?
java·开发语言·jvm
code2cat3 小时前
Java进阶篇之AtomicReference:一次替换引用,读到一份完整状态
java·并发编程·不可变对象·atomicreference
专业程序开发源3 小时前
springboot简历管理系统81389-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计