nginx烂笔头——nginx如何处理一个请求

说明:“Nginx烂笔头”系列Blog是自己对Nginx官方文档的的翻译,用作阅读笔记便于日后查阅的成分居多,无关重要内容会删减,也可能会加入自己的理解。囿于个人水平,一些专业的名称翻译不会太准确,推荐查看Nginx官网原始文档。翻译内容如果有错误,欢迎指正。

本文翻译自Nginx官网How nginx processes a request网页文档。

摘要

本文主要描述了nginx是怎样处理不同配置下的请求。

基于名称的虚拟主机

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”字段来决定请求需要转发到哪里。如果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参数。

注意,默认虚拟主机是一个监听端口的属性而不是虚拟主机名称的。稍后会后更多的解释。

使用为定义的server name来阻止请求

如果想禁止没有Host字段的请求,可以用下面的配置来丢弃这个请求:

server {
    listen      80;
    server_name "";
    return      444;
}

server名称设置成空字符串就可以匹配上这些不带Host请求头字段的请求,并且返回一个nginx特别的非标准的返回码来断开这个连接。

在0.8.48以后,这个设置在server上是默认的,所以,server_name ""这个配置key忽略。在之前的版本,服务器的hostname被用作为一个默认的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首先根据listen指令和server块指令来尝试匹配请求的ip和端口。然后根据匹配上的整个server块指令的server name来测试请求头的Host字段。如果没有找到匹配的server name,请求就会被默认的server处理。例如:192.168.1.1:80端口接收到一个www.example.com的请求会被转发到192.168.1.1:80的默认server处理,因为这个端口中没有www.example.com的server_name。

前面已经说过,default_server是监听端口的属性,不同的监听端口可以配置不同的默认server。

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是怎样选择location来处理一个经典的简单PHP站点

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参数字符串。上面,仅有的location配置“/”会匹配上所有的请求,但是会被放到最后的优先级。然后,nginx会根据配置文件的顺序来查找匹配的正则表达式。如果没有正则表达式被匹配就会使用之前查找出的最长location配置。

注意,所有的location类型只会尝试匹配请求URI不包含参数的部分。因为参数的组合方式有很多种。

/index.php?user=john&page=1
/index.php?page=1&user=john

几个例子,说明nginx是如果处理请求的:

  • 一个“/logo.gif”请求首先匹配了“/”前缀的location,然后匹配上了正则表达式".(gif|jpg|png)$",所以,它会被正在表达式所在的location块指令处理。因为这个locatin没有设置root指令,使用了server中的root /data/www,就是说,这个请求会被映射到/data/www/logo.gif,然后返回这个文件给客户端。
  • “/index.php”请求,先匹配上“/”,然后是正则表达式“.(php)$”。所以,它会被发送给监听着localhost:9000端口的FastCGI服务处理。(FastCGI方面java用的比较少,详情可以查看官方文档。)
  • "/about.html"请求只会被“/”前缀匹配上,所以,它就使用这个location来处理了。
  • 处理“/”请求比较复杂。当处理这个请求时,index指令会测试在参数配置的路径root /data/www路径下是否有index文件。如果文件/data/www/index.html不存在,但是/data/www/index.php存在,nginx会做一个内部重定向到"/index.php",nginx会把它当成是从客户端发送过来的请求处理。在上面可以知道,这个请求会被FastCGI server处理。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值