0)前言
近期打算从头复习下PHP/编程相关的基础知识,发现对一些模块都还只是一知半解,有些甚至连一知都达不到。故此决定写些文章记录心得、整理笔记加强记忆,也希望能帮助到新手。
1)介绍
在开始整理流程前先简单介绍几个后面可能会用到的知识点,这里只是简单的概要一下,想深入了解的可以看自行搜索相应的文章,了解的同学可直接跳过。
cgi
CGI是一种协议,专门用来和WEB服务器打交道的,是为了保证传递过来的数据是标准格式的。WEB服务器收到用户请求就会把请求提交给CGI程序,CGI程序根据请求提交的参数作相应处理,然后输出标准的HTML语句返回给WEB服务器,再返回给客户端,这就是普通CGI的工作原理。
通俗的来讲CGI就像是一根管子,浏览器/HTML页面的请求需要遵守这根管子的协议才能通过管子和WEB服务器中的执行程序连通,它把浏览器/HTML页面请求传递给服务器的执行程序,再把服务器执行程序的结果再返还给浏览器/HTML页面。
fast-cgi
FAST-CGI是一种协议,统管CGI程序的运行。因为CGI每次接收WEB请求都会启动退出过程,当大并发量时资源开销大容易歇菜,所以就产生了FAST-CGI,FAST-CGI是早早就启动好了的,运行着等待请求,接到请求执行结束后不会退出,继续等待下个请求。
php-cgi:
PHP-CGI是PHP提供给WEB服务器的CGI协议接口程序,每当接收到WEB服务器请求都会创建一个PHP-CGI进程进行处理,处理结束后销毁。如果更新了PHP配置,那么就需要重启PHP-CGI才能生效。
php-fpm:
PHP-FPM是PHP提供给WEB服务器的FAST-CGI协议接口程序,它不会像PHP-CGI处理请求一样要不断的创建销毁进程,而是可以一个进程重复利用处理多个请求,每处理完一个请求就开始等待处理下一个请求。支持平滑过渡配置更改。PHP-FPM算是PHP-CGI的管理器,一些比较旧的版本运行时查看进程时还是能看到PHP-FPM和PHP-CGI同时出现的,后来PHP-FPM被整合到内核后查看进程只会显示PHP-FPM。
2)过程
首先通过浏览器,输入域名发起请求,浏览器将判断输入的是IP/端口还是域名,如果是域名浏览器会通过DNS服务器去获取域名对应的IP/端口;
浏览器通过IP/端口向对应的服务器发起(HTTP协议)请求,WEB请求默认是80端口,由于Web服务器监听80端口,所以由WEB服务器(Apache,Nginx等)进行接收处理响应;
到这步讲两种常见的模式:
1.Nginx+PHP-FPM
这种方式,Nginx会根据配置文件中的server部分进行处理。根据下面代码配置中的location配置的规则来判断该请求的URI的类型(例如index.html,index.php,test.jpg等),如果是静态资源(例如test.jpg等)则直接将资源返回。这里假设是PHP文件,PHP文件则需要经过对应的解释器PHP-FPM/PHP-CGI(这种已经不常用了后续只提PHP-FPM)进行处理。但Nginx不能直接和PHP-FPM通信,所以会交给FAST-CGI模块处理。FAST-CGI根据下面代码配置中的fastcgi_pass127.0.0.1:9000(以具体配置为准),找到PHP-FPM,Nginx 会将所有的 PHP 请求翻译成 FASTCGI请求之后再发送到这个地址。
server {
listen 80;
server_name demo.code.com;
root "/WWW/code";
location / {
index index.html index.htm index.php;
#autoindex on;
if (!-e $request_filename) {
rewrite ^(.*)$ /admin.php?s=/$1 last;
break;
}
}
location ~ \.php(.*)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi_params;
}
}
这里简单说一些PHP-FPM的Master和Worker进程,PHP-FPM有Master进程和Worker进程如下所示,Master进程只有一个,用于监听端口及分配Worker进程处理任务,而Worker进程则有多个,每个进程都嵌入了PHP解释器,是PHP代码真正执行的地方,具体的数量可以配置死,也可以配置根据请求量自适应。
-bash-4.1$ ps -ef | grep fpm
root 1297 1 0 Apr22 ? 00:07:25 php-fpm: master process (/usr/local/php7/etc/php-fpm.conf)
apache 1642 1297 0 Apr22 ? 00:01:22 php-fpm: pool www
apache 2929 1297 0 Jul21 ? 00:00:00 php-fpm: pool www
apache 2941 1297 0 Jul24 ? 00:00:00 php-fpm: pool www
apache 3509 1297 0 Jul18 ? 00:00:00 php-fpm: pool www
apache 5724 1297 0 Jul16 ? 00:00:00 php-fpm: pool www
apache 5732 1297 0 May27 ? 00:00:00 php-fpm: pool www
apache 5794 1297 0 Jun11 ? 00:00:00 php-fpm: pool www
apache 6093 1297 0 May27 ? 00:00:00 php-fpm: pool www
apache 6902 1297 0 Jun13 ? 00:00:00 php-fpm: pool www
apache 7107 1297 0 12:33 ? 00:00:00 php-fpm: pool www
apache 7785 1297 0 May24 ? 00:00:06 php-fpm: pool www
apache 7859 1297 0 Jul18 ? 00:00:00 php-fpm: pool www
apache 8101 8083 0 13:58 pts/3 00:00:00 grep fpm
回到过程中,PHP-FPM的Master进程监听到Nginx请求,Master进程会分配一个处于空闲状态的Worker进程,Worker进程解析/执行请求,并将执行结束结果返回给Nginx,Nginx再将结果原路返回。
2.Apache+mod_php5
这种方式,Apache将PHP作为自己的一个子模块来运行,当请求的文件是PHP文件时,Apache就调用mod_php5来解析PHP代码
文章主要侧重讲请求到WEB服务器直至PHP中的应用调用过程,中间细致的过程肯定不止这么多,例如请求到服务器经历的网络七层协议等等,感兴趣的人可以去查下相关的资料。首次发文有什么不对的地方欢迎评论区指出,多多探讨。