介绍
Nginx是一个高性能的网页服务器,负责处理互联网上一些最大的网站的负载。它特别擅长处理许多同时连接,并擅长传输或提供静态内容。
了解 Nginx 配置背景
本指南将涵盖主 Nginx 配置文件的结构。此文件的位置将取决于 Nginx 是如何安装的。在许多 Linux 发行版中,该文件将位于 /etc/nginx/nginx.conf
。如果它不存在,它也可以位于 /usr/local/nginx/conf/nginx.conf
或 /usr/local/etc/nginx/nginx.conf
。
当你观察主配置文件时,你应该注意的第一件事之一是,它是以树类的结构来组织的,标记为支架集({
和 }
)。在 Nginx 文档中,这些支架定义的区域被称为背景
,因为它们包含配置细节,根据其关心区域分开。
由于背景可以相互层次化,所以 Nginx 允许继承配置. 一般来说,如果一个指令在多个嵌入范围内有效,那么在更广泛的背景下的一份声明将作为默认值传递给任何儿童背景。
指令只能在它们设计的环境中使用。Nginx在读取配置文件时会引发错误,指令被宣称处于错误的环境中。
下面我们将讨论您在与 Nginx 合作时可能遇到的最常见的背景。
核心背景
我们将讨论的第一个背景组是 Nginx 使用的核心背景来创建一个层次结构树,并分离分散的配置块,这些背景构成了 Nginx 配置的主要结构。
主要背景
最一般的背景是主要
或全球
的背景,它是唯一不包含在典型的背景块中的背景,看起来像这样:
1[label /etc/nginx/nginx.conf]
2# The main context is here, outside any other contexts
3
4. . .
5
6context {
7
8 . . .
9
10}
请记住,如果您的 Nginx 配置以模块化的方式设置 - 也就是说,在多个文件中配置选项 - 一些文件将包含指令,这些指令似乎存在于组合的背景之外,但在配置加载时将被包含在一个背景中。
主要的背景代表了 Nginx 配置的最广泛的环境,用于配置影响整个应用程序的细节,而本节中的指令影响了较低的背景,但在较低的层次中,许多情况都无法被夸大。
在主要背景下配置的一些常见细节是系统用户和运行工人进程的组,工人数量,以及存储主 Nginx 进程的 ID 的文件。
事件背景
事件
背景包含在主要
背景中,用来设置影响 Nginx 如何在一般层面处理连接的全球选项,在 Nginx 配置中只能定义一个事件背景。
这个背景在配置文件中会看起来像这样,除了其他任何嵌入式的背景之外:
1[label /etc/nginx/nginx.conf]
2# main context
3
4events {
5
6 # events context
7 . . .
8
9}
Nginx 使用一个基于事件的连接处理模型,因此在这种情况下定义的指令决定了工人流程应该如何处理连接。
通常,连接处理方法是根据平台提供的最有效的选择自动选择的,对于Linux系统来说,epoll
方法通常是最好的选择。
其他可以配置的项目包括每个工人可以处理的连接数量,无论工人是否会一次只进行一次连接,或在收到有关即将到来的连接通知后接受所有等待连接,以及工人是否会轮换响应事件。
HTTP 背景
当配置 Nginx 作为 Web 服务器或反向代理时,http
文本将占据大多数配置,此文本将包含所有指令和其他必要的文本,以定义程序将如何处理 HTTP 或 HTTPS 连接。
http 背景是事件背景的兄弟,所以它们应该排列一对一,而不是嵌入其中。
1[label /etc/nginx/nginx.conf]
2# main context
3
4events {
5 # events context
6
7 . . .
8
9}
10
11http {
12 # http context
13
14 . . .
15
16}
虽然较低的背景更具体地了解如何处理请求,但此级的指令控制了内部定义的每个虚拟服务器的默认值。
您可能遇到的数据的一些指令控制了访问和错误日志的默认位置(‘access_log’和 ‘error_log’),为文件操作配置非同步 I/O(‘aio’、‘sendfile’和 ‘directio’),并在出现错误时配置服务器的状态(‘error_page’)。其他指令配置了压缩(‘gzip’和 ‘gzip_disable’),精确调整了TCP保持活着的设置(‘keepalive_disable’、‘keepalive_requests’和‘keepalive_timeout’),以及Nginx将遵循的规则来尝试优化包和系统调用(‘sendfile’、‘tcp_elpes’和 ‘tcnop_push’)。
服务器背景
服务器
的背景被声明为http
的背景中。这是我们第一个嵌入式、嵌入式的背景示例,也是第一个允许多个声明的背景。
服务器背景的一般格式可能看起来像这样的东西. 请记住,这些都位于HTTP环境中:
1[label /etc/nginx/nginx.conf]
2# main context
3
4http {
5
6 # http context
7
8 server {
9
10 # first server context
11
12 }
13
14 server {
15
16 # second server context
17
18 }
19
20}
您可以声明多个服务器
背景,因为每个实例定义了一个特定的虚拟服务器来处理客户端请求。
每个客户端请求将根据单个服务器环境中定义的配置进行处理,因此 Nginx 必须根据请求的细节决定哪个服务器环境最合适。
- listen:这个服务器块旨在响应的IP地址/端口组合.如果一个符合这些值的客户端提出请求,这个区块可能会被选中来处理连接
- server_name:本指令是选择服务器块进行处理的其他组件。
在这种情况下,指令可以超越许多可能在HTTP环境中定义的指令,包括日志,文档根,压缩等。除了从HTTP环境中采用的指令,我们还可以配置文件来尝试响应请求(‘try_files’),输出重定向和重写(‘return’和‘rewrite’),并设置任意变量(‘set’)。
位置背景
位置背景与服务器背景共享许多关系特性,例如,可以定义多个位置背景,每个位置用于处理特定类型的客户端请求,每个位置通过选择算法来匹配位置定义与客户端请求。
虽然决定是否选择服务器块的指令是在服务器 context 中定义的,但决定一个位置处理请求的能力的组件位于位置 definition 中(打开位置块的行)。
一般的语法看起来像这样:
1[label /etc/nginx/nginx.conf]
2location match_modifier location_match {
3
4 . . .
5
6}
位置块生活在服务器环境中,不同于服务器块,可以相互嵌入,这可以有助于创建一个更一般的位置环境来捕捉某一特定子集的流量,然后根据更具体的标准进一步处理它,并在内有额外的背景:
1[label /etc/nginx/nginx.conf]
2# main context
3
4server {
5
6 # server context
7
8 location /match/criteria {
9
10 # first location context
11
12 }
13
14 location /other/criteria {
15
16 # second location context
17
18 location nested_match {
19
20 # first nested location
21
22 }
23
24 location other_nested {
25
26 # second nested location
27
28 }
29
30 }
31
32}
虽然服务器背景是根据所请求的 IP 地址/端口组合和主机
标题中的主机名称进行选择的,但位置块通过查看请求 URI 来进一步分割服务器块内的请求处理。
例如,假设一个客户端在端口上请求http://www.example.com/blog
80。 http
、www.example.com
和 80 个端口的组件将被单独用于确定要选择哪个服务器块。
此级别的新指令允许您访问文档根外的位置(‘alias’),将该位置标记为仅可内部访问(‘internal’),并向其他服务器或位置代理(使用 http、fastcgi、scgi 和 uwsgi 代理)。
其他背景
虽然上述示例代表了您将遇到的 Nginx 的基本情况,但其他情况也存在,以下情况下仅在某些情况下使用,或者用于大多数人不会使用的功能:
% split_客户端 : 此上下文被配置为将服务器接收的客户端通过基于一个百分比的变量标注来将客户端分成类别. 然后,这些可以通过向不同的主机提供不同的内容来进行A/B测试. (_) ( ) ================================================= ========================================================================================================================= (============ (============ 这些上下文为 Perl 处理器配置了它们出现的位置 。 这将只用于 Perl.
- 处理 地图: 此上下文用于根据另一个变量的值设定变量的值. 它提供了一个变量值的映射,以确定第二个变量应该设置到什么.
- XQGeo
**:和上下文一样,此上下文用于指定一个映射. 然而,这种映射被专门用来分类客户端IP地址. 它根据连接的IP地址设置变量的值. (_) ( )* QQ类型 : 此上下文再次用于映射. 此上下文用于将 MIME 类型映射到应该与之相关的文件扩展名 。 这通常通过一个输入主
nginx的文件提供。 conf ' 配置文件 。 (_) ) * QQCharset_map
**: 这是绘图背景的另一个例子。 此上下文用于映射从一个字符集到另一个字符集的转换表. 在上下文标题中,两套都列出,在正文中,绘图进行. (_) (英语)
上游背景
上游语境用于定义和配置上游
服务器. 此语境定义了一个名为群的服务器, Nginx 然后可以向其发送代理请求。
上游背景应该放在HTTP环境中,在任何特定的服务器环境之外。
1[label /etc/nginx/nginx.conf]
2# main context
3
4http {
5
6 # http context
7
8 upstream upstream_name {
9
10 # upstream context
11
12 server proxy_server1;
13 server proxy_server2;
14
15 . . .
16
17 }
18
19 server {
20
21 # server context
22
23 }
24
25}
然后,上游背景可以通过服务器或位置块中的名称进行引用,以便将某种类型的请求传递给已定义的服务器池。
如果背景
与传统编程中的 if 语句一样, Nginx 中的 if 语句将执行包含的指令,如果给定的测试返回真
。
Nginx中的 if 背景是由重写模块提供的,这是这个背景的主要用途,因为 Nginx 会用许多其他有目的的指令来测试请求的条件,所以if
不应该用于大多数形式的条件执行。
问题在于 Nginx 处理命令往往会导致意想不到的结果. 被认为在这些情况下可靠地安全使用的唯一指令是返回
和重写
指令(这些指令是为这种情况而创建的)。
最常见的是,如果将被用来确定是否需要重写或返回,这些通常会存在于位置块中,所以常见的表格将看起来像这样:
1[label /etc/nginx/nginx.conf]
2# main context
3
4http {
5
6 # http context
7
8 server {
9
10 # server context
11
12 location location_match {
13
14 # location context
15
16 if (test_condition) {
17
18 # if context
19
20 }
21
22 }
23
24 }
25
26}
局限 - 除了背景
例如,如果只有某些客户端应该能够访问 POST 内容,但每个人都应该能够读取内容,则可以使用limit_except
块来定义此要求。
上面的例子会看起来像这样:
1[label /etc/nginx/nginx.conf]
2. . .
3
4# server or location context
5
6location /restricted-write {
7
8 # location context
9
10 limit_except GET HEAD {
11
12 # limit_except context
13
14 allow 192.168.1.1/24;
15 deny all;
16 }
17}
在遇到任何 HTTP 方法时,这将适用于文本内的指令(旨在限制访问),除了文本标题中列出的任何 HTTP 方法。上面的示例的结果是,任何客户端都可以使用 GET 和 HEAD 词汇,但只有来自192.168.1.1/24
子网的客户端可以使用其他方法。
要遵循的背景规则
现在你已经了解到你在探索 Nginx 配置时可能会遇到的常见背景,我们可以讨论处理 Nginx 背景时使用的一些最佳实践。
在可用的最高背景下应用指令
例如,有很多指令可以在HTTP、服务器或位置环境中放置,这为我们提供了设置这些指令的灵活性。
作为一般规则,通常最好在它们适用的最高背景下声明指令,并在必要时在较低的背景下优先考虑它们。
首先,高级别声明允许您避免在兄弟背景之间不必要重复,例如,在下面的示例中,每个位置声明相同的文档根:
1[label /etc/nginx/nginx.conf]
2http {
3 server {
4 location / {
5 root /var/www/html;
6
7 . . .
8
9 }
10
11 location /another {
12 root /var/www/html;
13
14 . . .
15
16 }
17
18 }
19}
您可以将 root 移动到服务器块,甚至移动到 http 块,如下:
1http {
2 root /var/www/html;
3 server {
4 location / {
5
6 . . .
7
8 }
9
10 location /another {
11
12 . . .
13
14 }
15 }
16}
大多数时候,服务器级别将是最合适的,但在较高级别宣言有其优点。这不仅允许您在较少的地方设置指令,还允许您将默认值降至所有儿童元素,防止您通过忘记在较低级别的指令出现错误的情况。
使用多个兄弟背景,而不是如果逻辑处理
当你想要以不同的方式处理请求,取决于客户端请求中可以找到的一些信息时,用户经常跳到如果
的背景,试图调节处理。
首先是如果
指令往往会返回不符合管理员期望的结果,虽然处理过程总是会以相同的输入导致相同的结果,但 Nginx 对环境的解释方式可能不同于在没有强烈的测试的情况下可以假设的。
第二个原因是,已经有优化,有目的的指令,用于许多这些目的。Nginx已经使用了一种经过记录的选择算法,比如选择服务器块和位置块。
例如,而不是依靠重写来将用户提供的请求输入到您想要使用的格式中,您应该尝试为请求设置两个块,其中一个代表了所需的方法,另一个则捕捉了混乱的请求并重定向(并可能重写)到正确的块。
正确的请求没有进行额外处理,在许多情况下,错误的请求可以通过重定向而不是重写,这应该以较低的重定向执行。
结论
到目前为止,你应该对 Nginx 最常见的背景和创建定义它们的区块的指令有很好的了解。
始终检查 Nginx 的文档以获取有关指令可以放置在哪些背景的信息,并评估最有效的位置。
接下来,您可以学习如何使用 Nginx 配置密码身份验证(https://andsky.com/tech/tutorials/how-to-set-up-password-authentication-with-nginx-on-ubuntu-22-04)。