您的位置:首页 > 运维架构 > Nginx

how nginx processes a request

2015-11-04 20:07 295 查看

nginx如何处理请求

如何处理不确定的服务器名的请求

混合名称和IP的虚拟服务器

一个简单的PHP站点配置

基于名字的虚拟服务器

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标准的默认行为. 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;
}


服务器名称是一个空字符串, 将匹配没有”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
块的
server_name
指令检测请求的”Host”头属性. 如果没有找到匹配的服务器名称, 那么这个请求将被默认的服务器处理. 举个例子, 一个在 192.168.1.1:80 接收到的 www.example.com 请求将被 192.168.1.1:80 端口的默认服务器处理, 即第一个服务器, 因为没有 www.example.com 定义在这个端口.

正如之前讲过的, 一个默认的服务器是一个监听端口的属性, 不同的默认服务器会定义在不同的端口上.

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怎么选择一个定位去处理请求

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


现在让我们看看, 在上面的配置中, nginx将如何处理请求:

“/logo.gif” 请求首先被前缀location “/” 匹配, 然后被正则表达式 “\.( gif | jpg | png )$” 匹配, 因此这个请求将被后者处理. 因为使用 “root /data/www” 指令, 请求将映射到文件 /data/www/logo.gif , 然后此文件被发送到客户端.

“/index.php” 请求首先被前缀location “/” 匹配, 然后被正则表达式 “.( php )$” 匹配, 因此这个请求被后者处理, 被转发到监听localhost:9000的FastCGI服务器.

“/about.html” 请求只被前缀location “/” 匹配, 因此这个请求被这个location处理. 因为使用 “root /data/www” 指令, 请求将映射到文件 /data/www/about.html.

处理 “/” 请求更复杂.
index
指令检测索引文件的存在, 根据配置好的参数和 “root /data/www” 指令. 如果文件 /data/www/index.html 不存在, 以及文件 /data/www/index.php 存在, 那么指令将做一个内容重定向到 “/index.php”, nginx重新搜索location, 好像客户端重新发了一个请求过来. 正如我们之前看到的, 这个重定向的请求将被FastCGI服务器处理.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: