基于域名的虚拟服务器
Nginx会决定使用哪一个服务器接收请求。下面让我们看一个简单的配置示例,3台虚拟服务器都监听着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字段决定请求应该由哪一台服务器处理,如果Host字段的值没有相匹配的服务器或者请求中没有Host字段,那么Nginx会将请求路由至这个端口的默认服务器。在上文的配置中,默认的服务器是第一台,这是Nginx的默认策略。默认服务器是可以显式配置的,在listen指令使用default_server参数即可指定服务器为该端口的默认服务器。
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; }
上述配置中,server_name设置为空字符串,将匹配没有携带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首先使用server块的listen指令的配置去测试请求的ip地址以及端口,然后使用server_name去测试Host字段如果请求匹配了Ip地址以及端口。如果域名没有找到,请求将由默认服务器处理。举个例子,在192.168.1.1:80端口收到了对于www.example.com的请求,因为没有为该端口定义www.example.com的server_name,请求将由192.168.1.1:80的默认服务器处理,即配置中的第一台服务器。
如之前所述,默认服务器是监听端口的属性之一,并且可以为不同的监听端口匹配不同的默认服务器。
简单php站点的配置
接下来了解nginx如何处理简单php站点的请求,访问到请求所选择的location。
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会查找最明确的location前缀,并非根据配置中所定义的顺序。在上述配置中,"/"是最通用的,能够匹配任何请求,会被作为最后的手段使用。 然后nginx会按顺序使用配置中的location的正则表达式匹配地址。当匹配成功时,nginx会停止查找并且使用该location。如果请求没有和任何正则表达式匹配成功,那么nginx会使用之前查找到的最明确的location前缀。 值得注意的是,所有类型的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)$”匹配,因此它将由后一个location处理。使用指令“root/data/www”将请求映射到文件/data/www/logo.gif,并将文件发送到客户端。
- 请求”/index.php”首先由前缀”/”匹配,然后由正则表达式”/.(php)$”匹配。因此它将由后一个location处理,并且被转发到监听着location:9000端口的FastCGI服务器。fastcgi_param指令将FastCGI变量SCRIPT_FILENAME设置为”/data/www/index.php”,然后FastCGI执行该文件。变量$document_root变量等于root指令的值,变量$fastcgi_script_name等于请求的URI,即”/index.php”。
- 请求”/about.html”只由前缀”/”匹配,因此将由该location处理。使用指令”root /data/www”将请求映射到文件/data/www/about.html,然后发送到客户端。
- 处理请求”/”比较复杂。它只匹配了前缀”/”,因此由该location处理。然后index指令根据设置的变量以及”root /data/www”指令检查index文件是否存在。如果/data/www/index.html不存在,/data/www/index.php存在,会内部重定向到”index.php”,然后nginx再次使用这个地址搜索合适的location。正如我们之前所看到的,重定向的请求最终会被FastCGI服务器处理。
Igor Sysoev写作
Brian Mercer修改
kailuncen 翻译
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/98139.html