nginx.org的How nginx processes a request页面翻译

英文文档对应页面:How nginx processes a request

nginx如何处理请求

基于主机名的虚拟主机

nginx首先决定由哪个“server”块来处理请求。让我们以一个简单的配置开始,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” 字段,决定了请求应该路由到哪个 “server”块。如果 “Host” 字段未匹配到任何的服务器名称,或者请求头甚至不包含 “Host” 字段,nginx会将请求路由到默认的 “server”块。在上面的配置中,默认的 “server”块是第一个(这是nginx的标准默认行为)。也可以通过 “listen” 指令的 “default_server” 参数,明确设置默认服务器:

	server {
	    listen      80 default_server;
	    server_name example.net www.example.net;
	    ...
	}
<span style="font-family: SimSun; background-color: rgb(255, 255, 255);">自0.8.21版本后,就支持了 “default_server” 参数。更早的版本中,使用 “default” 参数代替。</span>
注意:

“default_server” 是 “listen port” 的属性,而不是 “server name” 的属性,这个很容易错误!

如何阻止未定义主机名的请求

如果一个没有 “Host” 字段的请求需要被禁止,可以使用下面的 “server”块配置:
	server {
	    listen      80;
	    server_name "";
	    return      444;
	}
这里,一个设置为空字符串的主机名,将匹配到没有 “Host” 字段的请求,并且返回一个特殊的非标准nginx状态码444,然后关闭连接。
自从0.8.48版本后,这是主机名的默认配置,因此,“server_name ""”,可以被省去。在更早的版本中,机器的主机名(machine's hostname),作为默认的主机名。

基于主机名和基于IP的混合方式的虚拟主机

让我们看一个稍微复杂点的配置,几个虚拟主机监听不同的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首先获取请求的IP地址和端口,同 “server”块的 “listen” 指令进行匹配。接着在已经通过IP和端口匹配到的 “server”块中,利用请求的 “Host” 字段同 “server_name” 指令进行匹配。未匹配到 “server_name”,请求将被默认server处理。例如:一个接收在192.168.1.1:80地址的www.example.com的请求,将被192.168.1.1:80的默认服务器处理(默认是第一个 “server”块,在第一节讲过),因为在这个IP&端口上,没有匹配到对应的主机名。
如上所述,“default_server” 是 “listen port” 的属性。不同的默认服务器,应该被定义在不同的 “listen port”(同一个ip&端口,只能定义一个默认服务器),例如:
	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站点配置

现在,让我们看一个典型的、简单的PHP站点,nginx如果选择一个 “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;
	    }
	}
/*
    location的匹配规则,先注意2点:
        1>先进行普通字符串的匹配,然后才进行正则的匹配。
        2>location的执行逻辑同顺序是有关系的,而非没关系。
            “普通 location ”的匹配规则是“最大前缀”,因此“普通 location ”的确与 location 编辑顺序无关;
            但是“正则 location ”的匹配规则是“顺序匹配,且只要匹配到第一个就停止后面的匹配”;
 */
1.nginx首先进行文字字符串的最大前缀搜索,忽略location的匹配顺序。在上面的配置中,仅有的location字符串前缀是 "/",它匹配任意的请求,作为一个最后的匹配方案。2.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”的请求,首先匹配到前缀是“/”的location,接着匹配到“\.(gif|jpg|png)$”的正则location,因此,它会被正则location处理。使用 “root /data/www” 指令,请求被映射到 “/data/www/logo.gif” 文件,文件发送给客户端。
  • “/index.php”的请求,首先匹配到前缀是“/”的location,接着匹配到“\.(php)$”的正则location,因此,它会被正则location处理。请求会被传递到一个监听在 “localhost: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再次匹配所有的locations,就像来自客户端的请求。同我们前面所看到的一样,这个重定向请求最终会被FastCGi服务器处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值