一次请求的过程

我们每天都打开网页,让我们来看看,一次典型的网页请求的整个过程:

1, 用户端:

1.1 用户打开一个浏览器,在地址栏输入一个http/https url(这里不涉及ftp,stmp等协议),点回车;

1.2 读取本地hosts文件, 查找url对应的ip服务器地址;

1.3 如果找不到,则从dns中查找,先从本机获取,如linux下

cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.1.1

这个看起来像localhost的地址究竟是什么意思?

因为 ubuntu下有一个本地的dns服务叫做dnsmasq,它是由NetworkManager控制的

ps -ef | grep dnsmasq

nobody    2111  1165  0 11月09 ?      00:00:08 /usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/var/run/NetworkManager/dnsmasq.pid --listen-address=127.0.1.1 --cache-size=0 --conf-file=/dev/null --proxy-dnssec --enable-dbus=org.freedesktop.NetworkManager.dnsmasq --conf-dir=/etc/NetworkManager/dnsmasq.d
c80k2    29357 28457  0 22:23 pts/54   00:00:00 grep --color=auto dnsmasq

你就可以看到它监听的本地地址,--listen-address=127.0.1.1 (ubuntu12.04及之前的版本 是 127.0.0.1), 这个地址是一个本地回环地址

而你真实的dns服务器地址,是被这个服务管理维护着的

local process -> local dnsmasq -> router -> ISP dns

dns域名解析过程一般分为递归查询recursive query和迭代查询iterative query,获取到所输url的根域名和服务器ip;

1.4 将请求指向到该服务器ip,通过负载均衡,指向到某台特定的服务器;

2 服务器上的过程

2.1 服务器上的web server,如nginx, Apache等,通过读取它的配置,如 /etc/nginx/sites-available/default 或者 apache的httpd.conf配置,这里以nginx为例

#loaclhost 
server {
        listen 80;
        server_name  localhost;
        root  /opt/wwwroot/;
        index  index.html index.htm index.php;

        location @rewrite {
            rewrite ^/(.*)$ /index.php?_url=/$1;
        }

        location / {
            allow all;
        }

        location ~ ^(.+\.php)(.*)$ {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index   index.php;
            fastcgi_split_path_info         ^(.+\.php)(.*)$;
            fastcgi_param       PATH_INFO                $fastcgi_path_info;
            fastcgi_param       PATH_TRANSLATED        $DOCUMENT_ROOT$fastcgi_path_info;
            fastcgi_param       SCRIPT_FILENAME  $DOCUMENT_ROOT/$fastcgi_script_name;
            include             fastcgi_params;
        }
}

我们一行一行来看看

server {   ->表示这是一个server,可对外提供服务
        listen 80; //该server监控的服务器端口,这里默认是80
        server_name  localhost; //server_name,就是url解析之后的根地址
        root  /opt/wwwroot/; //指向到的根目录
        index  index.html index.htm index.php; //指向到根目录下的任意文件

        location @rewrite { //重写:
            rewrite ^/(.*)$ /index.php?_url=/$1;
        }

        location / { //对url进行匹配
            allow all;
        }

        location ~ ^(.+\.php)(.*)$ {
            fastcgi_pass 127.0.0.1:9000; //后面的address为后端的fastcgi  server的地址
            fastcgi_index   index.php; // fastcgi默认的主页资源
            fastcgi_split_path_info         ^(.+\.php)(.*)$;  //这里通过新版的nginx的fastcgi_split_path_info将请求的url后半部分进行split操作
            fastcgi_param       PATH_INFO                $fastcgi_path_info; //参见以下示例
            fastcgi_param       PATH_TRANSLATED        $DOCUMENT_ROOT$fastcgi_path_info;
            fastcgi_param       SCRIPT_FILENAME  $DOCUMENT_ROOT/$fastcgi_script_name;
            include             fastcgi_params;
        }
}

示例:

请求的网址是/abc/index.php/def

DOCUMENT_ROOT的值是项目的根目录

PATH_INFO的值是/abc
SCRIPT_FILENAME的值是$doucment_root/abc/index.php
SCRIPT_NAME /abc/index.php

具体的location匹配信息可参见: https://segmentfault.com/a/1190000002797606

2.2  web服务器将请求通过master-worker的方式,抛给对应的进程管理器,比如cgi,php-fpm,如下:

nginx进程

ps -aux | grep nginx
root      1646  0.0  0.0 123396   236 ?        Ss   11月30   0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data  1649  0.0  0.0 123788   684 ?        S    11月30   0:13 nginx: worker process
www-data  1651  0.0  0.0 123788   604 ?        S    11月30   0:18 nginx: worker process
www-data  1652  0.0  0.0 123788  1236 ?        S    11月30   0:05 nginx: worker process
www-data  1653  0.0  0.0 123788  1040 ?        S    11月30   0:19 nginx: worker process
root     11563  0.0  0.0   4512     0 pts/0    Ss   11月30   0:00 /bin/sh -c service nginx start && service php7.0-fpm start && /bin/bash /bin/bash
root     11649  0.0  0.0 125120    32 ?        Ss   11月30   0:00 nginx: master process /usr/sbin/nginx
www-data 11650  0.0  0.0 125444    88 ?        S    11月30   0:02 nginx: worker process
www-data 11651  0.0  0.0 125444     0 ?        S    11月30   0:21 nginx: worker process
www-data 11652  0.0  0.0 125444     8 ?        S    11月30   0:18 nginx: worker process
www-data 11653  0.0  0.0 125444     0 ?        S    11月30   0:21 nginx: worker process

php进程

ps -aux | grep php
root      1338  0.0  0.1 399000  9268 ?        Ss   11月30   0:13 php-fpm: master process (/etc/php/5.6/fpm/php-fpm.conf)
www-data  1771  0.0  0.2 403764 23084 ?        S    11月30   0:00 php-fpm: pool www
www-data  1773  0.0  0.1 405616 15748 ?        S    11月30   0:00 php-fpm: pool www
c80k2     7137  0.0  0.0   9776  1644 ?        S    11月30   0:18 /opt/phpstorm/bin/fsnotifier64
root     11563  0.0  0.0   4512     0 pts/0    Ss   11月30   0:00 /bin/sh -c service nginx start && service php7.0-fpm start && /bin/bash /bin/bash
root     11791  0.0  0.0 366700    96 ?        Ss   11月30   0:10 php-fpm: master process (/etc/php/7.1/fpm/php-fpm.conf)
www-data 11792  0.0  0.0 374524  1584 ?        S    11月30   0:03 php-fpm: pool www
www-data 11793  0.0  0.0 374504  1880 ?        S    11月30   0:02 php-fpm: pool www

然后通过http/tcp-ip协议,nginx和php直接按照标准进行连接,如三次握手四次挥手(ACK?),滑动窗口控制数据传输,标准输入,输出等。同时,nginx里面的proxy_connect_timeout, proxy_read_timeout, proxy_send_out等参数控制连接的时长,返回相应的http状态码

2.3 php收到请求后,根据不同的进程管理器的方式,决定如何解析php文件,最后执行php代码

2.4 将数据返回给前端,进行页面渲染。

猜你喜欢

转载自my.oschina.net/u/3412738/blog/2967117