一学就会!Nginx 配置与优化全攻略

367 阅读12分钟

一学就会!Nginx 配置与优化全攻略

Nginx 是一款高性能的 web 服务器,也可以作为反向代理服务器、负载均衡器、HTTP缓存等。它是基于事件驱动架构的,设计上追求高并发、高性能,同时具有轻量化的特点,非常适合处理大量并发连接。

1. Nginx 的基本功能

Nginx 主要有以下几种常见的使用方式:

  • Web 服务器:作为静态资源的提供者。
  • 反向代理服务器:将请求转发到其他服务器上进行处理,然后将响应返回给客户端。
  • 负载均衡器:将流量分发到多台服务器上,确保系统的高可用性和高性能。
  • HTTP缓存:将静态内容缓存到内存或硬盘上,减少服务器的压力。

2. Nginx 的特点

Nginx 主要有以下几个特点:

高性能

Nginx 采用事件驱动模型,可以处理成千上万的并发连接。每个连接只占用少量内存,相较于传统的多进程/多线程模型,效率要高很多。

低内存消耗

Nginx 的工作原理是基于事件驱动和异步处理的,不同于 Apache 的进程/线程模型,Nginx 通过共享进程和事件驱动来节省内存。

可扩展性强

Nginx 支持动态模块加载,因此可以根据需要扩展其功能,比如负载均衡、SSL支持等。

反向代理和负载均衡

Nginx 内置了非常强大的反向代理和负载均衡功能,可以将请求分发到多台后端服务器上,常用于 Web 应用的负载均衡和容灾。

易于配置

Nginx 的配置文件语法简单明了,层级结构清晰,容易理解。通过少量的配置就能实现强大的功能。

3. Nginx 的工作原理

Nginx 基于事件驱动和异步处理模型来实现高并发的连接。其工作流程可以分为以下几个阶段:

  • 接收请求:当客户端请求到达 Nginx 时,Nginx 的 master 进程将请求分配给 worker 进程。worker 进程是多进程模型,它们处理具体的请求。
  • 处理请求:worker 进程根据配置文件中的规则,判断请求的内容,然后转发请求到相应的后端服务器或直接返回响应。
  • 响应请求:worker 进程将处理结果返回给客户端。

在处理请求时,Nginx 会根据请求的 URL 地址来匹配相关的配置规则,例如是否是静态文件请求,如果是,则直接返回文件内容;如果是动态请求,则会通过代理转发到应用服务器(如 PHP、Java、Node.js 等)进行处理。

4. 常见 Nginx 配置

Nginx 的配置文件通常位于 /etc/nginx/nginx.conf,里面包含多个配置块,主要包括以下几个部分:

1) 全局配置

Nginx 的 全局配置 是配置文件的最上层部分,用于定义一些全局性的参数,比如进程数、日志设置、PID 文件等。全局配置位于 Nginx 配置文件的开头部分,通常在 nginx.conf 文件中。全局配置会影响 Nginx 进程的整体行为,因此需要谨慎配置。

下面是 Nginx 全局配置常见的项及其解释:

1. worker_processes

  • 作用:定义 Nginx 启动的工作进程数。这个值直接影响到 Nginx 处理请求的并发能力。
  • 说明:通常情况下,工作进程数设置为 CPU 核数。可以通过 auto 来自动根据系统的 CPU 核心数来设置进程数。
worker_processes 1;    # 设置为1个进程
worker_processes auto;  # 自动设置为系统的 CPU 核心数

2. worker_cpu_affinity

  • 作用:控制工作进程的 CPU 亲和性(即将进程绑定到特定的 CPU 核心上)。
  • 说明:这个选项常用于优化多核系统上的性能。
worker_cpu_affinity 0001 0010;  # 绑定进程到特定的 CPU 核心

3. worker_connections

  • 作用:每个工作进程最大能够打开的连接数。这个参数决定了 Nginx 可以同时处理的最大连接数。
  • 说明:通常设置较大的值,以确保高并发场景下的性能。
worker_connections 1024;  # 每个工作进程最大连接数

4. pid

  • 作用:指定存储 Nginx 主进程 PID(进程ID)文件的路径。
  • 说明:Nginx 启动时,会将主进程的 PID 写入此文件。通常用于进程管理,像停止 Nginx 等操作时会用到 PID 文件。
pid /var/run/nginx.pid;  # 设置 PID 文件路径

5. error_log

  • 作用:指定错误日志的存储路径和日志级别。
  • 说明:Nginx 会记录发生的错误、警告和调试信息。默认日志级别是 error,可以根据需要设置为 infowarndebug 等。
error_log /var/log/nginx/error.log warn;  # 设置错误日志路径和级别

6. log_format

  • 作用:定义日志格式。可以定制 Nginx 访问日志的格式。
  • 说明:通常情况下可以根据业务需要调整日志格式,比如添加客户端的 IP 地址、请求的响应时间等。
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';  # 设置自定义日志格式

7. access_log

  • 作用:指定访问日志的路径和日志格式。
  • 说明:这个配置决定了 Nginx 访问日志的存储位置。可以通过 log_format 自定义日志格式,也可以指定 off 来禁用访问日志。
access_log /var/log/nginx/access.log main;  # 设置访问日志路径及格式

8. user

  • 作用:指定 Nginx 进程的运行用户和用户组。
  • 说明:通常设置为运行 Nginx 的普通用户,如 www-datanginx,以保证安全性。
user nginx;  # 设置运行 Nginx 的用户

9. worker_rlimit_nofile

  • 作用:设置每个工作进程可以打开的最大文件描述符数量。
  • 说明:对于高并发环境,这个参数非常重要,因为它直接影响到每个进程可以处理的并发连接数。
worker_rlimit_nofile 65535;  # 设置最大文件描述符数量

10. include

  • 作用:用于引入其他配置文件。Nginx 配置文件通常会使用 include 指令来引入外部的配置文件,从而实现配置的模块化和组织性。
  • 说明:例如,引入 MIME 类型配置、虚拟主机配置等。
include /etc/nginx/mime.types;  # 引入 MIME 类型配置
include /etc/nginx/sites-enabled/*;  # 引入所有虚拟主机配置

11. events

  • 作用:配置与事件相关的设置,例如事件驱动模型的类型、每个 worker 进程的最大连接数等。虽然 events 配置通常被认为是全局配置的一部分,但它也属于 http 模块的子配置块。
events {
    worker_connections 1024;  # 每个进程的最大连接数
}

12. sendfile

  • 作用:启用或禁用 sendfile() 系统调用,这是 Nginx 提供高效文件传输的一种方式。
  • 说明:开启 sendfile 可以提升大文件传输性能,尤其是在文件传输时。
sendfile on;  # 启用 sendfile

13. tcp_nopushtcp_nodelay

  • 作用:这两个选项用于调优 TCP 连接的传输效率。

    • tcp_nopush:允许将多个小包合并为一个大包发送,以减少网络中的包数。
    • tcp_nodelay:关闭 Nagle 算法,保证每个数据包立即发送,适用于低延迟要求的场景。
tcp_nopush on;  # 启用合并小包功能
tcp_nodelay on;  # 禁用 Nagle 算法

14. client_max_body_size

  • 作用:限制客户端请求的最大体积(例如 POST 请求的大小)。
  • 说明:如果客户端上传的文件超过这个大小限制,Nginx 会返回 413 错误(Request Entity Too Large)。
client_max_body_size 10M;  # 设置客户端请求的最大体积为 10MB

15. keepalive_timeout

  • 作用:设置持久连接的超时时间,即客户端与服务器之间保持连接的时间。
  • 说明:保持连接时间过长会占用更多的资源,因此可以根据实际情况进行调整。
keepalive_timeout 65;  # 设置连接保持时间为 65 秒

总结

Nginx 的全局配置部分主要涉及进程管理、日志管理、性能调优等内容。这些配置对于优化 Nginx 的性能和稳定性至关重要。在配置 Nginx 时,根据不同的硬件环境和业务需求合理调整这些配置,可以最大化地提升服务器的性能和响应速度。

2) Events 块

在 Nginx 配置文件中,events 块用于定义与事件驱动模型相关的配置,它负责控制工作进程如何处理连接。events 块主要用于设置连接处理的模式、最大连接数等,确保 Nginx 能高效地处理高并发的请求。

events 块是 Nginx 配置文件中的一个关键部分,通常位于配置文件的最上面,紧跟在全局配置之后。下面是 events 块的常见配置项。

events 块配置示例

events {
    worker_connections 1024;  # 每个工作进程可以处理的最大连接数
    use epoll;  # 选择事件驱动模型
    multi_accept on;  # 启用多连接接受
}

常见配置项详解

1. worker_connections
  • 作用:每个工作进程所能处理的最大连接数。
  • 说明:此设置决定了每个工作进程能同时处理的最大连接数,默认情况下,如果没有设置过多的 worker_processes,可以通过增加 worker_connections 来提高并发连接数。
worker_connections 1024;  # 每个工作进程允许最多 1024 个连接
  • 注意:如果你设置了 worker_processesauto,则 Nginx 会根据 CPU 核心数自动选择进程数,这样可以根据系统资源调整连接数。
2. use
  • 作用:定义 Nginx 使用的事件驱动模型。

  • 说明

    :Nginx 使用事件驱动模型来处理客户端请求,可以选择不同的事件模型来优化性能。常见的事件驱动模型有:

    • epoll:适用于 Linux 系统,特别是高并发时效果显著。
    • kqueue:适用于 BSD 和 macOS 系统。
    • select:适用于支持 select 系统调用的系统。
    • poll:类似于 select,但是适用于更多平台。
use epoll;  # 使用 epoll 事件模型(适用于 Linux)
  • 推荐:在 Linux 上通常使用 epoll,它能有效处理大量并发连接,减少了系统开销。
3. multi_accept
  • 作用:控制每个工作进程是否同时接受多个连接。
  • 说明:默认情况下,Nginx 在每次事件循环中只接受一个连接。如果启用 multi_accept,每个工作进程会尽可能地接收所有待处理的连接,从而提高处理效率。
multi_accept on;  # 启用每次接受多个连接
  • 注意:在高并发的情况下,启用此选项可以提高性能,但需要结合 worker_connections 和系统负载来进行合理配置。
4. accept_mutex
  • 作用:控制多个工作进程是否共享接受连接的互斥锁。
  • 说明:Nginx 在多进程模式下,会通过互斥锁来保证不会出现多个进程同时处理同一个连接。如果开启 accept_mutex,每个 worker 进程会尝试抢占锁来接收新连接。
accept_mutex on;  # 启用接收连接的互斥锁
  • 默认值:通常情况下是开启的。可以关闭 accept_mutex 来加快连接的接受速度,但有时会增加竞争,导致性能下降。
5. accept_mutex_delay
  • 作用:控制每个工作进程等待获取 accept_mutex 锁的时间。
  • 说明:这是 accept_mutex 启用时使用的超时时间,决定了每个工作进程等待锁的时长。如果超过这个时间,就会放弃当前连接等待,去接收下一个连接。
accept_mutex_delay 500ms;  # 设置等待锁的时间为 500 毫秒
6. worker_aio_requests
  • 作用:控制异步 I/O 请求的最大数量。
  • 说明:当使用异步 I/O 操作时,worker_aio_requests 用于设置每个工作进程同时进行的最大异步 I/O 请求数。这个参数用于提高 I/O 操作的性能。
worker_aio_requests 65535;  # 设置每个工作进程最大异步请求数

7. worker_shutdown_timeout

  • 作用:设置工作进程关闭时的超时时间。
  • 说明:Nginx 在重新加载配置文件或停止时,会优雅地关闭所有工作进程。在关闭过程中,worker_shutdown_timeout 定义了最大等待时间。
worker_shutdown_timeout 60s;  # 设置工作进程关闭时最大等待 60 秒

8. worker_processes

  • 作用:虽然 worker_processes 配置项通常在全局配置部分定义,但也可以在 events 块中定义,它指定了 Nginx 启动的工作进程数。通过配置 worker_processes,可以控制 Nginx 并发处理能力的大小。
  • 说明:通常情况下,可以设置为 auto 来自动匹配 CPU 核心数,从而获得最佳性能。
worker_processes auto;  # 根据系统的 CPU 核心数自动设置进程数

完整示例:events 块配置

events {
    worker_processes auto;  # 根据 CPU 核心数自动设置工作进程数
    worker_connections 1024;  # 每个工作进程最大连接数为 1024
    use epoll;  # 使用 epoll 事件驱动模型(适用于 Linux)
    multi_accept on;  # 启用多连接接收模式
    accept_mutex on;  # 启用连接接受互斥锁
    accept_mutex_delay 500ms;  # 设置等待锁的最大时间为 500 毫秒
}

总结

events 块是 Nginx 配置文件中非常重要的一部分,它与工作进程如何处理并发连接密切相关。通过合理配置 worker_connectionsusemulti_accept 等参数,可以优化 Nginx 在高并发情况下的性能。根据不同的操作系统和业务需求,可以选择适当的事件驱动模型和连接处理模式。

3) HTTP 块

http 模块是 Nginx 的核心模块之一,几乎所有的 Nginx 配置和功能都与 http 模块相关。它提供了 Nginx 处理 HTTP 请求和响应的功能,包括请求转发、负载均衡、反向代理、静态资源处理、SSL 加密等。几乎所有的 Web 服务器相关配置都需要在 http 块内进行配置。

http 模块是 Nginx 配置文件中非常重要的一部分,它包含了很多功能模块和配置指令。下面我会详细介绍 http 模块的一些常见配置项。

http 模块的常见配置项

1. http

http 块是一个最顶层的配置块,包含了整个 HTTP 服务器的相关配置。这个块里面的指令通常会影响整个 Web 服务的处理方式。所有关于 HTTP 请求和响应的配置都必须放在这个块中。

http {
    # HTTP 模块相关的配置项
}
2. server

server 块用于定义虚拟主机(即 Nginx 的站点配置)。每个 server 块可以配置不同的监听端口、域名、SSL 设置、反向代理等。一个 http 块下可以包含多个 server 块。

server {
    listen 80;
    server_name www.example.com;
    location / {
        root /var/www/html;
        index index.html;
    }
}
3. location

location 块是 server 块的子配置块,用于匹配客户端请求的 URI,并对不同的 URI 路径应用不同的配置。可以使用正则表达式或前缀匹配来处理请求。

location / {
    root /var/www/html;
    index index.html;
}
​
location /images/ {
    root /var/www/assets;
}

4. 主要的配置项与功能

1. listen
  • 作用:指定该 server 块监听的端口和地址。
  • 说明:常见的值包括 80(HTTP 协议)、443(HTTPS 协议),以及 unix 套接字等。
listen 80;        # 监听 80 端口
listen 443 ssl;   # 监听 443 端口并启用 SSL
2. server_name
  • 作用:指定服务器的域名或 IP 地址,用来匹配请求的 Host 头。
  • 说明:可以是一个或多个域名,也可以使用通配符。
server_name example.com www.example.com;  # 配置域名
server_name *.example.com;  # 使用通配符
3. rootalias
  • 作用:定义静态文件的根目录路径。root 配置项指向的目录是该路径的实际根目录,alias 则通常用于匹配请求路径。
  • root 示例
location / {
    root /var/www/html;  # 请求根路径时,返回 /var/www/html 目录下的文件
}
  • alias 示例
location /images/ {
    alias /var/www/images/;  # 请求 /images/ 路径时,返回 /var/www/images/ 目录下的文件
}
4. index
  • 作用:定义该目录的默认首页文件。
  • 说明:当请求目录而没有指定具体文件时,Nginx 会自动返回此配置指定的文件。
index index.html index.htm;  # 配置默认首页文件
5. try_files
  • 作用:尝试按顺序查找文件,如果文件存在,则返回该文件;如果文件不存在,则执行其他操作(如返回 404 错误或跳转到其他位置)。
  • 说明:通常用于静态文件的查找,支持多种路径查找。
location / {
    try_files $uri $uri/ =404;  # 如果请求的文件不存在,则返回 404 错误
}
6. access_logerror_log
  • 作用:设置访问日志和错误日志的路径以及日志格式。
  • 说明access_log 用于记录客户端请求,error_log 用于记录服务器的错误信息。
access_log /var/log/nginx/access.log combined;  # 设置访问日志路径和格式
error_log /var/log/nginx/error.log warn;  # 设置错误日志路径和级别
7. gzip
  • 作用:启用 Gzip 压缩,以减少传输的数据量,提高性能。
  • 说明:可以压缩文本文件、HTML 文件、CSS 和 JavaScript 文件等。
gzip on;  # 启用 Gzip 压缩
gzip_types text/plain text/css application/javascript;  # 指定压缩类型
gzip_min_length 1000;  # 设置最小压缩文件大小
8. client_max_body_size
  • 作用:设置客户端请求体的最大允许大小。
  • 说明:常用于上传文件时,限制客户端上传数据的大小,防止过大的请求导致服务器负担过重。
client_max_body_size 10M;  # 设置最大请求体为 10MB
9. proxy_pass
  • 作用:设置反向代理目标地址。通常用于负载均衡和将请求转发到后端服务器。
  • 说明:可以配置为 HTTP、HTTPS 或 Unix 套接字地址。
location /api/ {
    proxy_pass http://127.0.0.1:5000;  # 将 /api/ 路径的请求转发到后端的 API 服务器
}
10. ssl_certificatessl_certificate_key
  • 作用:配置 HTTPS 服务的 SSL 证书及私钥。
  • 说明:启用 HTTPS 服务时,必须配置这两个项。
server {
    listen 443 ssl;
    ssl_certificate /etc/nginx/ssl/example.com.crt;  # SSL 证书路径
    ssl_certificate_key /etc/nginx/ssl/example.com.key;  # SSL 私钥路径
}
11. rewrite
  • 作用:用于 URL 重写,可以基于正则表达式对请求的 URL 进行修改。
  • 说明:可以在 locationserver 块内使用。
rewrite ^/oldpath/(.*)$ /newpath/$1 permanent;  # 永久重定向
12. add_header
  • 作用:添加响应头部信息。可以在 httpserverlocation 等块内使用。
  • 说明:常用于设置 CORS、缓存控制等 HTTP 头。
add_header X-Content-Type-Options "nosniff";  # 防止 MIME 类型嗅探
add_header Cache-Control "no-cache, no-store, must-revalidate";  # 禁止缓存

完整示例:http 块配置

http {
    # 启用 Gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/javascript;
​
    # 配置访问日志
    access_log /var/log/nginx/access.log combined;
​
    # 配置最大请求体大小
    client_max_body_size 10M;
​
    # 配置虚拟主机
    server {
        listen 80;
        server_name example.com www.example.com;
​
        # 静态文件配置
        location / {
            root /var/www/html;
            index index.html;
        }
​
        # 反向代理配置
        location /api/ {
            proxy_pass http://127.0.0.1:5000;
        }
    }
​
    # 配置 SSL(HTTPS)
    server {
        listen 443 ssl;
        server_name secure.example.com;
​
        ssl_certificate /etc/nginx/ssl/example.com.crt;
        ssl_certificate_key /etc/nginx/ssl/example.com.key;
​
        location / {
            root /var/www/html;
            index index.html;
        }
    }
}

总结

http 模块是 Nginx 中最为重要的模块之一,负责处理所有与 HTTP 协议相关的配置。通过配置 serverlocationproxy_passsslrewrite 等指令,可以轻松地实现负载均衡、反向代理、静态资源服务、SSL 加密等功能。在实际项目中,http 模块的配置是大多数 Nginx 配置的核心部分。

4) Server 块

一个 server 块表示一个虚拟主机,可以有多个 server 块来配置不同的域名、端口等。每个 server 块可以包含多个 location 配置来指定不同的路径规则。

server {
    listen 80;  # 监听 80 端口
    server_name example.com;  # 设置域名
​
    location / {
        root /var/www/html;  # 指定根目录
        index index.html index.htm;  # 指定默认页面
    }
​
    # 配置反向代理
    location /api/ {
        proxy_pass http://backend-server:5000;
    }
}

1. location 路由配置规则

location 用于匹配客户端请求的 URI,它是 Nginx 路由请求的核心机制。location 可以根据请求的路径执行不同的操作,如返回静态文件、反向代理请求、重写 URL 等。

location 的匹配规则

Nginx 使用两种方式来匹配 location 块:

  • 前缀匹配(Prefix Matching)
  • 正则匹配(Regular Expression Matching)
1.1. 前缀匹配

前缀匹配是最常见的匹配方式。当请求的 URI 与 location 后的字符串匹配时,Nginx 会执行该 location 块中的配置。前缀匹配的规则是:Nginx 会按照配置文件中 location 块的顺序逐个检查,选择第一个匹配的 location 块进行处理。

nginx复制编辑location /images/ {
    root /var/www/assets;
}

这个配置表示:当请求路径以 /images/ 开头时,Nginx 会将该请求转发到 /var/www/assets/images/ 目录下查找静态文件。

1.2. 正则匹配

正则匹配使用 ~~* 来定义,~ 表示大小写敏感匹配,~* 表示大小写不敏感匹配。正则匹配具有更高的优先级,通常在前缀匹配之后进行判断。

nginx复制编辑location ~* .(jpg|jpeg|png|gif)$ {
    root /var/www/images;
}

这个配置表示:当请求路径以 .jpg.jpeg.png.gif 结尾时,Nginx 会将请求的文件返回 /var/www/images 目录下。

1.3. 前缀匹配和正则匹配的优先级
  • Nginx 会首先匹配前缀匹配
  • 然后,Nginx 会匹配正则匹配,其中按匹配顺序执行(即最先写的正则匹配会优先执行)。
  • 对于正则匹配,最后匹配到的规则会被执行。

2. Nginx 中的 locationproxy_pass 配置:反斜杠的区别

Nginx 配置中的 locationproxy_pass 是两个关键指令,它们都使用反斜杠(/)来定义路径。反斜杠的存在与否,决定了如何匹配请求路径以及如何将请求转发到后端服务器。

我们将以 /api 为例,讨论不同配置下的行为。


1. location 指令中反斜杠的作用

1.1. location /api/(加反斜杠)
location /api/ {
    proxy_pass http://backend-server;
}
  • 匹配规则:该配置会匹配所有以 /api/ 为前缀的请求路径。

  • 转发行为:

    • 例如请求路径 /api/users/123,Nginx 会将请求转发到 http://backend-server/api/users/123保留 /api/ 前缀

总结

  • 使用加反斜杠的 location /api/ 时,Nginx 会保留路径中的 /api/ 前缀,转发到后端时路径不会发生变化。
1.2. location /api(不加反斜杠)
location /api {
    proxy_pass http://backend-server;
}
  • 匹配规则:该配置会匹配所有以 /api 为前缀的请求路径,但不强制要求后缀跟 /,即它会匹配像 /api/apicustomers/api/123 等路径。

  • 转发行为:

    • 例如请求路径 /api/users/123,Nginx 会将请求转发到 http://backend-server/users/123去掉 /api 前缀

总结

  • 使用不加反斜杠的 location /api 时,Nginx 会去掉请求路径中的 /api 部分,转发时会去掉这个前缀。

2. proxy_pass 指令中反斜杠的作用

2.1. proxy_pass http://backend-server;(不加反斜杠)
location /api/ {
    proxy_pass http://backend-server;
}
  • 转发行为:

    • 例如请求 /api/users/123 时,Nginx 会将请求转发到 http://backend-server/api/users/123保持 /api/ 前缀
    • 这里,没有反斜杠proxy_pass 会将整个请求路径(包括 /api/)转发到目标服务器。

总结

  • proxy_pass 后不加反斜杠时,路径会 保持 /api/ 前缀,转发的 URL 会包括 /api/
2.2. proxy_pass http://backend-server/;(加反斜杠)
location /api/ {
    proxy_pass http://backend-server/;
}
  • 转发行为:

    • 例如请求 /api/users/123 时,Nginx 会将请求转发到 http://backend-server/users/123去掉了 /api 前缀
    • 这里,加了反斜杠proxy_pass 会去掉 /api/ 前缀,只将路径 /users/123 传递给后端服务器。

总结

  • proxy_pass 后加反斜杠时,路径会去掉 location 中定义的 /api/ 前缀,只将剩下的部分 /users/123 转发到目标服务器。

3. 综合对比:加与不加反斜杠对路径匹配与转发的影响

配置请求路径location 匹配规则转发到目标服务器的 URL
location /api/ { proxy_pass http://backend-server; }/api/users/123匹配 /api/ 前缀http://backend-server/api/users/123
location /api/ { proxy_pass http://backend-server/; }/api/users/123匹配 /api/ 前缀http://backend-server/users/123
location /api { proxy_pass http://backend-server; }/api/users/123匹配 /api 前缀http://backend-server/users/123
location /api { proxy_pass http://backend-server/; }/api/users/123匹配 /api 前缀http://backend-server/users/123

4. 适用场景

4.1. 需要保留路径前缀时(不加反斜杠)
  • 当你的目标服务器需要 保留路径前缀(如 /api),且不希望该前缀被去掉时,使用 proxy_pass 后不加反斜杠 的配置。

  • 示例场景

    • 目标服务器需要完整的路径 /api/users/123,以便正确处理请求。
location /api/ {
    proxy_pass http://backend-server;
}
  • 结果/api/users/123 会被转发到 http://backend-server/api/users/123
4.2. 需要去掉路径前缀时(加反斜杠)
  • 当你的目标服务器 不需要路径前缀(如 /api),并且你希望去掉这个前缀时,使用 proxy_pass 后加反斜杠 的配置。

  • 示例场景

    • 目标服务器只关心 /users/123 路径,而不是 /api/users/123
location /api/ {
    proxy_pass http://backend-server/;
}
  • 结果/api/users/123 会被转发到 http://backend-server/users/123/api/ 前缀被去掉。
4.3. location /api(不加反斜杠)
  • 如果希望匹配 /api 开头的路径,并且不需要考虑是否存在额外的 /,使用 location /api 可以匹配多种路径,如 /api, /apicustomers, /api123 等。结合 proxy_pass 的使用,通常会去掉 /api 前缀,转发给后端。
location /api {
    proxy_pass http://backend-server;
}
  • 结果/api/users/123 会被转发到 http://backend-server/users/123,去掉了 /api 前缀。

结论

  • location 中的反斜杠:决定了如何匹配请求路径。加反斜杠(/api/)会更严格匹配路径并保留前缀;不加反斜杠(/api)会匹配路径以 /api 开头的任何请求。
  • proxy_pass 中的反斜杠:决定了请求路径如何被转发到后端。加反斜杠(http://backend-server/)会去掉 location 中定义的前缀;不加反斜杠(http://backend-server)会保留路径前缀。

通过合理组合 locationproxy_pass 中的反斜杠配置,可以精确控制请求的路径匹配和转发行为,满足不同的路由需求。

3. 常见场景配置

3.1. 静态文件缓存配置

为了提高静态文件的加载速度,可以启用浏览器缓存功能。通过配置 expirescache-control 头,Nginx 可以指示浏览器缓存静态资源。

location /images/ {
    root /var/www;
    expires 30d;  # 设置缓存过期时间为 30 天
    add_header Cache-Control "public, max-age=2592000";  # 公开缓存,最大缓存时间为 30 天
}
  • expires 用于设置静态文件的过期时间。
  • Cache-Control 可以进一步控制缓存策略,如 no-cachemax-age 等。
3.2. 跨域配置(CORS)

跨域资源共享(CORS)允许浏览器从不同域加载资源。在 Nginx 中,可以通过 add_header 指令来设置 CORS 响应头。

location /api/ {
    root /var/www;
    add_header Access-Control-Allow-Origin *;  # 允许所有域访问
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';  # 允许的 HTTP 方法
    add_header Access-Control-Allow-Headers 'Origin, X-Requested-With, Content-Type, Accept, Authorization';  # 允许的请求头
}
  • Access-Control-Allow-Origin * 允许所有域的请求。
  • Access-Control-Allow-MethodsAccess-Control-Allow-Headers 用于指定允许的 HTTP 方法和请求头。
3.3. 反向代理配置(proxy_pass

proxy_pass 用于将请求转发到后端服务器或服务。Nginx 可以作为反向代理服务器,将请求转发到其他应用服务器(如 Node.js、Java 后端等)。

location /api/ {
    proxy_pass http://localhost:3000;  # 将请求转发到本地的 3000 端口
    proxy_set_header Host $host;  # 保持原始的 Host 头部
    proxy_set_header X-Real-IP $remote_addr;  # 传递客户端的真实 IP 地址
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 传递请求的转发链
}
  • proxy_pass:指定反向代理的地址,可以是 IP 地址、域名,或 Unix 套接字地址。
  • proxy_set_header:设置 HTTP 请求头部,保证请求的原始信息(如客户端 IP、Host 等)不会丢失。
3.4. 使用 rewrite 进行 URL 重写

rewrite 指令用于修改请求的 URL 路径或进行重定向。常用于将老的 URL 转向新的 URL。

location /old-path/ {
    rewrite ^/old-path/(.*)$ /new-path/$1 permanent;  # 永久重定向
}
  • rewrite 指令使用正则表达式将请求的路径 /old-path/* 重定向到 /new-path/*
3.5. 限制访问

你可以根据请求的 IP 地址来限制访问:

location /admin/ {
    deny all;  # 禁止所有 IP 访问
    allow 192.168.1.0/24;  # 只允许指定 IP 地址段的访问
}

总结

  • location 配置用于匹配请求的路径,并执行相应的操作。它可以通过前缀匹配或正则表达式匹配请求 URI。
  • location /gogs/location /gogs 的区别:加反斜杠会使路径匹配更加严格,并且可能影响 URL 的重写和文件查找行为。
  • 常见的应用场景包括:静态文件缓存、跨域配置(CORS)、反向代理 (proxy_pass)、URL 重写 (rewrite)、以及基于 IP 的访问控制。

5. Nginx 的常见用法

1. 反向代理

反向代理是 Nginx 最常用的应用之一,主要用于将客户端请求转发到后台的应用服务器,通常用于提升性能、负载均衡或隐藏后端服务的细节。

示例配置:
server {
    listen 80;
    server_name www.example.com;
​
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
解释:
  • proxy_pass:将请求转发到 http://127.0.0.1:8080
  • proxy_set_header:设置请求头,确保传递客户端的真实 IP 地址、主机名和协议等信息给后端服务器。

2. 负载均衡

Nginx 还可以作为负载均衡器,将流量分发到多个后端服务器。常见的负载均衡策略有轮询、加权轮询和 IP 哈希等。

轮询负载均衡:
http {
    upstream backend {
        server 192.168.1.1;
        server 192.168.1.2;
        server 192.168.1.3;
    }
​
    server {
        listen 80;
        server_name www.example.com;
​
        location / {
            proxy_pass http://backend;
        }
    }
}
解释:
  • upstream:定义一个名为 backend 的负载均衡组,包含多个后端服务器。
  • proxy_pass http://backend:所有请求都会被转发到 backend 组中的服务器。
加权负载均衡:
http {
    upstream backend {
        server 192.168.1.1 weight=3;
        server 192.168.1.2;
    }
​
    server {
        listen 80;
        server_name www.example.com;
​
        location / {
            proxy_pass http://backend;
        }
    }
}
解释:
  • 通过 weight 参数,可以设置服务器的权重,控制流量分配。例如,192.168.1.1 的权重为 3,192.168.1.2 的权重为 1,流量将按 3:1 的比例分配。

3. 缓存静态资源

Nginx 可以非常高效地缓存静态资源,如图片、JS 和 CSS 文件,以减少后端服务器的负担,提高性能。

示例配置:
server {
    listen 80;
    server_name www.example.com;
​
    location /images/ {
        root /var/www/html;
        expires 30d;
        add_header Cache-Control "public";
    }
}
解释:
  • expires 30d:设置缓存过期时间为 30 天。
  • Cache-Control:添加缓存控制头,指示客户端缓存该文件。
进一步优化:使用 proxy_cache 缓存反向代理的内容
http {
    proxy_cache_path /tmp/cache levels=1:2 keys_zone=cache_zone:10m max_size=1g inactive=60m use_temp_path=off;
​
    server {
        listen 80;
        server_name www.example.com;
​
        location / {
            proxy_cache cache_zone;
            proxy_cache_valid 200 1h;
            proxy_pass http://backend;
        }
    }
}
解释:
  • proxy_cache_path:定义缓存的存储路径及相关配置(如最大缓存大小、缓存失效时间等)。
  • proxy_cache:启用代理缓存。
  • proxy_cache_valid:设置缓存有效时间。

4. 跨域(CORS)配置

在一些前后端分离的应用中,可能会遇到跨域请求问题。Nginx 可以通过设置 CORS 头来解决这个问题。

示例配置:
server {
    listen 80;
    server_name www.example.com;
​
    location /api/ {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
        add_header Access-Control-Allow-Headers 'Content-Type, Authorization';
        
        if ($request_method = 'OPTIONS') {
            return 204;
        }
​
        proxy_pass http://backend;
    }
}
解释:
  • Access-Control-Allow-Origin:允许所有域访问。
  • Access-Control-Allow-Methods:允许的 HTTP 方法。
  • Access-Control-Allow-Headers:允许的请求头。
  • OPTIONS 请求处理:CORS 预检请求是 OPTIONS 请求,因此需要特别处理。

5. SSL 配置

Nginx 可以处理 HTTPS 请求,通过 SSL/TLS 加密协议保护传输数据的安全性。

示例配置(生成 SSL 证书并启用 HTTPS):
server {
    listen 443 ssl;
    server_name www.example.com;
​
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
​
    location / {
        proxy_pass http://backend;
    }
}
​
server {
    listen 80;
    server_name www.example.com;
    return 301 https://$host$request_uri;
}
解释:
  • listen 443 ssl:监听 443 端口并启用 SSL。
  • ssl_certificatessl_certificate_key:配置 SSL 证书和私钥路径。
  • 第二个 server 块是将 HTTP 请求重定向到 HTTPS。

6. URL 重写与跳转

Nginx 支持强大的 URL 重写功能,可以用于实现 301 重定向、条件判断、路径转换等。

示例:重定向 HTTP 到 HTTPS
server {
    listen 80;
    server_name www.example.com;
    return 301 https://$host$request_uri;
}
示例:重定向带 www 的域名到不带 www 的域名
server {
    listen 80;
    server_name www.example.com;
    return 301 http://example.com$request_uri;
}
示例:条件重写 URL
server {
    listen 80;
    server_name www.example.com;
​
    location / {
        if ($request_uri ~ ^/old-path) {
            return 301 /new-path;
        }
    }
}

7. 访问控制与限制

Nginx 可以限制访问特定路径、IP 或者限制请求频率,以提高安全性或防止滥用。

7.1 限制 IP 地址访问
nginx复制编辑server {
    listen 80;
    server_name www.example.com;
​
    location /admin/ {
        deny 192.168.1.1;
        allow all;
    }
}
解释:
  • deny:拒绝某些 IP 地址访问。
  • allow:允许特定 IP 地址或地址范围访问。
7.2 限制访问频率
http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
​
    server {
        listen 80;
        server_name www.example.com;
​
        location / {
            limit_req zone=mylimit burst=5;
            proxy_pass http://backend;
        }
    }
}
解释:
  • limit_req_zone:定义一个限制请求速率的区域。
  • limit_req:限制单个 IP 地址的访问速率,每秒不超过 1 次请求,最多允许突发 5 次。

8. 日志配置

Nginx 提供了非常强大的日志功能,可以帮助管理员了解访问情况。

示例配置:
http {
    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 /var/log/nginx/access.log main;
}
解释:
  • log_format:定义日志格式,$remote_addr 表示客户端 IP 地址,$request 表示请求方法和路径,$status 表示 HTTP 状态码等。
  • access_log:设置日志文件的位置。

9. 文件上传与下载

Nginx 可以非常高效地处理大文件上传和下载。

上传配置:
server {
    listen 80;
    server_name www.example.com;
​
    location /upload/ {
        client_max_body_size 100m;  # 最大允许上传 100MB
        proxy_pass http://backend;
    }
}
下载配置:
server {
    listen 80;
    server_name www.example.com;
​
    location /downloads/ {
        root /var/www/html;
        autoindex on;  # 启用目录列表功能
    }
}

总结

Nginx 是一款非常强大的 Web 服务器和反向代理服务器,它可以轻松处理高并发、实现负载均衡和提供高效的静态资源服务。它的配置文件简洁易懂,灵活性强,广泛应用于 Web 服务的搭建、微服务架构、API 网关等场景。