Nginx 问题与修复
基本结构 全局块:配置全局变量,如用户、进程数等,不设置会有默认值 events 块:配置与网络连接相关的选项,如连接数等,每个配置文件中只能有一个,不设置会有默认值 http 块:最常见的配置块,处…
基本结构
- 全局块:配置全局变量,如用户、进程数等,不设置会有默认值
- events 块:配置与网络连接相关的选项,如连接数等,每个配置文件中只能有一个,不设置会有默认值
- http 块:最常见的配置块,处理 HTTP 请求的相关设置,包含 server 块和 location 块,每个配置文件中只能有一个,不设置会有默认值
- upstream 块:定义一个后端服务器池,主要用于负载均衡
上面的块只能在 Nginx 主配置文件(通常是 /etc/nginx/nginx.conf)中定义,而不能在其他的配置文件中(如 sites-available 或 conf.d 目录中的文件)
- server 块:用来配置虚拟主机,监听指定的 IP 地址和端口,处理不同的域名。每个配置文件中可以有多个
- location 块:用来匹配不同的 URL 路径,可以精确匹配、前缀匹配或使用正则表达式
- 精确匹配:使用
=符号,表示完全匹配 - 前缀匹配:默认方式,匹配前缀的路径
- 正则表达式匹配:使用
~或~*表示区分大小写的正则匹配
- 精确匹配:使用
1# 全局块
2# 工作进程数量,对于多核处理器,建议与 CPU 核心数相同来调整该值
3worker_processes auto; # 自动检测 CPU 核心数
4# 指定 Nginx 进程的运行用户和用户组
5user www-data;
6# 指定 PID 文件路径
7pid /var/run/nginx.pid;
8# 允许包含其他配置文件,可以实现配置的模块化和重用
9# include /etc/nginx/conf.d/*.conf;
10
11events {
12 # 每个工作进程可以同时处理的最大连接数(默认 1024)
13 worker_connections 1024;
14 # 允许每个工作进程一次性接受多个连接,在高并发情况下可以提高性能
15 multi_accept on;
16 # 控制连接的接受方式,在多个工作进程之间共享,从而避免竞争条件,适用于连接频繁到来的场景
17 accept_mutex on;
18}
19
20http {
21 # 引入 MIME 类型文件,使 Nginx 能正确处理各种文件类型的响应
22 include mime.types;
23 # 设置默认的 MIME 类型,当 Nginx 无法识别文件类型时,使用这个默认类型
24 default_type application/octet-stream;
25 # 用于在文件传输时提高性能,允许直接通过操作系统的缓存发送文件,而不需要将文件读取到用户空间
26 sendfile on;
27 # 优化大文件的传输
28 tcp_nopush on;
29 # 低延迟响应
30 tcp_nodelay on;
31 # 设置客户端和服务器之间保持连接的时间(秒),如果在指定的时间内没有新的请求,将关闭连接
32 keepalive_timeout 65;
33 # 设置服务器向客户端发送响应的超时时间,如果客户端在指定时间内没有接收数据,将关闭连接
34 send_timeout 30;
35 # 关闭或开启在 HTTP 响应头中显示 Nginx 的版本信息(为了安全性,通常设置 off)
36 server_tokens off;
37 # 启用或禁用 gzip 压缩。开启后,Nginx 会对传输内容进行压缩,从而减少传输的数据量
38 gzip on;
39 # 限制客户端请求的最大请求体大小,防止大文件上传
40 client_max_body_size 1M;
41 # 访问日志(不配置就没有,不会自动删除,错误日志不配置有默认)
42 access_log /var/log/nginx/access.log main;
43
44 upstream backend {
45 # 允许每个连接最多处理 2 个请求(默认 1)提高性能
46 keepalive 2;
47 # 权重越大,优先级越高
48 server 127.0.0.1:8001 weight=3;
49 # 标记此服务器为不可用,通常用于在更新服务器配置时
50 server 127.0.0.1:8002 down;
51 # 备用服务器,只有主服务器都不可用的情况,才会将请求分配
52 server 127.0.0.1:8003 backup;
53 # 最大并发连接数被限制为10个,如连接数超过,则把请求转发到其他服务
54 server 127.0.0.1:8004 max_conns=10;
55 # 最少连接,优先将请求分发给当前连接数最少的服务器
56 least_conn;
57 # IP 哈希,根据客户端的 IP 地址进行请求分发,使同一个客户端总是访问同一台服务器
58 ip_hash;
59 }
60
61 server {
62 listen 80; # 监听端口 80
63 server_name example.com; # 域名
64
65 location / {
66 root /var/www/html; # 设置根目录
67 index index.html index.ht; # 默认首页文件
68 try_files $uri @jump;
69 }
70 # 命名位置跳转 @
71 location @jump {
72 proxy_pass http://backend;
73 proxy_http_version 1.1;
74 proxy_set_header Upgrade $http_upgrade;
75 proxy_set_header Connection $connection_upgrade;
76 }
77 # 精确匹配 =
78 location = /login {
79 # 反向代理到后端服务
80 proxy_pass http://backend;
81 proxy_set_header Host $host;
82 proxy_set_header X-Real-IP $remote_addr;
83 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
84 proxy_set_header X-Forwarded-Proto $scheme;
85 }
86 # 前缀匹配 /
87 location /api/ {
88 allow 192.168.1.0/24; # 允许指定 IP 段
89 deny all; # 拒绝其他访问
90 }
91 # 正则表达式匹配
92 location ~* \.(jpg|jpeg|png|gif|ico)$ {
93 root /var/www/images;
94 expires 30d; # 缓存时间
95 }
96 # 自定义错误页面
97 error_page 500 502 503 504 /50x.html;
98 location = /50x.html {
99 root /var/www/html;
100 }
101 # 301 永久重定向
102 location /oldpath {
103 return 301 /newpath;
104 }
105 # 302 临时重定向
106 location /temp {
107 rewrite ^/temp$ /newpath redirect;
108 }
109 }
110 # 配置 SSL 证书并启用 HTTPS
111 server {
112 listen 443 ssl;
113 server_name secure.example.com;
114 ssl_certificate /etc/nginx/ssl/nginx.crt;
115 ssl_certificate_key /etc/nginx/ssl/nginx.key;
116 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
117 ssl_ciphers HIGH:!aNULL:!MD5;
118 }
119}
目录选择偏好
单独的配置文件:/etc/nginx/conf.d/zailiangs.com.conf
禁用则尾缀加 .disabled
SSL 证书:/etc/nginx/ssl/zailiangs.com.key
Nginx 目录权限
方案一:改所有者
1sudo chown -R zailiang:zailiang /etc/nginx/conf.d
2sudo chown -R zailiang:zailiang /etc/nginx/ssl
3# 查看
4ls -ld /etc/nginx
方案二:保留 root 所有权
如果你希望 /etc/nginx 下面所有东西都保持 root 管理:
1sudo chown root:zailiang /etc/nginx
2sudo chmod 775 /etc/nginx
这样:
- root 完全控制
- zailiang 可以上传、修改文件
SSL 证书权限建议
1sudo chmod 644 /etc/nginx/ssl/*.crt
2sudo chmod 600 /etc/nginx/ssl/*.key
403 Forbidden
确保 Nginx 的运行用户对文件有正确的读取权限。Nginx 默认的用户是 nginx 或 www-data(取决于操作系统)。你可以检查一下/usr/share/nginx/html/blog/和 Nginx 配置中的其他路径的权限。
使用以下命令检查文件和目录权限:
1ls -l /usr/share/nginx/html/blog/
检查目录的权限,确保它至少是 755(目录必须可执行才能让 Nginx 访问它):
1sudo chmod -R 755 /usr/share/nginx/html/blog/
部署防止根域名报证书有误
证书申请时填根域名不带 www nginx 的 server_name 可以填多个
1server {
2 listen 443 ssl;
3 server_name zailiangs.com www.zailiangs.com;
4 ssl_certificate /etc/nginx/cert/zailiangs.com/zailiangs.com.pem;
5 ssl_certificate_key /etc/nginx/cert/zailiangs.com/zailiangs.com.key;
6 ssl_session_cache shared:SSL:1m;
7 ssl_session_timeout 5m;
8 ssl_protocols TLSv1.2;
9 ssl_ciphers HIGH:!aNULL:!MD5;
10 ssl_prefer_server_ciphers on;
11
12 location / {
13 root html;
14 index index.html index.htm;
15 proxy_pass http://zailiangs;
16 proxy_redirect default;
17 }
18}
语法报错
1(base) ➜ ~ nginx -t
2nginx: [emerg] "events" directive is not allowed here in /etc/nginx/conf.d/milvus.conf:3
3nginx: configuration file /etc/nginx/nginx.conf test failed
4(base) ➜ ~ nginx -t
5nginx: [emerg] "http" directive is not allowed here in /etc/nginx/conf.d/milvus.conf:3
6nginx: configuration file /etc/nginx/nginx.conf test failed
events http 块只能在 Nginx 主配置文件(通常是 /etc/nginx/nginx.conf)中定义,而不能在其他的配置文件中(如 sites-available 或 conf.d 目录中的文件)
root 与 alias 区别
root 会将匹配的 location 路径保留并拼接到指定的根目录路径后。
1location /way {
2 root /usr/share/nginx/html;
3 index index.html;
4}
5# root 将匹配的 location 路径拼接 /usr/share/nginx/html + /way
6# 无需以 / 结尾
7# /root_path/location_path/request_path
alias 用于替换匹配的路径,与 root 不同,alias 不会拼接 location 中的路径,而是直接替换整个路径。
1location /test-way {
2 alias /usr/share/nginx/html/way/;
3 index index.html;
4}
5# /test-way 会映射到 /usr/share/nginx/html/way/ 这个目录下
6# 必须以 / 结尾
7# /alias_path/request_path
/etc/nginx/sites-enabled/default 的作用
这个文件定义了一个默认的网站(虚拟主机),当用户访问 Nginx 服务器的 默认 IP 地址 + 端口(比如 http://192.168.2.42)时,如果没有其他匹配的 server_name,就会由这个配置来响应。
1server {
2 listen 80 default_server;
3 root /var/www/html;
4 index index.html index.htm;
5}
如果用户没有请求特定域名或端口匹配不到其他 server 块时,Nginx 会使用这个默认配置来处理请求。 这个文件有什么“副作用”?
如果你手动在 /etc/nginx/nginx.conf 或其他 conf.d 中写了你自己的网站配置,但没有删除这个 default 配置文件,就可能遇到以下问题:
- 你的网站运行在端口 8000,而访问 80 时看到的却是默认页面 原因:default 配置还在监听 80,导致访问 http://ip 显示的是默认页面而不是你的 Vue 页面。
- 端口冲突问题 如果你手动写了一个 listen 80 的配置,而 default 配置也有 listen 80 default_server,可能会导致 Nginx 重启失败或启动错误。
- default_server 抢占默认站点位置 会影响你设置的某些虚拟主机无法生效(因为 default 被优先使用了)。
大模型流式推送卡成一大块发送
在使用 Nginx 作为 SSE(Server-Sent Events)反向代理时,数据被“卡成一大块”发送,并非逐字符平滑流出,往往与 Nginx 的 缓冲机制 有关,而非 SSE 本身问题。
1location /sse {
2 proxy_pass http://backend;
3 proxy_http_version 1.1; # 开启 HTTP/1.1 支持
4 proxy_set_header Connection ""; # 清除 Connection 头,保持连接
5 proxy_buffering off; # 关闭缓冲,立即推送
6}
- 若后端已支持
X‑Accel‑Buffering: no,则可移除 proxy_buffering off;,由响应头控制缓冲策略。
去除响应头 Server 的版本号
1vim /etc/nginx/nginx.conf
2
3http {
4 server_tokens off;
5 ...
6}
7
8sudo nginx -s reload
这会将 Server: nginx/1.24.0(Ubuntu) 改为 Server: nginx
修改请求头 Referer 不允许从其他地方的请求
1set $referer_check 1;
2
3location /nt-rest {
4 set $referer_valid 0;
5 if ($http_referer ~* "^https?://(127\.0\.0\.1:8080|localhost:8080|192\.168\.2\.42:8080)") {
6 set $referer_valid 1;
7 }
8 # 组合判断:referer_check=1 且 referer 无效
9 set $deny "${referer_check}${referer_valid}";
10 if ($deny = "10") {
11 add_header Content-Type application/json;
12 return 403 '{"code":403,"msg":"illegal referer"}';
13 }
14 proxy_pass http://nt-rest;
15}
正则转义:. 需要写成 .,例如 192.168.1.100
协议匹配:^https?:// 同时匹配 http:// 和 https://
端口匹配:使用 :\d+ 匹配任意端口,或写死端口如 :5173
测试配置:修改后执行 nginx -t 测试,然后 nginx -s reload 重载