基于名称的虚拟服务器 基于名称(指HTTP请求头Host字段)的虚拟服务器指通过HTTP请求头的Host来决定客户端请求由哪个server进行处理。 让我们从一个简单的配置开始,下面配置了三个虚拟服务器,它们均侦听80端口:server{listen80;servernameexample。orgwww。example。。。。}server{listen80;servernameexample。netwww。example。。。。}server{listen80;servernameexample。comwww。example。。。。} 上面配置中,nginx仅测试请求的头字段Host以确定应将请求路由到哪个server。如果Host的值与任何server名称都不匹配,或者请求根本不包含Host头字段,则nginx会将请求路由到此端口的默认server。 上面的配置中,默认server是第一个这是nginx的标准默认行为。还可以使用listen指令中的defaultserver参数明确设置哪个server应该是默认server:server{listen80servernameexample。netwww。example。。。。} 注意:defaultserver参数从0。8。21版本开始可用。在早期版本中,应该使用默认参数。如何防止处理具有未定义server名称的请求? 如果不允许处理没有Host头字段的客户端请求(反过来说,只处理带有Host头字段的客户端请求),可以定义一个只丢弃请求的server:server{listen80;return444;} 在这里,servername设置为一个空字符串,它将匹配没有Host头字段的请求,并返回一个特殊的nginx非标准代码444来关闭连接。 注意:从0。8。48版本开始,servername的默认设置为一个空字符串,因此可以省略servername。在早期版本中,机器的主机名被用作servername默认值。混合基于名称和基于IP的虚拟服务器 让我们看一个更复杂的配置,其中一些虚拟服务器侦听不同的地址:server{listen192。168。1。1:80;servernameexample。orgwww。example。。。。}server{listen192。168。1。1:80;servernameexample。netwww。example。。。。}server{listen192。168。1。2:80;servernameexample。comwww。example。。。。} 上面配置中,nginx首先根据server块的listen指令测试请求的IP地址和端口。然后,它根据与IP地址和端口匹配的server块的servername条目测试请求的Host标头字段。如果未找到服务器名称,则请求将由默认服务器处理。例如,在192。168。1。1:80端口上收到的www。example。com请求将由192。168。1。1:80端口的默认服务器处理,即由第一个服务器处理,因为没有www。example。com为此端口定义。 如前所述,默认服务器是监听端口的一个属性,可以为不同的端口定义不同的默认服务器:server{listen192。168。1。1:80;servernameexample。orgwww。example。。。。}server{定义默认服务器listen192。168。1。1:80servernameexample。netwww。example。。。。}server{定义默认服务器listen192。168。1。2:80servernameexample。comwww。example。。。。}一个简单的PHP站点配置 现在让我们看看nginx如何选择一个位置来处理一个典型的、简单的PHP站点的请求:server{listen80;servernameexample。orgwww。example。location{indexindex。htmlindex。}location。(gifjpgpng){expires30d;}location。php{fastcgipasslocalhost:9000;fastcgiparamSCRIPTFILENAME}} 无论列出的顺序如何,nginx首先搜索由文字字符串给出的最具体的前缀位置。在上面的配置中,唯一的前缀位置是,并且由于它匹配任何请求,因此将用作最后的手段。然后nginx按照配置文件中列出的顺序检查正则表达式给出的位置。第一个匹配的表达式停止搜索,nginx将使用这个位置。如果没有正则表达式匹配请求,则nginx使用之前找到的最具体的前缀位置。 注意:所有类型的位置仅测试不带参数的请求行的URI部分。这样做是因为查询字符串中的参数可以通过多种方式给出,例如:index。php?userjohnpage1index。php?page1userjohn 此外,任何人都可以在查询字符串中请求任何内容:index。php?page1somethingelseuserjohn 现在让我们看看在上面的配置中如何处理请求:请求logo。gif首先与前缀位置匹配,然后与正则表达式。(gifjpgpng)匹配,因此由后一个位置处理。使用指令rootdatawww将请求映射到文件datawwwlogo。gif,并将该文件发送到客户端。请求index。php也首先匹配前缀位置,然后匹配正则表达式。(php)。因此,它由后一个位置处理,并将请求传递给侦听localhost:9000的FastCGI服务器。fastcgiparam指令将FastCGI参数SCRIPTFILENAME设置为datawwwindex。php,FastCGI服务器执行该文件。变量documentroot等于root指令的值,变量fastcgiscriptname等于请求URI,即index。php。请求about。html只匹配前缀位置,因此在该位置处理。使用指令rootdatawww将请求映射到文件datawwwabout。html,并将该文件发送到客户端。处理请求更为复杂。它仅与前缀位置匹配,因此由该位置处理。然后index指令根据其参数和rootdatawww指令测试索引文件是否存在。如果文件datawwwindex。html不存在,而文件datawwwindex。php存在,则该指令会进行内部重定向到index。php,并且nginx再次搜索位置,就好像请求是由客户端发送的一样。正如我们之前看到的,重定向的请求最终将由FastCGI服务器处理。