how nginx processes a request

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服务器处理.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值