22icon : 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
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+ # 或者
156209sudo 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
342380Nginx 在处理请求时会按照以下顺序匹配 location 块:
343381
344- 1. 精确匹配 (= )。
382+ 1 . 精确匹配 (` = ` )。
3453832 . 前缀匹配(无修饰符和 ` ^~ ` ,按最长前缀匹配)。
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+
554594Nginx 支持多种负载均衡算法,默认是轮询(round-robin)。你可以通过在 upstream 块中指定不同的算法来更改负载均衡策略,例如:
555595
556596最少连接:
0 commit comments