基于名称的虚拟服务器
-
nginx首先决定哪个服务器应该处理请求。让我们从一个简单的配置开始,其中所有三个虚拟服务器都在端口*:80上侦听:
server{ listen 80; server_name example.org www.example.org; ... } server{ listen 80; server_name example.net www.example.net; ... } server{ listen 80; server_name example.com www.example.com; ... }
-
在此配置中,nginx仅测试请求头的字段“Host”,以确定请求应路由到哪个服务器。如果其值与任何服务器名称都不匹配,或者请求根本不包含此标头字段,则nginx会将请求路由到此端口的默认服务器。在上面的配置中,默认服务器是第一个-这是nginx的标准默认行为。它也可以default_server使用listen指令中的参数明确设置哪个服务器应该是默认的:
server { listen 80 default_server ; server_name example.net www.example.net; ... }
-
该default_server参数自版本0.8.21起可用。在早期版本中,default应该使用参数。
-
请注意,默认服务器是侦听端口的属性,而不是服务器名称的属性。稍后会详细介绍。
-
如何使用未定义的服务器名称来防止处理请求
如果不允许没有“Host”头字段的请求,则可以定义只删除请求的服务器:server { listen 80; server_name ""; return 444; }
-
这里,服务器名称设置为一个空字符串,它将匹配没有“Host”头字段的请求,并返回一个特殊的nginx非标准代码444来关闭连接。
-
从版本0.8.48开始,这是服务器名称的默认设置,因此server_name ""可以省略。在早期版本中,计算机的主机名用作默认服务器名称。
基于名称的混合和基于IP的虚拟服务器
-
让我们看一个更复杂的配置,其中一些虚拟服务器监听不同的地址:
server{ listen 192.168.1.1:80; server_name example.org www.example.org; ... } server{ listen 192.168.1.1:80; server_name example.net www.example.net; ... } server{ listen 192.168.1.2:80; server_name example.com www.example.com; ... }
-
在此配置中,nginx首先根据服务器块的listen指令 测试请求的IP地址和端口 。然后,它针对 与IP地址和端口匹配的服务器块的server_name 条目 测试请求的
Host
头字段 。如果未找到服务器名称,则默认服务器将处理该请求。例如,请求http://192.168.1.1:80端口上的接收请求将由192.168.1.1:80端口的默认服务器处理,即由第一个服务器处理,因为请求头中的Host
字段为192.168.1.1:80。 -
如前所述,默认服务器是监听端口的属性,可以为不同的端口定义不同的默认服务器:
server{ listen 192.168.1.1:80; server_name example.org www.example.org; ... } server { listen 192.168.1.1:80 default_server ; server_name example.net www.example.net; ... } server { listen 192.168.1.2:80 default_server ; server_name example.com www.example.com; ... }
一个简单的PHP站点配置
-
现在让我们看一下nginx如何选择一个位置来处理一个典型的简单PHP站点的请求:
server { listen 80; server_name example.org www.example.org; root /data/www; location / { index index.html index.php; } location ~* \.(gif|jpg|png)$ { expires 30d; } location ~ \.php$ { fastcgi_pass localhost:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
-
nginx首先搜索由文字字符串给出的最具体的前缀位置,而不管列出的顺序如何。在上面的配置中,唯一的前缀位置是“ /”,因为它匹配任何请求,它将被用作最后的手段。然后nginx按照配置文件中列出的顺序检查正则表达式给出的位置,直到匹配一个表达式,停止搜索,nginx将使用此location。如果没有正则表达式匹配请求,则nginx使用先前找到的最具体的前缀位置。
-
请注意,所有类型的location仅测试不带参数的请求参数的URI部分。这样做是因为查询字符串中的参数可以通过多种方式给出,例如:
/index.php?user=john&page=1 /index.php?page=1&user=john
此外,任何人都可以在查询字符串中请求任何内容
/index.php?page=1&something+else&user=john
-
现在让我们看看如何在上面的配置中处理请求:
-
请求
/logo.gif
首先与前缀位置/
匹配,然后由正则表达式\.(gif|jpg|png)$
匹配,因此,它由后一位置处理。使用指令root /data/www
将请求映射到文件/data/www/logo.gif
,并将文件发送到客户端。 -
请求
/index.php
也首先与前缀位置/
匹配,然后由正则表达式\.(php)$
匹配。因此,它由后一个位置处理,请求被传递给侦听localhost:9000
的FastCGI服务器。该fastcgi_param
指令设置FastCGI的参数SCRIPT_FILENAME
为/data/www/index.php
,并FastCGI的服务器执行该文件。变量$document_root
等于root 指令的值, 变量$fastcgi_script_name
等于请求URI,即“/index.php”。
请求“/about.html”仅与前缀位置“/” 匹配,因此,它在此位置处理。使用指令“root /data/www”将请求映射到文件/data/www/about.html,并将文件发送到客户端。 -
处理请求“/”更复杂。它仅与前缀位置“/” 匹配,因此,它由此location处理。然后索引指令根据其参数和“root /data/www”指令测试索引文件是否存在。如果该文件/data/www/index.html不存在,并且该文件/data/www/index.php存在,(查看location 下的 index 指令),则该指令执行内部重定向到“/index.php”,并且nginx再次搜索位置,就像请求已由客户端发送一样。正如我们之前看到的,重定向的请求最终将由FastCGI服务器处理。
nginx如何处理TCP / UDP会话
来自客户端的TCP / UDP会话在称为阶段的连续步骤中处理:
- Post-accept
接受客户端连接后的第一阶段。该ngx_stream_realip_module 模块在这个阶段被调用。 - Pre-access
初步检查访问。该ngx_stream_limit_conn_module 模块在这个阶段被调用。 - Access
实际数据处理前的客户端访问限制。该ngx_stream_access_module 模块在这个阶段被调用。 - SSL
TLS / SSL终止。该ngx_stream_ssl_module 模块在这个阶段被调用。 - Preread
将初始数据字节读入 预读缓冲区, 以允许诸如ngx_stream_ssl_preread_module之类的模块 在处理之前分析数据。 - Content
实际处理数据的强制阶段(通常 代理到 上游服务器)或指定值返回给客户端。 - Log
记录客户端会话处理结果的最后阶段。该ngx_stream_log_module 模块在这个阶段被调用。
网友评论