1 安装包下载地址

nginx 官网

2 配置文件详细分析(nginx 1.28.0)


#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;


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;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

好的,我们来以您提供的 nginx.conf 文件为基础,详细解析 Nginx 的各项配置。这个配置文件是 Nginx 1.28.0 的默认配置,是一个非常基础和简洁的范例。

配置文件整体上分为几个主要部分(也称为上下文 “Context”):

  1. 全局块 (Main Context): 配置文件开始到 events {...} 块之前的部分。
  2. events 块 (Events Context): 设置影响 Nginx 服务器与用户网络连接的参数。
  3. http 块 (HTTP Context): 服务器核心配置,影响所有 Web 服务的 HTTP 流量。
  4. server 块 (Server Context): 位于 http 块内,用于定义一个虚拟主机(Virtual Host)。
  5. location 块 (Location Context): 位于 server 块内,用于根据请求的 URI 来匹配并处理特定的请求。

2.1 第一部分:全局块 (Main Context)

2.1.1 user nobody;

- **作用**: 定义运行 Nginx **工作进程(Worker Processes)** 的用户和组。
- **详解**: 出于安全考虑,Nginx 主进程(Master Process)通常以 `root` 用户启动(为了绑定 80/443 等特权端口),然后其工作进程会降权到指定的非特权用户(如 `nobody`, `www-data`, `nginx`)来运行。这行被注释了,意味着工作进程仍以启动 Nginx 的用户(很可能是 `root`)运行,**这在生产环境中是极不安全的**。应该取消注释并配置为合适的非特权用户。

2.1.2 worker_processes 1;

- **作用**: 定义工作进程的数量。
- **详解**:
    * `1` 是默认值,表示只启动 1 个 worker 进程。
    * 最优值取决于服务器 CPU 核心数、磁盘和负载类型。一个常见的推荐值是设置为 CPU 的逻辑核心数(`auto`),例如 `worker_processes auto;`,让 Nginx 自动检测。

2.1.3 error_log

- **作用**: 配置全局错误日志的文件路径和记录级别。
- **详解**:
    * `logs/error.log` 是相对路径,相对于 Nginx 的安装目录(通常是 `/usr/local/nginx/` 或 `/etc/nginx/`)。
    * 日志级别(`debug`, `info`, `notice`, `warn`, `error`, `crit`)从上到下严重性递增,记录的详细信息递减。`error` 是默认级别。生产环境通常用 `warn` 或 `error`。
    * 这里提供了几个配置示例,但都被注释了,会使用 Nginx 内建的默认设置。

2.1.4 pid

- **作用**: 定义存储主进程(Master Process)ID 的文件路径。
- **详解**: 这个文件用于其他程序(比如 init 系统或管理脚本)找到 Nginx 主进程的 PID,以便向其发送信号(如重载、停止)。注释掉也会使用默认路径(编译时指定,通常是 `logs/nginx.pid`)。

2.2 events 块 (Events Context)

events {
    worker_connections  1024;
}

这个块专门用于设置如何处理连接,对性能影响很大。

2.2.1 worker_connections 1024;

- **作用**: **单个 worker 进程** 能够同时处理的最大连接数。
- **详解**:
    * 这个数字包括了所有连接:**前端的客户端连接(如浏览器)** 和 **后端的代理/上游服务器连接**。
    * 它限制了单个 worker 的并发能力。整个 Nginx 服务器的最大理论连接数是 `worker_processes * worker_connections`。
    * 对于高并发站点,这个值(1024)可能不够,需要调高(如 4096, 8192)。但最终受限于系统的 `ulimit -n`(最大打开文件数限制),需要确保系统级限制足够大。

2.3 http 块 (HTTP Context)

这是配置的核心,包含了所有 HTTP 相关的设置。

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  ... (省略) ...;
    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server { ... } # 下一个部分详细讲
}

2.3.1 include mime.types;

- **作用**: 引入一个外部的配置文件。
- **详解**: `mime.types` 文件包含了**文件扩展名**到 **MIME 类型** 的映射表。例如,`.html` 映射为 `text/html`,`.jpg` 映射为 `image/jpeg`。这使得 Nginx 在发送文件时能正确设置 `Content-Type` 响应头,浏览器才能正确解析内容。

2.3.2 default_type application/octet-stream;

- **作用**: 定义默认的 MIME 类型。
- **详解**: 当 Nginx 无法在 `mime.types` 中找到请求文件对应的类型时,就会使用这个默认类型。`application/octet-stream` 表示这是一个通用的二进制流文件,浏览器通常会将其作为下载处理。

2.3.3 log_format 和 access_log

- **作用**: 定义访问日志的格式和存储路径。
- **详解**:
    * `log_format` 指令(此处被注释且命名为 `main`)定义了一种日志格式,包含了客户端 IP、时间、请求行、状态码、引用页、用户代理等信息。这是一种非常详细和通用的格式。
    * `access_log` 指令启用访问日志,并指定写入的文件路径和使用的格式(这里用的是上面定义的 `main` 格式)。
    * 它们被注释了,所以默认不会记录访问日志。生产环境必须开启此功能用于分析和排查问题。

2.3.4 sendfile on;

- **作用**: 启用 `sendfile` 系统调用。
- **详解**: 这是一个重要的性能优化选项。当需要发送静态文件(如图片、CSS)时,启用后文件数据可以不经过用户态空间(Userspace)直接在内核态(Kernel Space)中传输到网络套接字,减少了上下文切换和数据拷贝,极大提高了传输效率。

2.3.5 tcp_nopush on;

- **作用**: 与 `sendfile on` 配合使用。
- **详解**: 启用后,Nginx 会尝试在单个数据包中发送完整的 HTTP 响应头,并在发送文件数据时,等待数据包填满后再发送。这有助于优化网络利用率,减少数据包数量。它只在 `sendfile on` 时有效。

2.3.6 keepalive_timeout 65;

- **作用**: 设置 **Keep-Alive** 连接的超时时间。
- **详解**:
    * HTTP Keep-Alive 允许客户端和服务器在单个 TCP 连接上发送和接收多个 HTTP 请求/响应,减少了建立和关闭连接的开销。
    * `65` 表示服务器将在连接空闲 65 秒后关闭它。设置为 `0` 则禁用 Keep-Alive。
    * 设置一个合理的超时时间(如 15-30 秒)对性能有益,太长会占用服务器资源。

2.3.7 gzip on;

- **作用**: 启用 Gzip 压缩。
- **详解**: 启用后,Nginx 会在将响应发送给客户端(通常是浏览器)之前,对文本类内容(HTML, CSS, JS, XML, JSON 等)进行压缩,可以显著减少传输数据量,加快加载速度。这是另一个非常重要的性能优化选项,通常应该开启并配合 `gzip_comp_level`, `gzip_types` 等指令进行细化配置。

2.4 第四部分:server 块 (Server Context) - 虚拟主机

server 块嵌套在 http 块内,用于定义一个虚拟服务器(虚拟主机)。你可以在 http 块内有多个 server 块,通过 server_name 来区分不同的网站。

server {
    listen       80;
    server_name  localhost;

    ... (location 等配置) ...
}

2.4.1 listen [ip] [options];

- **作用**: 指定该虚拟主机监听的 **IP 地址和端口**。
- **详解**: `80` 表示监听所有网络接口(0.0.0.0)上的 80 端口。也可以指定 IP,如 `listen 192.168.1.1:80;`。

2.4.2 server_name localhost;

- **作用**: 定义该虚拟主机的域名。
- **详解**: 当客户端请求到达时,Nginx 会检查请求头中的 `Host` 字段,并将其与所有 `server` 块的 `server_name` 进行匹配,来决定由哪个块来处理请求。
    * `localhost` 仅匹配直接通过 `localhost` 访问的请求。
    * 可以设置多个域名,如 `server_name example.com www.example.com;`。
    * 可以使用通配符 `*.example.com` 和正则表达式。
    * 如果只有一个 server 块,则为默认处理块,不论请求头中的 `Host` 字段是什么,都会被默认处理块处理。

2.4.3 listen

  • 作用: 指定该 server 块(虚拟主机)监听哪个网络接口(IP 地址)的哪个端口上的连接请求。
  • 详解:
    • 核心功能: 告诉 Nginx 的 worker 进程,在哪些网络“门”(IP+端口)上等待客户端的连接。
    • 格式: listen [address][:port] [options];
      • address: (可选) 要监听的 IP 地址。省略时默认为 0.0.0.0(所有 IPv4 接口)或 [::](所有 IPv6 接口)。
      • port: (可选) 要监听的端口号。省略时默认为 80(HTTP)或 443(HTTPS)。
      • options: (可选) 附加选项,常见的有:
        • default_server: 将此 server 块标记为该监听端口(IP+端口组合)的默认服务器。当请求头中的 Host 字段不匹配任何 server_name 时,或者请求根本没有 Host 头(如 HTTP/1.0),则由该默认服务器处理。
        • ssl: 表示该端口用于 HTTPS 连接,需要配置 SSL 证书。
        • http2: 启用 HTTP/2 支持(通常与 ssl 一起使用)。
        • reuseport: (Linux 3.9+) 允许每个 worker 进程在同一个端口上监听独立的 socket,可以提高性能(尤其在高并发下)。
    • 一个 server 块可以有多个 listen 指令,以监听多个地址/端口组合(例如同时监听 IPv4 和 IPv6)。
  • 例子:
    1. listen 80;
      • 监听所有网络接口0.0.0.0)上的 80 端口(HTTP)。
      • 这是最常见的配置,服务器上的任何 IP 地址收到 80 端口的 HTTP 请求都会被此 server 块处理(如果 server_name 也匹配)。
    2. listen 127.0.0.1:8080;
      • 监听本地环回接口127.0.0.1)上的 8080 端口
      • 只有来自本机(服务器自身)发往 127.0.0.1:8080 的请求才会被此 server 块处理。外部网络无法访问。
    3. listen 192.168.1.100:443 ssl http2;
      • 监听特定 IP 地址 192.168.1.100 上的 443 端口
      • 启用 SSL/TLS(需要配置证书)和 HTTP/2 协议。
      • 只有发往 192.168.1.100:443 的 HTTPS 请求才会被此 server 块处理。
    4. listen [::]:80;
      • 监听所有 IPv6 接口[::])上的 80 端口(HTTP)。
    5. listen 80 default_server;
      • 监听所有 IPv4 接口的 80 端口。
      • 将此 server 块标记为 80 端口的默认服务器。如果请求的 Host 头不匹配任何其他 server 块的 server_name,或者没有 Host 头,就由这个块处理。

2.4.3 server_name

  • 作用: 定义该 server 块(虚拟主机)负责处理哪些域名(主机名)的请求。Nginx 通过检查客户端请求头中的 Host 字段来决定哪个 server 块应该处理该请求。
  • 详解:
    • 核心功能: 基于域名进行虚拟主机路由。一台物理服务器(一个 IP)可以托管多个网站(多个域名),Nginx 根据 Host 头将它们区分开。
    • 匹配规则(优先级从高到低):
      1. 精确匹配: server_name www.example.com; 只匹配 Host: www.example.com
      2. 通配符(开头): server_name *.example.com; 匹配所有以 .example.com 结尾的域名,如 a.example.com, shop.example.com不匹配 example.com 本身。
      3. 通配符(结尾): server_name example.*; 匹配所有以 example. 开头的域名,如 example.com, example.net, example.org。(这种用法较少见)。
      4. 正则表达式:~ 开头,如 server_name ~^(www\.)?(?<domain>.+)$;。非常灵活,但性能略低于精确匹配和通配符。捕获组(如 (?<domain>.+))可以在配置中通过变量(如 $domain)引用。
      5. 默认服务器: 如果以上都不匹配,则由该监听端口(IP+端口)上标记了 default_serverserver 块处理。如果没有显式指定 default_server,则配置文件中第一个定义该监听端口的 server 块成为默认服务器。
    • 一个 server_name 指令可以包含多个名称,用空格分隔: server_name example.com www.example.com shop.example.com;
    • 特殊名称:
      • _ (下划线):有时用作无效域名的占位符或匹配所有,但不推荐依赖它作为默认服务器。明确使用 default_server 选项更好。
      • localhost:匹配本地环回地址的请求(Host: localhost)。
  • 例子:
    1. server_name localhost;
      • 只处理请求头 Host: localhost 的请求(通常是本地测试)。
    2. server_name example.com www.example.com;
      • 处理请求头 Host: example.comHost: www.example.com 的请求。常用于将主域名和 www 子域名指向同一个网站。
    3. server_name *.example.com;
      • 处理所有子域名为 example.com 的请求,如 Host: blog.example.com, Host: api.example.com, Host: store.example.com不处理 Host: example.com
    4. server_name ~^sub\d\.example\.com$;
      • 使用正则表达式匹配类似 Host: sub1.example.com, Host: sub2.example.com, Host: sub99.example.com 的请求。
    5. server_name example.com www.example.com *.example.com;
      • 组合使用:匹配 example.com, www.example.com 以及所有 *.example.com 子域名。
    6. server_name _; (结合 listen 80 default_server;)
      • 这是一个常见的(但非最规范)设置默认服务器的方式。_ 在这里是一个无效域名,意味着当 Host 头不匹配任何其他 server_name 时,或者没有 Host 头时,这个块作为 80 端口的默认服务器处理请求。更推荐显式使用 default_server 选项。

2.4.5 两者协同工作流程

  1. 客户端发起请求: 客户端(浏览器)向服务器的某个 IP 地址和端口(如 203.0.113.10:80)发送一个 HTTP 请求。请求头中包含 Host: www.example.com
  2. Nginx 接收连接: Nginx worker 进程在配置的监听地址/端口(如 listen 203.0.113.10:80;listen 80;)上接收到该连接。
  3. 匹配监听端口: Nginx 首先找出所有监听了该连接目标 IP+端口(203.0.113.10:80)的 server 块。如果该 IP 是服务器上的一个具体地址,配置了 listen 203.0.113.10:80;listen 80;(监听所有 IP)的块都会被考虑。如果 IP 是 0.0.0.0,则监听该端口的所有块都会被考虑。
  4. 匹配域名 (server_name): 在上一步筛选出的 server 块列表中,Nginx 检查请求头中的 Host 字段(www.example.com),并尝试与每个块的 server_name 指令进行匹配(按优先级:精确 > 通配符开头 > 通配符结尾 > 正则)。
  5. 选择处理块:
    • 如果找到一个精确匹配(如 server_name www.example.com;),则使用该 server 块处理请求。
    • 如果找到通配符匹配(如 server_name *.example.com;),则使用该块。
    • 如果找到正则匹配(如 server_name ~^www\..+\.com$;),则使用该块。
    • 如果没有匹配,则使用该监听端口(203.0.113.10:80)上标记为 default_serverserver 块。如果没有显式标记,则使用该端口上配置文件中第一个出现的 server 块。
  6. 处理请求: 选定的 server 块中的配置(如 root, location, proxy_pass 等)被用来处理该请求并生成响应。

总结:

  • listen 定义了 Nginx 在哪里(IP:Port)接收请求。
  • server_name 定义了 Nginx 根据什么(请求的 Host 头)来决定由哪个配置块来处理到达该地址/端口的请求。
  • 它们共同实现了基于名称的虚拟主机,是 Nginx 配置多网站的基础。理解它们的匹配规则和优先级对于正确配置复杂的站点至关重要。

2.5 第五部分:location 块 (Location Context)

location 块嵌套在 server 块内,用于根据请求的 URI(即域名后面的路径部分)来指定不同的处理规则。

location / {
    root   html;
    index  index.html index.htm;
}
  • 修饰符:
    • = 精确匹配(最高优先级)。
    • ~ 正则匹配(区分大小写)。
    • ~* 正则匹配(不区分大小写)。
    • ^~ 如果匹配此前缀则立即使用(跳过正则检查)。
    • 无修饰符:前缀匹配,按最长前缀选择。
  • 示例:
location = /exact { ... }        # 只匹配 /exact
location ^~ /images/ { ... }     # 优先匹配 /images/ 前缀
location ~ \.php$ { ... }       # 正则匹配 PHP 后缀
location / { ... }              # 通用

2.5.1 location / { … }

- **作用**: 匹配所有以 `/` 开头的 URI,即**所有请求**。
- **详解**: `location` 后面的字符串可以用前缀匹配(如 `/images/`),正则表达式匹配(`~ \.php$`)或精确匹配(`= /exact-path`)。

2.5.2 root html;

- **作用**: 定义该 location 的**根目录**。
- **详解**: `html` 是一个相对路径,相对于 Nginx 的**安装目录**。所以,对于请求 `http://localhost/index.html`,Nginx 会去寻找 `{nginx安装目录}/html/index.html` 文件。

2.5.3 rootalias 区别

  • root /var/www/site; location /static/ { root /var/www/site; } 当请求 /static/js/a.js 时实际文件路径为 /var/www/site/static/js/a.js
  • alias /data/static/; location /static/ { alias /data/static/; } 请求 /static/js/a.js 时文件路径为 /data/static/js/a.jsalias 会替换匹配的 location 前缀)。alias 需要注意结尾斜杠与 location 的匹配。

2.5.3 index index.html index.htm;

- **作用**: 定义默认索引文件。
- **详解**: 当客户端请求以 `/` 结尾时(即访问一个目录),Nginx 会按顺序尝试查找并返回 `index.html` 或 `index.htm` 文件。
error_page   500 502 503 504  /50x.html;
location = /50x.html {
    root   html;
}

2.5.4 error_page 500 502 503 504 /50x.html;

- **作用**: 定义当出现特定错误状态码时,要返回给客户端的自定义错误页面。
- **详解**: 当服务器内部错误(500)、网关错误(502/504)等发生时,Nginx 不会返回默认的错误页,而是会内部重定向到 `/50x.html` 这个 URI。

2.5.5 location = /50x.html { … }

- **作用**: 精确匹配 (`=`) `/50x.html` 这个 URI。
- **详解**: 这个块专门用于处理上面 `error_page` 指令产生的内部重定向请求,从 `html` 目录下找到 `50x.html` 文件并返回。

2.5.6 代理后端(proxy_pass)关键点与常见坑

  • proxy_pass http://127.0.0.1:8080/;proxy_pass http://127.0.0.1:8080; 的行为不同(结尾斜杠影响 URI 拼接):
    • 如果 location 是 location /api/ { proxy_pass http://backend/; },请求 /api/x 会转发为 /x 到后端。
    • 如果 proxy_pass http://backend;(没有尾 /),请求 /api/x 会转发为 /api/x 到后端(保留 location 部分)。
      这是新手常踩的坑。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐