概述
PHP在业界被调侃,是世界上最好的语言,PHP确实是Web开发里的利器,具体点说,就是一个用C语言实现包含大量组件模块的软件框架。是一个强大的UI框架。
PHP动态语言执行过程:拿到一段代码后,经过词法解析、语法解析等阶段后,源程序会被翻译成一个个指令(opcodes),然后ZEND虚拟机顺次执行这些指令完成操作。PHP本身是用C实现的,因此最终调用的也是C的函数,实际上,我们可以把PHP看做一个C开发的软件。
分层体系
复杂的结构需要分层,TCP/IP协议因为分层得到了很好的应用,不熟悉的同学可以去我的计算机网络专栏的文章里看一看,PHP也是主要分为四层,分层处理,提高处理效率和职能。
PHP从下倒上是一个4层体系:
1、Zend引擎:Zend整体用纯C实现,是PHP的内核部分,他将PHP代码翻译(词法、语法解析等一系列编译过程)为可执行opcode的处理并实现相应的处理方法、实现了基本的数据结构(如:hash_table、OO)、内存分配机制及管理、提供了相应的api方法供外部调用,是一切的核心,所有的外围功能均围绕Zend实现。
2、Extensions:围绕着Zend引擎,extensions通过组件式的方式提供各种基础服务,我们常见的各种内置函数(array系列)、标准库等都是通过extension来实现CGI即通用网关接口,用户也可以根据需要实现自己的extension的典型应用)。
博主梦话:印象里在win上开发的时候,有个ext文件夹,里面装载着各种类库,就是Extensions层存放扩展文件的路径。
3、Sapi: Sapi全称 Server Application Programming Interface ,也就是服务端应用编程接口,Sapi通过一系列钩子函数,使得PHP可以和外围交互数据,这是PHP非常优雅和成功的设计,通过sapi成功的将PHP本身和上层应用解耦隔离,PHP可以不再考虑如何针对不同应用进行兼容,而应用本身也可以针对自己的特点实现不同的处理方式。
4、上层应用:这就是我们平时编写的PHP程序,通过不同的spai方式得到各种各样的应用模式,如何通过webserver实现web应用、在命令行下已脚本方式运行等等。
Sapi
Sapi通过一系列的接口,使得外部应用可以和PHP交换数据并可以根据不同应用特点实现特定的处理方法,我们常见一些sapi有:
var_dump(php_sapi_name()); # 输出当前php运行模式
1、CGI/FastCGI
下文有详细解释。
2、APACHE2HANDLER
PHP作为Apache模块,Apache服务器在系统启动后,预先生成多个进程副本驻留在内存中,一旦有请求出 现,就立即使用这些空余的子进程进行处理,这样就不存在生成子进程造成的延迟了。这些服务器副本在处理完一次HTTP请求之后并不立即退出,而是停留在计 算机中等待下次请求。对于客户浏览器的请求反应更快,性能较高。
3、apache模块的DLL
该运行模式是我们以前在windows环境下使用apache服务器经常使用的,而在模块化(DLL)中,PHP是与Web服务器一起启动并运行的。
博主梦话:印象里在win上开发的时候,有个ext文件夹,里面装载着各种类库,就是.dll结尾的文件。
4、Cli
在最开始设计PHP这门语言时是为了执行脚本,所以win上和Linux中都有 Cli模式,Cli模式会强制使用一些配置参数,强制关闭缓冲区的数据,执行也非常高效,常用的参数:
-a 交互式运行PHPCLI程序
-c 告诉PHP,从那个路径寻找php.ini
-l 检查php文件的语法,不执行
-m 查看编译的模块
Cli模式的生命周期
模块初始化阶段
->请求初始化阶段
->脚本执行阶段
->请求关闭阶段
->模块关闭阶段
。
后来Swoole
中为了追求性能,在启动服务的时候使用常驻内存的方式预先加载在内存里,在脚本中千万不要写配置文件中,因为在Cli模式下第一次的执行没有被释放,第二次的又来执行,会造成服务内存问题。
CGI/FastCGI
之前互联网上的Web服务都属于html,静态资源分布,随着互联网的发展,后来出现了像asp、jsp、php这种动态语言,动态语言的特点是需要Web服务器的解析Cgi就是Web服务器和动态语言通信的网关。
CGI即通用网关接口(Common Gateway Interface),它是动态语言的产物,是负责Web服务与PHP通信的接口,CGI方式在遇到连接请求(用户 请求)先要创建cgi的子进程,激活一个CGI进程,然后处理请求,处理完后结束这个子进程。这就是 fork-and-execute 模式。所以用cgi 方式的服务器有多少连接请求就会有多少cgi子进程,子进程反复加载是cgi性能低下的主要原因。
在这个基础上产生了FastCGI,FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去fork一 次。PHP使用PHP-FPM(FastCGI Process Manager),全称PHP FastCGI进程管理器进行管理。
FPM的三种模式运行模式
重点要介绍的是FPM的三种模式运行模式:内存优先(ondemand)、静态池(static)、服务优先(dynamic)。
ondemand
php-fpm启动的时候不会启动worker进程,按需启动worker,有链接进来后,才会启动。
listen = 127.0.0.1:9001
pm = ondemand
pm.process_idle_timeout = 60
pm.max_children = 10
连接到来时(只有链接,不没有数据也会创建,telnet也会创建),创建新worker进程,worker进程数的创建收max_children设置限制,也受限于全局的process.max设置(三种模式都受限此,下文中有全局配置项讲解),如果空闲时间超过了process_idle_timeout的设置就会销毁worker进程。
优点:按流量需求创建,不浪费系统资源。
缺点:因为php-fpm是短连接的,如果每次请求都先建立连接,大流量场景下会使得master进程变得繁忙,浪费cpu,不适合大流量模式,不推荐使用此模式。
dynamic
会初始化创建一部分worker,在运行过程中,动态调整worker数量,最大worker数再pm.max_children
和process.max
之间。
pm.max_children < worker进程数量 < process.max
pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 6
当空闲进程数小于min_spare_servers时,创建新的子进程,总子进程数小于等于pm.max_children
,小于等于process.max
,当空闲进程数大于max_spare_servers
,会杀死启动时间最长的子进程,如果子进程(idle状态)数大于max_children
,会打印warning日志,结束处理。
process小于 max_children ,计算一个num,启动num个worker。
优点:动态扩容,不浪费系统资源。
缺点:所有worker都在工作,新的请求到来需要等待创建worker进程,最长等待1s(内部存在一个1s的定时器,去查看,创建进程),频繁启停进程消耗cpu,请求数稳定,不需要频繁销毁
static
启动固定大小数量的worker,也有1s的定时器,用于统计进程的一些状态信息,例如空闲worker个数,活动worker个数
#需要主意的是,必须配置这个参数,而且只有这个参数有效
pm.max_children = 10
NGINX与php-fpm的通信
我理解的php-fpm是PHP对FastCGi封装的模块,是PHP对CGI网关通信的优化和扩展,Web服务器都在php-fpm实现。配置文件里的listen。listen负责监听ip和端口,查看php-fpm的配置文件,查看监听端口,默认是9000,然后配置你的Nginx。
ps aux | grep php
listen = 127.0.0.1:9000
Nginx Server里配置:
server {
listen 80;
server_name www.baidu.com;
root /home/work/www/baidu/;
index index.php;
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
}
location ~ / {
rewrite ^(.*)$ /index.php$1 break;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param ENVIROMENT 0;
include fastcgi_params;
}
}
网友评论