Skip to content

Commit bf15ef9

Browse files
iBugtaoky
andcommitted
nginx: Reorganize
Co-authored-by: taoky <me@taoky.moe>
1 parent 215d8fc commit bf15ef9

File tree

2 files changed

+128
-88
lines changed

2 files changed

+128
-88
lines changed

docs/ops/network-service/nginx.md

Lines changed: 127 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
icon: simple/nginx
33
---
44

5-
# Nginx 网页服务器
5+
# Nginx 服务器
66

77
!!! note "主要作者"
88

@@ -12,7 +12,7 @@ icon: simple/nginx
1212
>
1313
> —— [@Cherrling][Cherrling]
1414
15-
Nginx 是一个高性能的 HTTP 和反向代理服务器,它可以作为一个独立的 Web 服务器,也可以作为其他 Web 服务器的反向代理服务器
15+
Nginx 是一个高性能的 HTTP 和反向代理服务器,它可以作为一个独立的 Web 服务器,也可以作为其他 Web 服务的反向代理服务器
1616

1717
如果你只是需要简单快速的拉起一个网站,或许也可以试试 [Caddy](../../advanced/caddy.md),它是一个更加简单的 Web 服务器。
1818

@@ -49,7 +49,7 @@ sudo systemctl stop nginx # 安全停止 Nginx
4949

5050
## 配置 {#configuration}
5151

52-
### 配置文件结构简介
52+
### 配置文件结构简介 {#config-file-structure}
5353

5454
对于 Debian & Ubuntu 来说,`nginx.conf` 的内容一般包含:
5555

@@ -67,7 +67,7 @@ http {
6767
- `sites-available` 目录下存放的是所有的站点配置文件。
6868
- `sites-enabled` 目录下存放的是启用的站点配置文件的符号链接。
6969

70-
一般情况下,我们不在 `nginx.conf` 文件中直接编写站点信息(`http` 块),而是在 `sites-available` 目录下创建一个新的配置文件,然后在 `sites-enabled` 目录下创建一个符号链接。如果要暂时下线某个站点,只需要删除 `sites-enabled` 目录下的符号链接即可,而不需要删除配置文件。
70+
一般情况下,我们不在 `nginx.conf` 文件的 `http` 块中直接编写站点信息,而是在 `sites-available` 目录下创建一个新的配置文件,然后在 `sites-enabled` 目录下创建一个符号链接。如果要暂时下线某个站点,只需要删除 `sites-enabled` 目录下的符号链接即可,而不需要删除配置文件。
7171

7272
从 Nginx 的角度来看,唯一的区别在于来自 `conf.d` 的文件能够更早被处理,因此,如果你有相互冲突的配置,那么来自 `conf.d` 的配置会优先于 `sites-enabled` 中的配置。
7373

@@ -84,9 +84,60 @@ http {
8484

8585
此时,你需要将你编写的配置文件放置于 `/etc/nginx/conf.d` 目录下,但当你需要禁用某些内容时,必须将其移出文件夹、删除或进行更改。当然,你也可以自己创建 `sites-available` 和 `sites-enabled` 目录,然后在 `nginx.conf` 中引入。
8686

87-
关于两者的区别,你可以查看[这篇文章](https://serverfault.com/questions/527630/difference-in-sites-available-vs-sites-enabled-vs-conf-d-directories-nginx)。
87+
### 指令、变量与模块 {#directives-variables-modules}
8888

89-
### 编辑站点配置
89+
Nginx 的配置由一系列的指令(directive)组成。directive 有两种:简单 directive 和块 directive。在上面的例子中,`server` 块就是一个块 directive,而 `listen``server_name``root` 等则是简单 directive。
90+
91+
Nginx 的配置还支持变量。以上例子中 `$host``$remote_addr``$uri` 等都是变量,Nginx 会在处理请求的时候将它们替换为实际的值。用户也可以用 `set` 指令来定义自己的变量:
92+
93+
```nginx
94+
set $my_variable "Hello, World!";
95+
```
96+
97+
Nginx 是模块化的服务器,其中 [`ngx_http_core_module`](https://nginx.org/en/docs/http/ngx_http_core_module.html) 提供了基础的让 Nginx 提供 HTTP 服务的功能(包括 `http` 块)。Nginx 也不仅限于 HTTP 服务——可以转发 TCP 和 UDP 流量,甚至是当邮件服务器,或者 RTMP 直播服务器等。这些功能都是通过不同的模块来实现的。用户也可以自己编译安装第三方模块来扩展 Nginx 的功能。
98+
99+
[Nginx 文档](https://nginx.org/en/docs/) 是非常重要的参考资料,其包含了:
100+
101+
- [按字母序排序的 directive 列表文档](https://nginx.org/en/docs/dirindex.html)
102+
- [按字母序排序的变量列表文档](https://nginx.org/en/docs/varindex.html)
103+
- 官方模块的列表文档
104+
105+
其中每个 directive 和变量都包含了详细的说明。
106+
107+
### `server` 块与 `location` 块 {#server-location-blocks}
108+
109+
Nginx 配置的 [`http`](https://nginx.org/en/docs/http/ngx_http_core_module.html#http)中可以有多个 [`server`](https://nginx.org/en/docs/http/ngx_http_core_module.html#server),每个 `server` 块定义了一个站点(虚拟主机),Nginx 会根据请求的域名和端口号来匹配对应的 `server` 块。Nginx 正是通过 `server` 块来实现多站点配置的。
110+
111+
一个典型的 `server` 块如下:
112+
113+
```nginx
114+
server {
115+
listen 80; # 监听的端口
116+
server_name example.com; # 服务器名称
117+
118+
location / {
119+
# 处理请求的指令
120+
}
121+
}
122+
```
123+
124+
[`location`](https://nginx.org/en/docs/http/ngx_http_core_module.html#location)嵌套于 `server` 块中,用于定义如何处理特定 URI 的请求。一个 `server` 块中可以有多个 `location` 块。
125+
126+
??? tip "URI? URL?"
127+
128+
URI(Uniform Resource Identifier,统一资源标识符)包含 URL(Uniform Resource Locator,统一资源定位符)和 URN(Uniform Resource Name,统一资源名称)。其中 URL 大家都非常熟悉,而 URN 则比较少见。URN 的格式类似于 `urn:isbn:123456789`,用于标识资源(这里是一本书)的名称。因为 URN 很少见,在绝大部分场景下,URI 和 URL 可以视为同义词。
129+
130+
Nginx 的 `location` 块用于定义如何处理特定 URI 的请求。它是 Nginx 配置中的一个重要部分,允许让 Nginx 根据请求的路径、参数或其他条件来执行不同的操作。
131+
132+
一个 `location` 块的基本结构如下:
133+
134+
```nginx
135+
location [modifier] /path/ {
136+
# 处理请求的指令
137+
}
138+
```
139+
140+
### 编辑站点配置 {#edit-site-config}
90141

91142
默认的站点配置文件在 `/etc/nginx/sites-available/default`,你可以直接编辑它——以下为去除了所有注释的默认版本:
92143

@@ -106,7 +157,7 @@ server {
106157
}
107158
```
108159

109-
这个配置文件中定义了一个完整的 `server` 块。一个 `server` 块定义了一个站点(虚拟主机),Nginx 会根据请求的域名和端口号来匹配对应的 `server` 块。`server` 块中的指令如下:
160+
这个配置文件中定义了一个完整的 `server` 块。`server` 块中的指令如下:
110161

111162
- `listen`:该默认站点在所有的 IPv4 和 IPv6 上监听 80 端口。
112163
- `root`:根目录是 `/var/www/html`
@@ -140,7 +191,7 @@ server {
140191

141192
这时访问 `http://localhost` 就会被转发到 `http://backend_server:port`。对外部网络来说,Nginx 就是一个反向代理站点。
142193

143-
### 重新加载配置
194+
### 重新加载配置 {#reload}
144195

145196
修改配置文件后,别忘了重新加载 Nginx 配置,否则修改不会生效。
146197

@@ -153,69 +204,12 @@ sudo nginx -t
153204
如果没有问题,就重新加载配置文件:
154205

155206
```bash
207+
sudo systemctl reload nginx # 推荐使用
208+
# 或者
156209
sudo nginx -s reload
157210
```
158211

159-
或者使用:
160-
161-
```bash
162-
sudo systemctl reload nginx
163-
```
164-
165-
需要注意的是,如果配置文件中存在错误,`nginx -s reload` 会报出错误,然后 Nginx 会以旧的配置文件继续运行。
166-
167-
## Nginx 名词解释
168-
169-
在向你展示如何进阶配置 Nginx 之前,有一些你必须要了解的概念。
170-
171-
### server 块
172-
173-
Nginx 的配置文件中可以有多个 server 块,每个 server 块定义了一个站点(虚拟主机),Nginx 会根据请求的域名和端口号来匹配对应的 server 块。
174-
Nginx 正是通过 server 块来实现多站点配置的。
175-
一个典型的 server 块:
176-
177-
```nginx
178-
server {
179-
listen 80; # 监听的端口
180-
server_name example.com; # 服务器名称
181-
182-
location / {
183-
# 处理请求的指令
184-
}
185-
}
186-
```
187-
188-
### location 块
189-
190-
location 块嵌套于 server 块中,用于定义如何处理特定 URI 的请求。一个 server 块中可以有多个 location 块。
191-
192-
Nginx 的 location 块用于定义如何处理特定 URI 的请求。它是 Nginx 配置中的一个重要部分,允许您根据请求的路径、参数或其他条件来执行不同的操作。
193-
194-
一个 location 块的基本结构如下:
195-
196-
```nginx
197-
location [modifier] /path/ {
198-
# 处理请求的指令
199-
}
200-
```
201-
202-
### 反向代理与负载均衡
203-
204-
反向代理是指代理服务器接收客户端的请求,然后将请求转发给后端服务器,最后将后端服务器的响应返回给客户端。反代有不同协议的区分,如 HTTP 反代、TCP 反代、UDP 反代等。
205-
206-
负载均衡是指将请求分发给多个后端服务器,以达到均衡负载的目的。Nginx 支持多种负载均衡算法,如轮询、加权轮询、IP 哈希、最少连接等。
207-
208-
一个十分巧妙的负载均衡算法是一致性哈希算法,它可以保证在服务器数量变化时,尽可能少地改变已有的映射关系。推荐阅读:[一致性哈希算法](https://zh.wikipedia.org/wiki/%E4%B8%80%E8%87%B4%E5%93%88%E5%B8%8C)
209-
210-
### TLS
211-
212-
TLS 是一种加密通信协议,用于保护客户端和服务器之间的通信安全。Nginx 支持 TLS 协议,可以用来配置 HTTPS 站点。
213-
214-
一般的 HTTP 监听端口是 80,HTTPS 监听端口是 443,这是 IANA(互联网号码分配局)为这两种协议分配的标准端口号。
215-
216-
### WebSocket
217-
218-
WebSocket 是一种全双工通信协议,用于在客户端和服务器之间建立持久连接,实现实时通信。Nginx 支持 WebSocket 协议,可以用来配置 WebSocket 服务器。
212+
需要注意的是,如果配置文件中存在错误,重新加载的时候会报出这些错误,然后 Nginx 会以旧的配置文件继续运行。
219213

220214
## 示例讲解
221215

@@ -261,10 +255,29 @@ server {
261255
```
262256

263257
`default_server` 又是什么意思呢?它表示默认站点,当请求的域名不在 server_name 中时,Nginx 会使用 `default_server` 对应的 server 块来处理请求。
264-
该站点的 server_name 指定为 `_`,是一种约定俗成的默认域名,没有特殊含义
258+
该站点的 server_name 指定为 `_`,是一种约定俗成的默认域名,本身没有特殊含义
265259
对于配置了 `default_server` 的 server 块,你也可以完全不写 `server_name` 指令。
266260
一般建议为 Nginx 配置一个默认站点,用于处理未知域名的请求。
267261

262+
!!! example "拒绝未知域名请求"
263+
264+
你也可以通过配置一个默认站点来拒绝未知域名的请求,例如:
265+
266+
```nginx
267+
server {
268+
listen 80 default_server; # 默认站点
269+
listen [::]:80 default_server;
270+
listen 443 default_server ssl; # 默认站点(HTTPS)
271+
listen [::]:443 default_server ssl;
272+
ssl_reject_handshake on; # 拒绝 SSL 握手
273+
return 444; # 直接关闭连接
274+
}
275+
```
276+
277+
这样,当请求的域名不符合任何一个已经配置的 server_name 时,Nginx 对于 HTTP 请求会直接关闭连接,同时拒绝 HTTPS 请求的 SSL 握手。
278+
279+
一些特定地区或环境的监管要求 HTTP 服务器对未备案登记的域名的请求拒绝响应,这时可以使用这种配置。
280+
268281
### Location 块详解
269282

270283
一个典型的 location 块如下:
@@ -275,11 +288,23 @@ location [modifier] /path/ {
275288
}
276289
```
277290

278-
首先来看 `modifier`,它是一个可选的修饰符,用于修改 location 块的匹配规则。常用的修饰符有:
291+
在 location 块里,我们可以使用一些指令来处理请求,如:
292+
293+
- `proxy_pass http://backend_server;`:反向代理。
294+
- `root /var/www/html;`:指定网站根目录。
295+
- `try_files $uri $uri/ =404;`:尝试查找文件,如果找不到返回 404 错误。
296+
- `return 200 "Hello, World!";`:返回指定的状态码和内容。
297+
- `include fastcgi_params;`:引入 FastCGI 参数。
298+
299+
#### Location 匹配
279300

280-
- 前缀匹配(无修饰符)
301+
Nginx 需要决定由哪个 location 块来处理请求时,会根据请求的 URI path 来匹配 location 块。
281302

282-
前缀匹配是 location 块的默认匹配规则,只要请求的路径以 location 块的路径开头,就会匹配成功。例如:
303+
Nginx 支持多种匹配方式,主要通过 location 指令后面的可选修饰符来区分。常用的修饰符有:
304+
305+
前缀匹配(无修饰符)
306+
307+
: 前缀匹配是最基本的匹配方式,只要请求的路径以 location 块的路径开头,就会匹配成功。例如:
283308

284309
```nginx
285310
location /example {
@@ -288,9 +313,18 @@ location [modifier] /path/ {
288313
}
289314
```
290315

291-
- 前缀匹配 `^~`
316+
多个前缀匹配时,Nginx 会选择匹配前缀最长的 location 块。例如:
292317

293-
这是另一种形式的前缀匹配,匹配规则与无修饰符相同,但会阻止后续的正则匹配检查。
318+
```nginx
319+
location /example { ...; }
320+
location /example/sub { ...; }
321+
```
322+
323+
在此例中,请求 `/example`、`/example123` 和 `/example/test` 会匹配第一个 location;请求 `/example/sub/page` 会匹配到第二个 location,因为它的前缀更长。
324+
325+
前缀匹配 `^~`
326+
327+
: 这是另一种形式的前缀匹配,匹配规则与无修饰符相同,但会阻止后续的正则匹配检查。
294328

295329
```nginx
296330
location ^~ /static/ {
@@ -304,9 +338,11 @@ location [modifier] /path/ {
304338
}
305339
```
306340

307-
- `=`
341+
在这个例子中,如果请求的 URI 是 `/static/style.css`,则会匹配到第一个 location 块,因为它是以 `/static/` 开头的前缀匹配,且使用了 `^~`,Nginx 不会继续检查正则匹配。
342+
343+
精确匹配 `=`
308344

309-
精确匹配,只有请求的路径与 location 块的路径完全相同时才匹配。
345+
: 精确匹配,只有请求的路径与 location 块的路径完全相同时才匹配。
310346

311347
```nginx
312348
location = /example {
@@ -316,13 +352,17 @@ location [modifier] /path/ {
316352
}
317353
```
318354

319-
- 区分大小写的正则匹配 `~` 与不区分大小写的正则匹配 `~*`,例如:
355+
正则匹配
356+
357+
: 正则匹配的 modifier 有两种,区分大小写的 `~` 与不区分大小写的 `~*`
358+
两种 modifier 具有完全相同的优先级,例如:
320359

321360
```nginx
322361
location ~ /example[0-9] {
323362
# 处理请求 /example1, /example2, ...
324363
return 200 "This is a case-sensitive regex match.";
325364
}
365+
326366
location ~ \.php$ {
327367
# 处理以 .php 结尾的请求
328368
include fastcgi_params;
@@ -335,13 +375,11 @@ location [modifier] /path/ {
335375
}
336376
```
337377

338-
在这个例子中,如果请求的 URI 是 `/static/style.css`,则会匹配到第一个 location 块,因为它是以 `/static/` 开头的前缀匹配。即使 `/static/style.css` 也符合第二个正则匹配的条件,但由于第一个 location 块使用了 `^~`,Nginx 不会继续检查正则匹配。
339-
340378
#### Location 块的匹配顺序
341379

342380
Nginx 在处理请求时会按照以下顺序匹配 location 块:
343381

344-
1. 精确匹配 (=)。
382+
1. 精确匹配 (`=`)。
345383
2. 前缀匹配(无修饰符和 `^~`,按最长前缀匹配)。
346384

347385
在此步骤中,所有无修饰符和 `^~` 的 location 块会一起参与匹配,Nginx 会选择匹配前缀最长的 location。
@@ -352,15 +390,11 @@ Nginx 在处理请求时会按照以下顺序匹配 location 块:
352390
如果有匹配到的正则表达式,Nginx 会使用该 location 块处理请求。
353391
如果没有匹配到的正则表达式,Nginx 会使用第二步中匹配到的前缀 location 块处理请求。
354392

355-
而在 location 块中,我们可以使用一些指令来处理请求,如:
393+
### SSL/TLS 配置
356394

357-
- `proxy_pass http://backend_server;`:反向代理。
358-
- `root /var/www/html;`:指定网站根目录。
359-
- `try_files $uri $uri/ =404;`:尝试查找文件,如果找不到返回 404 错误。
360-
- `return 200 "Hello, World!";`:返回指定的状态码和内容。
361-
- `include fastcgi_params;`:引入 FastCGI 参数。
395+
TLS 是一种加密通信协议,用于保护客户端和服务器之间的通信安全。Nginx 支持 TLS 协议,可以用来配置 HTTPS 站点。
362396

363-
### SSL/TLS 配置
397+
一般的 HTTP 监听端口是 80,HTTPS 监听端口是 443,这是 IANA(互联网号码分配局)为这两种协议分配的标准端口号。
364398

365399
作为 WebServer,必不可少的功能就是支持 HTTPS。你可以在 <https://cherr.cc/ssl.html> 找到 SSL/TLS 的原理解释。
366400

@@ -490,6 +524,8 @@ server {
490524

491525
!!! bug "Grafana 需要 websocket 反代支持"
492526

527+
WebSocket 是一种全双工通信协议,用于在客户端和服务器之间建立持久连接,实现实时通信。Nginx 支持 WebSocket 协议,可以用来配置 WebSocket 服务器。
528+
493529
参考:<https://grafana.com/tutorials/run-grafana-behind-a-proxy/>
494530

495531
关键在于 Grafana 加载数据时使用了 WebSocket,需要指示 Nginx 支持 WebSocket 反代。
@@ -551,6 +587,10 @@ http {
551587

552588
#### 负载均衡算法
553589

590+
负载均衡是指将请求分发给多个后端服务器,以达到均衡负载的目的。Nginx 支持多种负载均衡算法,如轮询、加权轮询、IP 哈希、最少连接等。
591+
592+
一个十分巧妙的负载均衡算法是一致性哈希算法,它可以保证在服务器数量变化时,尽可能少地改变已有的映射关系。推荐阅读:[一致性哈希算法](https://zh.wikipedia.org/wiki/%E4%B8%80%E8%87%B4%E5%93%88%E5%B8%8C)
593+
554594
Nginx 支持多种负载均衡算法,默认是轮询(round-robin)。你可以通过在 upstream 块中指定不同的算法来更改负载均衡策略,例如:
555595

556596
最少连接:

mkdocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ nav:
117117
- ops/network-service/index.md
118118
- 网络时间同步: ops/network-service/ntp.md
119119
- 隧道组网: ops/network-service/intranet.md
120-
- Nginx 网页服务器: ops/network-service/nginx.md
120+
- Nginx 服务器: ops/network-service/nginx.md
121121
- Zeroconf: ops/network-service/zeroconf.md
122122
- 数据库:
123123
- ops/database/index.md

0 commit comments

Comments
 (0)