Nginx是什么

因为我之前没怎么接触过 nginx,个人配置 Web 服务器几乎全部使用 Apache,所以说我也是重新学习一下

Nginx是 lgor Sysoev 为俄罗斯访问量第二的 rambler.ru 站点设计开发的。从2004年发布至今,凭借开源的力量,已经接近成熟与完善。

Nginx 是一种代理服务器,代理服务器是一种位于客户端与服务器之间的中间层服务器,其主要功能是转发客户端的请求到目标服务器,并将目标服务器的响应返回给客户端,并在中间提供各种功能。在生产环境中,几乎所有现代 Web 应用架构都会将 Nginx 作为前端的第一道防线和流量入口。客户端直接连接的是 Nginx,而不是后端应用服务器,Nginx负责将流量转发给它们,这提升了性能和并发能力的同时,而且保护了后端应用服务器。

Nginx功能丰富,而且轻量,可作为HTTP服务器,也可作为反向代理服务器,邮件服务器。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。并且支持很多第三方的模块扩展。而且处理高并发能力是十分强大的。

Nginx支持热部署,启动简单,可以做到7*24不间断运行。几个月都不需要重新启动。

一个典型的使用 Nginx 的架构通常是这样的:

1
[客户端浏览器/搜索引擎爬虫] <---> [Nginx服务器] <---> [后端应用服务器集群]

在这个架构中:

  • Nginx:处理所有客户端请求,负责反向代理、负载均衡、SSL 终止和缓存。
  • 后端应用服务器:运行实际的业务逻辑。它们通常是无状态的,可以水平扩展。

而且 Nginx 是一个强大的多面手 Web 服务器,主要功能包括:

  • HTTP 服务器:这是最基本的功能,用于直接提供 HTML、CSS、JavaScript、图片等静态文件
  • 反向代理:这是 Nginx 最核心和最常用的功能之一。它接收客户端(如浏览器)的请求,然后将请求转发到后端的其他服务器。客户端只与 Nginx 交互,完全不知道后端服务器的存在。
  • 负载均衡:当有多个后端服务器时,Nginx 可以将客户端的请求智能地分发到不同的服务器上,从而避免单个服务器过载,提高整个应用的可用性和处理能力。
  • 缓存:Nginx 可以缓存从后端服务器获取的内容(如 API 响应、图片),对于频繁访问但很少变化的内容,直接从 Nginx 缓存中返回,大大减轻后端服务器的压力并提升响应速度。
  • SSL/TLS 终止:Nginx 可以处理 SSL/TLS 握手和加密 / 解密过程,即 “终止” SSL 连接。这意味着后端应用服务器不需要处理复杂的加密逻辑,只需要处理普通的 HTTP 请求,从而简化了应用代码并提高了安全性。
  • URL 重写与重定向:可以根据规则重写 URL 路径,或者将请求重定向到其他地址,实现更灵活的路由控制。
  • 健康检查:在负载均衡模式下,Nginx 可以定期检查后端服务器的健康状态,自动将故障的服务器从服务列表中剔除,保证服务的高可用。

什么是代理和反向代理

img

Nginx 代理分为两类:

  • 正向代理:客户端通过 Nginx 访问外部资源,外部服务器认为请求来自 Nginx。
  • 反向代理:客户端访问 Nginx,Nginx根据配置将请求转发到后端服务器,客户端并不知道后端服务器的真实地址。

Nginx 最常用于 反向代理

正向代理

什么是正向代理

我们都学习过代理设计模式,都知道代理模式中有代理角色和被代理角色

正向代理就是你去主动连接一个中间服务器,让它帮你访问目标网站,在这个过程中,目标服务器并不知道真正的客户端是谁,它只知道是代理服务器在请求它。

例如:你想进山姆买点东西,但你没有会员资格。于是你找了一个有会员资格的朋友(代理服务器),让他把会员卡借你刷卡进门(代表你访问目标服务器)。山姆(目标服务器)只认识你的朋友,而不认识你。

这种情况对应我们日常生活中很多访问国外网站的情况,在这个时候如果不使用代理,访问速度会非常慢,通常这时候我们会通过给浏览器配置一个网速快的、可以访问国外网站内容的代理来解决我们的问题

image-20251228125908988

我们首先请求代理服务器,然后代理服务器帮我们去快速访问国外的网站,对于这种代理方式,我们就称之为正向代理。

此时,我们当前的角色为 被代理者,正向代理的本质是我们去请求外部的资源,是客户端(如你的浏览器)主动决定要访问哪个目标服务器

如果以生产者、消费者模式来区分,我们属于消费者。而且正向代理中,我们不对外提供服务,反而是对外消费服务,属于消费者。

不止访问国外网站,代理服务器在缓存加速,过滤内容上也很重要(扫码dmm就是通过正向代理隔绝非日本用户的)

反向代理

很明显,就是和正向代理相反

image-20251228130013607

其中客户端(如浏览器)的请求首先到达一个代理服务器(Nginx),然后由代理服务器根据配置将请求转发到后端的一个或多个应用服务器

在这个过程中,客户端只知道代理服务器的存在,而不知道后端应用服务器的存在

去饭馆吃饭就是很明显的例子,你去一家餐厅吃饭。你(客户端)只需要和门口的迎宾员(Nginx)打交道,告诉他你要吃什么。迎宾员(Nginx)会把你的需求(请求)传达给厨房的厨师(后端应用服务器),然后把做好的菜(响应)端给你。你从头到尾都没有见过厨师。

反向代理就是客户端主动发起请求,但请求首先到达代理服务器。客户端只与代理服务器交互,完全不知道后端有哪些应用服务器。因为代理服务器知道后端所有应用服务器的地址和状态。

最典型的用处就是负载均衡和隐藏后端

如何编写 Nginx 配置

Nginx配置文件结构

Nginx 的配置文件几乎管理了 Nginx 几乎全部的配置

而且Nginx 的配置由主配置文件**(nginx.conf)和模块化配置文件(如conf.d/*.conf)组成,整体遵循层级嵌套的结构

  • 主配置文件 /etc/nginx/nginx.conf(Linux)是入口,主配置中通常通过 include 指令引入其他配置文件
  • 建议将不同域名 / 服务的配置拆分到 conf.d 目录下的独立文件,便于维护

其中配置文件的结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
...              #全局块

events { #events块
...
}

http #http块
{
... #http全局块
server #server块
{
... #server全局块
location [PATTERN] #location块
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http全局块
}
graph TD
    A[全局块] --> B[events块]
    A --> C[http块]
    C --> D[upstream块]
    C --> E[server块]
    E --> F[location块]

其中

  • 全局块是配置文件的最顶部,用于设置影响 Nginx 整体运行的全局参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 运行Nginx的用户和用户组(Linux)
    user nginx;

    # Nginx工作进程数,建议设置为CPU核心数(如4核CPU设为4)
    worker_processes auto; # auto会自动匹配CPU核心数

    # 错误日志路径和级别(debug/info/notice/warn/error/crit)
    error_log /var/log/nginx/error.log warn;

    # 进程PID文件路径
    pid /var/run/nginx.pid;
  • 全局块内的 events 块是用于配置 Nginx 与客户端连接相关的参数,影响 Nginx 的并发处理能力,仅能有一个 events 块。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    events {
    # 每个工作进程的最大并发连接数
    worker_connections 10240;

    # 采用epoll模型(Linux下高性能的事件驱动模型)
    use epoll;

    # 允许一个连接同时被多个工作进程接受(提高连接效率)
    multi_accept on;
    }
  • 全局块内的http块是 Nginx 处理 HTTP/HTTPS 请求的核心配置块,包含所有与 HTTP 相关的全局配置,可嵌套多个serverupstream块。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    http {
    # 引入MIME类型映射文件(决定不同文件的Content-Type响应头)
    include /etc/nginx/mime.types;
    default_type application/octet-stream; # 默认MIME类型

    # 日志格式定义(main是自定义名称,可在server/location中引用)
    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;

    # 开启高效文件传输模式(sendfile系统调用,减少内核态/用户态切换)
    sendfile on;
    # 合并小数据包发送,减少网络IO
    tcp_nopush on;
    # 关闭TCP延迟确认,提高实时性
    tcp_nodelay on;

    # 连接超时时间(客户端与Nginx的连接保持时间)
    keepalive_timeout 65;

    # 开启gzip压缩,减小传输体积
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    # 引入后端服务器集群配置(可多个upstream)
    upstream backend_api {
    server 192.168.1.100:8080 weight=1 max_fails=3 fail_timeout=30s;
    server 192.168.1.101:8080 weight=2 max_fails=3 fail_timeout=30s;
    # weight:权重,数值越大接收请求越多
    # max_fails:失败重试次数
    # fail_timeout:失败后多久重新检测
    }

    # 引入虚拟主机配置(可多个server)
    include /etc/nginx/conf.d/*.conf;
    }
  • http块内的 server 块对应一个虚拟主机,用于配置特定域名 / 端口的服务,是 HTTP 配置的核心单元,可嵌套多个location块。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    server {
    # 监听的端口和协议(80=HTTP,443=HTTPS)
    listen 80;
    listen [::]:80; # 监听IPv6

    # 匹配的域名(多个域名用空格分隔,*为通配符)
    server_name your-domain.com www.your-domain.com;

    # 重定向HTTP到HTTPS(常见场景)
    return 301 https://$host$request_uri;
    }

    # HTTPS服务配置示例
    server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name your-domain.com www.your-domain.com;

    # SSL证书配置
    ssl_certificate /etc/nginx/ssl/your-domain.crt;
    ssl_certificate_key /etc/nginx/ssl/your-domain.key;

    # SSL优化配置
    ssl_session_timeout 1d;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    # 静态资源根目录
    root /usr/share/nginx/html;
    index index.html index.htm; # 默认首页

    # location块:匹配URL路径,处理不同请求
    # 匹配静态资源(优先级高)
    location ~* \.(jpg|jpeg|png|gif|css|js)$ {
    expires 7d; # 浏览器缓存7天
    add_header Cache-Control "public, max-age=604800";
    }

    # 匹配API请求,转发到后端集群
    location /api/ {
    proxy_pass http://backend_api/; # 末尾/表示转发时去掉/api/前缀
    # 转发请求头,让后端获取真实客户端信息
    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_connect_timeout 30s;
    proxy_send_timeout 30s;
    proxy_read_timeout 30s;
    }

    # 匹配根路径,处理前端SPA应用
    location / {
    try_files $uri $uri/ /index.html; # 解决SPA路由刷新404问题
    }
    }
  • server内的 location 块用于匹配请求的 URL 路径,并对匹配的请求进行个性化处理(如转发、静态资源、重定向等),是 Nginx 配置中最灵活的部分。

    语法 匹配类型 示例 说明
    location = / 精确匹配 location = /login 仅匹配/login,不匹配/login//login?id=1
    location ^~ /path 前缀匹配(优先) location ^~ /static/ 匹配以/static/开头的路径,且终止后续正则匹配
    location ~ pattern 正则匹配(区分大小写) location ~ \.php$ 匹配以.php结尾的路径
    location ~* pattern 正则匹配(不区分大小写) location ~* .(jpg | png)$ 匹配以.jpg/.png结尾的路径,不区分大小写
    location /path 普通前缀匹配 location /api/ 匹配以/api/开头的路径,优先级最低

而且,Nginx 配置文件规则大约这样

  1. 指令格式指令名 参数;(末尾必须加;,否则配置报错)
  2. 注释:以#开头,注释内容不会被解析
  3. 块指令:指令名后加{},内部嵌套子指令(如server {}location {}
  4. 变量使用:以$开头,如$host(请求域名)、$remote_addr(客户端 IP)、$request_uri(完整请求路径)
  5. 包含文件include指令可引入其他配置文件,支持通配符(如include conf.d/*.conf;
  6. 配置生效:修改配置后需执行 nginx -s reload 重载配置(不中断服务)

正向代理配置详解

nginx 以反向代理为主,实际上,nginx 可以去配置正向代理,但是情况比较少见

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 全局块(如果是独立配置文件,无需重复写全局块,仅需写http/server部分)
# user nginx;
# worker_processes auto;

events {
worker_connections 10240;
use epoll;
}

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

# 1. 正向代理核心配置:关闭请求缓冲(避免大文件代理卡顿)
proxy_request_buffering off;

# 2. 超时配置:防止代理请求超时
proxy_connect_timeout 30s; # 与目标服务器的连接超时
proxy_send_timeout 60s; # 向目标服务器发送请求的超时
proxy_read_timeout 60s; # 读取目标服务器响应的超时

# 3. DNS解析配置:正向代理必须配置,否则无法解析目标域名
resolver 8.8.8.8 114.114.114.114 valid=300s; # Google DNS + 114 DNS
resolver_timeout 5s; # DNS解析超时时间

# 4. 正向代理服务器配置
server {
listen 8080; # 代理服务器监听端口(客户端配置的代理端口)
resolver $dns_addr; # 复用上面的DNS配置

# 匹配所有HTTP请求(正向代理核心location)
location / {
# 核心:将请求转发到目标服务器($host是请求的目标域名,$request_uri是请求路径)
proxy_pass http://$host$request_uri;

# 5. 请求头配置:让目标服务器获取正确的客户端信息
proxy_set_header Host $host; # 传递目标域名
proxy_set_header X-Real-IP $remote_addr; # 传递真实客户端IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递代理链IP
proxy_set_header X-Forwarded-Proto $scheme; # 传递协议(http/https)

# 6. 响应头配置:隐藏Nginx标识,提高安全性
proxy_hide_header X-Powered-By;
proxy_hide_header Server;
add_header X-Proxy-Server "Nginx Forward Proxy" always;

# 7. 缓存配置:可选,缓存静态资源减少重复请求
proxy_cache_valid 200 304 1h; # 200/304响应缓存1小时
proxy_cache_bypass $http_pragma; # 忽略Pragma头的缓存
proxy_no_cache $http_cache_control; # 忽略Cache-Control的缓存

# 8. 限制请求大小:防止超大请求占用资源
client_max_body_size 100M;
}

# 可选:处理HTTPS正向代理(CONNECT方法)
location ~ ^/(CONNECT) {
# HTTPS代理需要TCP转发,而非HTTP
proxy_pass $scheme://$host$request_uri;
proxy_connect_timeout 10s;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
}

上面配置中正向代理特有的、最关键的配置项,单独拿出来说一下

DNS 解析配置

1
2
resolver 8.8.8.8 114.114.114.114 valid=300s;
resolver_timeout 5s;

正向代理需要解析客户端请求的目标域名,比如用户访问www.baidu.com,Nginx 需要知道这个域名的 IP,resolver指定 DNS 服务器地址。

  • 8.8.8.8/114.114.114.114是常用的公共 DNS 服务器
  • valid=300s是DNS 解析结果的缓存时间

反向代理不需要这个配置但是正向代理必须配,否则会报no resolver defined to resolve xxx错误。

转发指令如下

1
proxy_pass http://$host$request_uri;

这是正向代理的核心,将客户端的请求转发到目标服务器

$host是客户端请求的目标域名,$request_uri是客户端的完整请求路径,一般情况下反向代理的proxy_pass是固定地址,因为这是你的域名,而正向代理是动态的,他要通过变量获取目标地址。

关闭请求缓冲

1
proxy_request_buffering off;

默认情况下,Nginx 会先把客户端的请求全部接收完,再转发给目标服务器(缓冲模式)。关闭后,Nginx 会实时转发请求(流式),适合代理大文件上传 / 下载场景。

牢记 Nginx 这两条命令

1
2
3
4
5
# 1. 验证配置语法是否正确
nginx -t

# 2. 重载Nginx配置(不中断服务)
nginx -s reload

反向代理配置详解

偏静态资源代理

一般情况下,反向代理会 和 静态资源服务一起配置,下面是我实际网站的一个 nginx 偏向静态资源的配置,拆来说一下

基础监听与域名配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# HTTPS服务的server块
server {
# 监听443端口(HTTPS默认端口),启用SSL
listen 443 ssl ;
# 监听IPv6的443端口,启用SSL
listen [::]:443 ssl ;
# 启用HTTP/2协议(比HTTP/1.1性能更好,HTTPS下推荐开启)
http2 on;
# 匹配的域名(仅处理zyplatform.xyz的请求)
server_name zyplatform.xyz;

# HTTP跳转的server块
server {
# 监听80端口(HTTP默认端口)
listen 80;
listen [::]:80;
# 匹配相同域名,用于HTTP转HTTPS
server_name zyplatform.xyz;
# 301永久重定向,将HTTP请求跳转到HTTPS
return 301 https://$host$request_uri;
}
  • listen:指定 Nginx 监听的端口和协议,ssl参数表示该端口启用 HTTPS;[::]:443是 IPv6 监听,生产环境一般同时配置 IPv4 和 IPv6。
  • http2 on:启用 HTTP/2,需配合 HTTPS,因为HTTP/2 仅支持 HTTPS
  • server_name:匹配请求的Host头,只有请求域名是zyplatform.xyz时,才会走这个server块的配置;
  • 而且一般情况下,有 HTTPS ,HTTP 端口(80)就仅做跳转了

然后是 SSL/TLS 安全配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# SSL证书文件路径(公钥,包含域名证书+CA证书链)
ssl_certificate
# SSL私钥文件路径(保密,仅服务器持有)
ssl_certificate_key
# 支持的TLS协议版本(禁用低版本如TLSv1.0/TLSv1.1,提升安全性)
ssl_protocols TLSv1.2 TLSv1.3;
# 加密套件
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
# 优先使用服务器端的加密套件(而非客户端)
ssl_prefer_server_ciphers on;
# SSL会话缓存(减少重复握手,提升性能)
ssl_session_cache shared:SSL:10m;
# SSL会话超时时间(10分钟内重复访问无需重新握手)
ssl_session_timeout 10m;

静态资源基础配置

1
2
3
4
# 默认首页文件,按顺序查找
index index.html index.htm;
# 前端静态文件的根目录(Vue打包后的dist目录路径)
root /www/wwwroot/zyplatform.xyz;
  • root:指定静态文件的根目录,当请求https://zyplatform.xyz/index.html时,Nginx 会去/www/wwwroot/zyplatform.xyz/index.html找文件。
  • index:访问域名根路径(/)时,默认查找的文件;适配前端应用的首页。

如果你是 Vue,注意,需要配置 Vue History 模式路由兼容

1
2
3
4
location / {
# 核心:尝试查找$uri(请求的文件)→ $uri/(请求的目录)→ 找不到则返回/index.html
try_files $uri $uri/ /index.html;
}

因为 Vue History 模式下,刷新https://zyplatform.xyz/user这类路由时,Nginx 会认为/user是文件 / 目录,找不到就返回 404;try_files解决思路是先尝试匹配真实文件 / 目录,匹配不到则转发到index.html,由 Vue 的前端路由接管,避免 404;

这是前端 SPA(单页应用)反向代理的必配项

一些静态资源缓存和日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 匹配图片、JS、CSS等静态资源,缓存30天
location ~* \.(gif|jpg|jpeg|png|bmp|swf|js|css)$ {
expires 30d; # 浏览器缓存30天
access_log off; # 关闭这类请求的访问日志,减少日志体积
}

# 排除/docs路径的JS/CSS,缓存12小时
location ~* ^(?!/docs).*\.(js|css)?$ {
expires 12h;
access_log off;
}

# 访问日志路径(记录所有请求的访问信息)
access_log /www/wwwlogs/zyplatform.xyz.log;
# 错误日志路径(记录Nginx运行错误、请求错误)
error_log /www/wwwlogs/zyplatform.xyz.error.log;

偏向 Nginx 反向代理

然后这是偏向 Nginx 反向代理的到我后端的配置,因为一般情况下,主域名会分配给前端网站做访问,api.的二级域名回去对接后端,去做 API 代理

其中重复的 HTTPS ,HTTP 重定向,SSL 这些重复的就不说了,直接看 Nginx 核心的反向代理配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
location / {
# 核心:将请求转发到本地9006端口的Spring Boot应用
proxy_pass http://127.0.0.1:9006;

# 传递关键请求头,让Spring Boot获取真实客户端信息
proxy_set_header Host $host; # 传递请求的域名(api.zyplatform.xyz)
proxy_set_header X-Real-IP $remote_addr; # 传递真实客户端IP(而非Nginx的IP)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递代理链IP
proxy_set_header X-Forwarded-Proto $scheme; # 传递协议(https)

# WebSocket支持(Spring Boot常用,比如实时通知、消息推送)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

# 超时配置(适配Spring Boot长业务/大文件上传)
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}

其中,这个块就是将匹配location /的所有请求(即api.zyplatform.xyz的所有 API 请求)转发到http://127.0.0.1:9006(Spring Boot 应用的监听地址);

而且proxy_set_header等这些传递客户端真实信息的必须要配,不加这些配置的话,Spring Boot 中通过request.getRemoteAddr()获取的是 Nginx 服务器的 IP(127.0.0.1),而非真实用户的 IP;通过request.getScheme()获取的是http而非https,会导致业务逻辑(比如生成回调 URL)出错。

image-20251228141417606

其中文件大小上传配置是简易配置的,而且通常简易配的要比 Spring Boot 控制的文件大小限制要大一些

1
client_max_body_size 100m;

那么,Nginx 反向代理的经典配置和常用配置项如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# 全局块
user nginx;
worker_processes auto; # 自动匹配CPU核心数
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

# 事件块,连接相关配置
events {
worker_connections 10240; # 每个worker最大并发连接数
use epoll; # Linux下高性能事件模型
multi_accept on; # 一次性接收所有新连接
}

# HTTP核心块,反向代理的核心配置域
http {
include /etc/nginx/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" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/access.log main;

# 性能优化基础配置
sendfile on; # 高效文件传输,静态资源必备
tcp_nopush on; # 合并小数据包发送
tcp_nodelay on; # 关闭TCP延迟确认(长连接优化)
keepalive_timeout 65; # 客户端连接保持时间
client_max_body_size 100M; # 最大请求体大小(文件上传必备)

# Gzip压缩,减少传输体积,基本都会写
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript application/xml image/svg+xml;

# 如果是微服务,会做后端服务集群,负载均衡配置
upstream backend_cluster {
server 192.168.1.100:8080 weight=2 max_fails=3 fail_timeout=30s; # 权重2,优先接收请求
server 192.168.1.101:8080 weight=1 max_fails=3 fail_timeout=30s; # 权重1
ip_hash; # 基于IP哈希,保证会话粘滞(可选)
# least_conn; # 最少连接数分发(替代ip_hash,适合无状态服务)
}

# --------------------------
# 1. HTTP强制跳转HTTPS(必配)
# --------------------------
server {
listen 80;
listen [::]:80;
server_name your-domain.com www.your-domain.com;

# 301永久重定向,保留完整请求路径
return 301 https://$host$request_uri;

# 可选:禁止爬虫抓取HTTP站点
add_header X-Robots-Tag "noindex, nofollow" always;
}

# --------------------------
# 2. HTTPS反向代理核心配置(主配置)
# --------------------------
server {
listen 443 ssl http2; # 启用HTTPS+HTTP/2
listen [::]:443 ssl http2;
server_name your-domain.com www.your-domain.com;

# --------------------------
# SSL/TLS安全配置(HTTPS核心)
# --------------------------
ssl_certificate /etc/nginx/ssl/your-domain.crt; # 证书公钥
ssl_certificate_key /etc/nginx/ssl/your-domain.key; # 证书私钥

# 仅启用高安全协议版本
ssl_protocols TLSv1.2 TLSv1.3;
# 高安全加密套件
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:HIGH:!aNULL:!MD5:!RC4;
ssl_prefer_server_ciphers on; # 优先服务器套件

# SSL会话缓存(减少握手耗时)
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# OCSP装订(优化证书验证)
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/root-ca.crt; # CA根证书

# --------------------------
# 静态资源配置(前端文件托管)
# --------------------------
root /usr/share/nginx/html; # 前端静态文件根目录
index index.html index.htm;

# 静态资源缓存(性能优化核心)
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
expires 30d; # 浏览器缓存30天
add_header Cache-Control "public, max-age=2592000";
access_log off; # 关闭静态资源日志
gzip on; # 静态资源压缩
}

# SPA前端路由兼容(Vue/React History模式)
location / {
try_files $uri $uri/ /index.html; # 404时返回index.html
}

# --------------------------
# API反向代理核心配置(对接后端)
# --------------------------
location /api/ {
# 转发到后端集群(负载均衡)
proxy_pass http://backend_cluster/; # 末尾/去掉/api前缀

# --------------------------
# 反向代理核心请求头(必配)
# --------------------------
proxy_set_header Host $host; # 传递域名
proxy_set_header X-Real-IP $remote_addr; # 传递真实客户端IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 代理链IP
proxy_set_header X-Forwarded-Proto $scheme; # 传递协议(HTTPS)
proxy_set_header X-Forwarded-Port $server_port; # 传递端口

# --------------------------
# 超时配置(稳定性保障)
# --------------------------
proxy_connect_timeout 30s; # 与后端连接超时
proxy_send_timeout 60s; # 向后端发送数据超时
proxy_read_timeout 60s; # 读取后端响应超时(关键!)

# --------------------------
# WebSocket支持(实时通信必备)
# --------------------------
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

# --------------------------
# 缓冲区配置(大响应优化)
# --------------------------
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
}

# --------------------------
# 安全加固配置
# --------------------------
# 禁止访问敏感文件
location ~ ^/(\.git|\.env|\.htaccess|\.user.ini) {
deny all; # 直接拒绝访问
access_log off;
log_not_found off;
}

# 限制特定IP访问后台(可选)
location /admin/ {
allow 192.168.1.0/24; # 允许内网IP
deny all; # 拒绝其他IP
proxy_pass http://backend_cluster/admin/;
}

# --------------------------
# 日志配置
# --------------------------
access_log /var/log/nginx/your-domain.access.log main;
error_log /var/log/nginx/your-domain.error.log error; # 仅记录错误级别
}
}

其中,Nginx 反向代理的配置核心就是 location 块内的内容,这是反向代理的核心中的核心,通常所有对接后端的配置都集中在这里

单独拿出来说一下

配置项 作用 关键说明
proxy_pass http://backend_cluster/ 转发请求到后端服务 末尾/:去掉location前缀(如/api/user/user);无/:保留前缀(如/api/user/api/user
proxy_set_header Host $host 传递请求域名到后端 后端多租户、域名匹配逻辑依赖此头
proxy_set_header X-Real-IP $remote_addr 传递真实客户端 IP 后端获取真实 IP(而非 Nginx 的 IP)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for 传递代理链 IP 多层代理时,拼接所有代理节点 IP
proxy_set_header X-Forwarded-Proto $scheme 传递协议(http/https) 后端生成链接时避免出现 http(HTTPS 场景必配)
proxy_connect_timeout 30s 与后端连接超时 网络正常时设 30s,内网可设 10s
proxy_read_timeout 60s 读取后端响应超时 关键!长业务(如报表生成)需调大(如 120s),否则返回 504
proxy_send_timeout 60s 向后端发送数据超时 大请求体(如批量 JSON)需调大
proxy_http_version 1.1 启用 HTTP/1.1 WebSocket、长连接场景必开
proxy_set_header Upgrade $http_upgrade 传递 WebSocket 升级头 实时通信(如聊天、推送)必配
proxy_set_header Connection "upgrade" 强制连接升级 配合上一项启用 WebSocket
proxy_buffering on 启用响应缓冲 Nginx 先接收后端响应,再发给客户端(减少后端连接数);大文件下载可设off(流式传输)
  1. 请求头必配原则HostX-Real-IPX-Forwarded-ForX-Forwarded-Proto这 4 个头是反向代理必须的,无论什么场景都必须配置,否则后端会获取不到真实客户端信息。
  2. 性能优化原则
    • 静态资源必开sendfilegzip,关闭访问日志;
    • HTTPS 必开ssl_session_cache,减少握手耗时;
    • 高并发场景调大worker_connections,设worker_processes为 CPU 核心数。

差不多这样就可以了

当然微服务和分布式集群这种配置没有上纲上线来说,因为这些问题说起来还是很麻烦的,对了,Nginx 默认是轮询,通常配成加权轮询