码农日记

薄洪涛的个人博客

php程序是如何被解析的?

我们每天都在写php代码,然后往服务器上一丢,你就发现php文件就运行了,嘿,是不是很神奇,但是有没有想过,php是如何被解释执行的呢?要知道apache,nginx都是不能解析.php文件的;所以想和大家探讨下原理;

首先,安装过lnmp的同学都知道,在安装nginx部署站点的时候,nginx总会带着以下代码

location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
        include fastcgi_params;
    }

估计菜鸟也能看出来,这句话的意思就是,如果我nginx遇到了.php文件,我就不处理,我就交给php的解释器去处理,所以这就引出了fast-cgi这个东西,你看代码中配置了吧

CGI

再说fast-cgi之前,需要先说cgi,其实cgi就是一个协议,就是语言(php)和服务器(nginx)之间的一个桥梁,就是说,只要nginx处理不了的.php我都通过cgi交给php处理,php处理后把结果给nginx,然后nginx返回给浏览器;

但是cgi有个弊端,就是每次请求都会创建一个cgi进程,然后php解释器会加载php.ini,初始化环境,处理.php,然后请求结束后杀死这个cgi进程,这样效率就极低,所以产生了fast-cgi

Fast-CGI

fast-cgi其实就是cgi的改进,就是常驻进程,每次请求不杀死进程也不创建进程,这样性能上就高了很多(这里需要批评下很多文章博客人云亦云,fastcgi是协议协议协议!!!)

下面图片可以点击放大

百度百科:

image.png

wiki:

image.png

wiki大致意思,说fast-cgi是一个通用网关的变体,改善cgi的性能问题(高负载下频繁的进程创建销毁),重用了资源,提升了服务器和cgi下程序关联的效率

php-FPM

是一个实现了fast-cgi协议的程序,并且可以实现进程管理 , 每个子进程都会嵌入php的解释器,去解释php代码,一般会有两种进程master和worker,master进程只有一个,负责监听端口,接收来自nginx的请求(一直监听9000端口),work进程则一般有多个,每个进程内部都嵌入一个php解释器,负责解释php代码;看下图

[root@web ~]# ps -ef|grep php-fpm
www       2009 13180  0 Aug06 ?        00:00:10 php-fpm: pool www //子进程,负责解释php
www       2010 13180  0 Aug06 ?        00:00:10 php-fpm: pool www
root      4110  4079  0 12:52 pts/0    00:00:00 grep --color=auto php-fpm
root     13180     1  0 Jul25 ?        00:00:24 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)   //主进程,负责管理子进程,监听9000端口
www      28694 13180  0 Aug02 ?        00:00:22 php-fpm: pool www

说到这里应该明白了,cgi和fast-cgi是协议和语言无关,php-fpm是实现了fast-cgi的程序,并且监听9000端口

当浏览器请求时,nginx通过location指令(这里有人说是nginx的fast-cgi模块),将所有以php为后缀的文件都交给 127.0.0.1:9000 来处理,也就是php-fpm 的master进程 ,master进程选择并连接到一个子进程去处理php文件,然后返回给nginx,nginx返回给浏览器;这样才算完成了一次请求,注意,这里的子进程数量是由woker_process配置的,一般是auto;

这样我们就把浏览器-nginx-php的流程缕了一遍



发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

Powered By Z-BlogPHP 1.7.3

版权所有 | 转载请标明出处