编程技术分享平台

网站首页 > 技术教程 正文

你真的懂Nginx吗之《Nginx是如何处理用户请求》

xnh888 2024-09-28 03:07:22 技术教程 202 ℃ 0 评论

问题概述:

一般情况下,一个部署了Nginx的服务器中的Nginx配置中,会配置多个Server块,且Server块都会监听在80端口;如配置如下

http {
    # 定义日志格式
    log_format combined_with_upstream '$remote_addr -$remote_user [$time_local] '
                                        '"$request"$status $body_bytes_sent '
                                        '"$http_referer" "$http_user_agent" '
                                        '$host$upstream_addr $upstream_status';

    # 第一个Server块,server_name为a.com
    server {
        listen 80;
        server_name a.com;
        access_log /var/log/nginx/a.com-access.log combined_with_upstream;

        location / {
            proxy_pass http://upstream_a;
            proxy_set_header Host $host;
        }
    }

    # 第二个Server块,server_name为b.com
    server {
        listen 80;
        server_name b.com;
        access_log /var/log/nginx/b.com-access.log combined_with_upstream;

        location / {
            proxy_pass http://upstream_b;
            proxy_set_header Host $host;
        }
    }

    # 第三个Server块,server_name为c.com
    server {
        listen 80;
        server_name c.com;
        access_log /var/log/nginx/c.com-access.log combined_with_upstream;

        location / {
            proxy_pass http://upstream_c;
            proxy_set_header Host $host;
        }
    }
}

那么这么多Server块,Nginx到底如何处理的,经常会让人感到疑惑

问题1:Nginx是如何根据用户的请求匹配Server块

用户请求到Nginx匹配到Server块的实践结果,回答如下:

第一步:浏览器解析用户输入URL(http://c.com),并向DNS服务器发送请求,获取URL对应的IP地址

第二步:浏览器向IP地址对应的Nginx服务器发送HTTP请求

第三步:Nginx读取请求头中的Host值(c.com)

第四步:Nginx根据Host按照配置依次查找Server块中的server_name,找到server_name为c.com的server块,

第五步:Nginx根据请求的URL和配置文件中的location指令,匹配到一个合适的处理模块

第六步:处理模块输出内容给用户

问题2:如果用户输入的域名,在DNS服务器获取对应的IP对应的Nginx服务器上面没有找到server_name为用户输入域名的server块,Nginx会用那个server块呢?

根据实践结果如下:

比如用户输入d.com;而这个d.com也是到上面的一台服务器;那么Nginx会采用第一个Server块,也就是说会给用户响应a.com的内容

问题3:如果用户输入的域名,在DNS服务器获取对应的IP对应的Nginx服务器上面没有找到server_name为用户输入域名的server块,但有一个server块配置成为默认default_server服务;Nginx会用那个server块呢?

配置如下

http {
    # 定义日志格式
    log_format combined_with_upstream '$remote_addr -$remote_user [$time_local] '
                                        '"$request"$status $body_bytes_sent '
                                        '"$http_referer" "$http_user_agent" '
                                        '$host$upstream_addr $upstream_status';

    # 第一个Server块,server_name为a.com
    server {
        listen 80;
        server_name a.com;
        access_log /var/log/nginx/a.com-access.log combined_with_upstream;

        location / {
            proxy_pass http://upstream_a;
            proxy_set_header Host $host;
        }
    }

    # 第二个Server块,server_name为b.com,设置为默认服务器
    server {
        listen 80 default_server;
        server_name b.com;
        access_log /var/log/nginx/b.com-access.log combined_with_upstream;

        location / {
            proxy_pass http://upstream_b;
            proxy_set_header Host $host;
        }
    }

    # 第三个Server块,server_name为c.com
    server {
        listen 80;
        server_name c.com;
        access_log /var/log/nginx/c.com-access.log combined_with_upstream;

        location / {
            proxy_pass http://upstream_c;
            proxy_set_header Host $host;
        }
    }
}

根据实践结果如下:

比如用户输入d.com;而这个d.com也是到上面的一台服务器;那么Nginx会采用默认default_server服务,也就是说会给用户响应b.com的内容

总结

  • nginx会先读取用户的请求头中的host值
  • 然后会按配置server中的先后顺序依次查找匹配server_name
  • 如果没有找到匹配的,则会找是否有配置了default_server(默认服务)
  • 如果仍然没有,则取第一个server块

[微笑]现在你是不是清晰多了,欢迎评论区留言

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表