xiwenAndlejian / my-blog

Java基础学习练习题
1 stars 0 forks source link

Nginx学习笔记(二)nginx如何处理请求 #13

Open xiwenAndlejian opened 5 years ago

xiwenAndlejian commented 5 years ago

Nginx学习笔记(二)nginx如何处理请求

Nginx官方文档

第一步:选择处理请求的服务器

服务器名称

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;
    ...
}

这里的server_name对应请求中的Host

上述配置中,三个 server 均监听80端口,但 server_name 不相同。 即在监听(接受)端口相同的情况下,nginx 仅会根据匹配请求中的 host 与 server_name 是否相同,来确定请求路由到哪个服务器中。 如果请求的 host 与任何 server_name 都不匹配,则 nginx 会将请求路由到此端口的默认服务器。(如果没有指明默认服务,则默认服务器为第一个)

设置默认服务器

使用default_server设置默认服务器


server {
    listen 80 default_server;
    server_name example.net www.example.net;
    ...
}

0.8.21版本后使用 default_server,更早版本应使用 default 注意:默认服务器是侦听端口(listen)的属性,不是服务器名称(server_name)的属性

只处理包含 host 的请求

如果想只允许请求通过 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;# 注意此处监听的ip地址
    server_name example.com www.example.com;
}

上述配置中的请求处理顺序

  1. nginx 根据请求的IP地址和端口,匹配与之相同的 listen。
  2. 从第一步匹配成功的服务器列表中,根据请求的 host 匹配与之相同的 server_name 。
  3. 如果第二步匹配失败,则使用默认服务器处理请求。

eg:192.168.1.1:80 端口上接受的请求,将由 192.168.1.1:80 端口上的默认服务器处理,即第一个服务器处理。

第二步:选择 location 块

第一步明确处理请求的服务器后,nginx 的处理请求流程如下:

  1. 搜索文字字符串给出的最具体的前缀位置,而不管列出的顺序。(这里的具体可以理解为最长/最准确)
  2. 再从配置文件中列出的顺序检查正则表达式,如果匹配成功,则使用此 location 块。
  3. 如果没有匹配的正则表达式,则使用第一步中匹配的 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,仅测试不带参数的请求行的URI部分 eg: /index.php?user=john&page=1 /index.php?page=1&user=john 即只处理?之前hostname之后的部分,此处为:/index.php

几个请求处理示例

沿用上方 php 站点的配置。

/logo.gif

  1. 请求先与/匹配
  2. 然后又与正则表达式\.(gif|jpg|png)$匹配,因此由当前匹配成功的正则表达式 location 块处理。
  3. 根据全局配置的root /data/www,将请求映射到文件/data/www/logo.gif,并将文件发送到客户端

注:expires 30d;将会为响应添加两个HTTP标头(Expires、Cache-Control)。 浏览器将使用这些标头来缓存内容,避免每次加载页面时重复请求相同的静态文件。 参数30d表示静态文件将被浏览器缓存30天。

/index.php

  1. 请求与/匹配成功
  2. 然后又与正则表达式\.(php)$匹配。因此由当前 location 块处理。
  3. 将请求转发给侦听localhost:9000的 FastCGI 服务器(大概是PHP的服务器的一种)

/about.html

  1. 请求与/匹配成功
  2. 正则匹配失败,因此由上一步匹配成功的 location 处理。
  3. 请求将根据root /data/www被映射到文件/data/www/about.html,并将文件发送给客户端。

/

  1. 请求与/匹配成功
  2. 正则匹配失败,因此由上一步匹配成功的 location 处理
  3. 请求将根据index index.html index.phproot /data/www处理
    1. 测试索引文件(index.html)是否存在,即/data/www/index.html是否存在,如果存在则将文件发送给客户端
    2. 如果第一步中的索引文件不存在,且/data/www/index.php存在,则指令执行内部重定向到/inedx.php,并且 nginx 再次匹配 location(像客户端发送的请求一样),最后重定向的请求将由 FastCGI 服务器处理。