探索PHP

PHP的相关进程,随着Apache的启动而运行的;

PHP通过mod_php 5.so模块和Apache相连(具体说来是SAPI,即服务器应用程序编程接口);

php总共分为三个模块:php内核、Zend引擎、扩展层。

php内核用来处理请求、文件流和错误处理等相关操作。

Zend引擎负责将原文件转化为机器语言,然后在虚拟机上运行。

扩展层是一组函数、类库和流,php用它们进行一些特殊的处理特定的操作,例如使用Mysql扩展来连接使用MySQL数据库。

当zend执行程序的时候可能会连接若干个扩展,这时候zend将控制权转交给扩展层,等处理完特定的任务后再返还。

ZE将程序运行结果返回给PHP内核,它再将结果传送给SAPI(服务器应用程序编程接口)层,最终输出到浏览器上。

深入理解:

1 Apache启动后,php解释程序也随之启动;
2 php启动分为两个步骤:
初始化一些环境变量,这将在整个SAPI生命周期中发生作用;
     *   生成只针对当前请求的一些变量设置。
php启动第一步:
让我们先看看第一步,也是最主要的一步。要记住的是,第一步的操作在任何请求到达之前就发生了。
启动Apache后,PHP解释程序也随之启动;
PHP调用各个扩展的MINIT方法,从而使这些扩展切换到可用状态。看看php .ini文件里打开了哪些扩展
MINIT的意思是“模块初始化”。各个模块都定义了一组函数、类库等用以处理其他请求。
PHP启动第二步:
  • 当一个页面请求发生时,SAPI层将控制权交给PHP层。于是PHP设置了用于回复本次请求所需的环境变量。同时,它还建立一个变量表,用来存放执行过程中产生的变量名和值。
  • PHP调用各个模块的RINIT方法,即“请求初始化”。一个经典的例子是Session模块的RINIT,如果在php .ini中启用了Session模块,那在调用该模块的RINIT时就会初始化$_SESSION变量,并将相关内容读入;
  • RINIT方法可以看作是一个准备过程,在程序执行之间就会自动启动。
PHP关闭第一步:

如同PHP启动一样,PHP的关闭也分两步:

  • 一旦页面执行完毕(无论是执行到了文件末尾还是用exit或die函数中止),PHP就会启动清理程序。它会按顺序调用各个模块的RSHUTDOWN方法。
  • RSHUTDOWN用以清除程序运行时产生的符号表,也就是对每个变量调用unset函数。
PHP关闭第二步:

最后,所有的请求都已处理完毕,SAPI也准备关闭了,PHP开始执行第二步:

  • PHP调用每个扩展的MSHUTDOWN方法,这是各个模块最后一次释放内存的机会。
这样,整个PHP生命周期就结束了。要注意的是,只有在服务器没有请求的情况下才会执行“启动第一步”和“关闭第二步”。

关于 php 的底层工作原理,一定绕不开 webserver ,象 apache  lighttpd  nginx  iis 等。我这里就选择 apache为例吧 。以下内容将结合 apache 的源码、工作原理和扩展来逐步切入 php 的解析过程。
 Apache 运行机制剖析
浏览器(Browser) 和服务器(Web Server) 的交互过程:

1、  浏览器向服务器发出HTTP请求(Request)。

2、  服务器收到浏览器的请求数据,经过分析处理,向浏览器输出响应数据(Response)。

3、  浏览器收到服务器的响应数据,经过分析处理,将最终结果显示在浏览器中。

 下图是一份浏览器请求数据和服务器响应数据的快照:


关于浏览器和服务器数据交互过程非常简单,很容易理解。我想从事Web开发的人员都很清楚,在此不再赘述,仅供参考。
 Apache概述

Apache是目前世界上使用最为广泛的一种Web Server,它以跨平台、高效和稳定而闻名。按照去年官方统计的数据,Apache服务器的装机量占该市场60%以上的份额。尤其是在 X(Unix/Linux)平台上,Apache是最常见的选择。其它的Web Server产品,比如IIS,只能运行在Windows平台上,是基于微软.Net架构技术的不二选择。

Apache并不是没有缺点,它最为诟病的一点就是变得越来越重,被普遍认为是重量级的 WebServer。所以,近年来又涌现出了很多轻量级的替代产品,比如lighttpd,nginx等等,这些WebServer的优点是运行效率很 高,但缺点也很明显,成熟度往往要低于Apache,通常只能用于某些特定场合,。

Apache组件逻辑图
Apache是基于模块化设计的,总体上看起来代码的可读性高于PHP的代码,它的核心代码 并不多,大多数的功能都被分散到各个模块中,各个模块在系统启动的时候按需载入。你如果想要阅读Apache的源代码,建议你直接从main.c文件读 起,系统最主要的处理逻辑都包含在里面。MPM(Multi -Processing Modules,多重处理模块)是Apache的核心组件之 一,Apache通过MPM来使用操作系统的资源,对进程和线程池进行管理。Apache为了能够获得最好的运行性能,针对不同的平台 (Unix/Linux、Window)做了优化,为不同的平台提供了不同的MPM,用户可以根据实际情况进行选择,其中最常使用的MPM有 prefork和worker两种。至于您的服务器正以哪种方式运行,取决于安装Apache过程中指定的MPM编译参数,在X系统上默认的编译参数为 prefork。由于大多数的Unix都不支持真正的线程,所以采用了预派生子进程(prefork)方式,象Windows或者Solaris这些支持 线程的平台,基于多进程多线程混合的worker模式是一种不错的选择。对此感兴趣的同学可以阅读有关资料,此处不再多讲。Apache中还有一个重要的 组件就是APR(Apache portable Runtime Library),即Apache可移植运行库,它是一个对操作系统调用的抽象库,用来实现Apache内部组件对操作系统的使用,提高系统的可移植性。 Apache对于php的解析,就是通过众多Module中的php Module来完成的。

Apache的生命周期
以下是Apache的生命周期(prefork模式)示意图。

Apache的运行

Apache运行分为启动阶段和运行阶段。

启动阶段

在启动阶段,Apache主要进行配置文件解析(例如http.conf以及Include指令设定的配置文件等)、模块加载(例如mod_php.so,mod_perl.so等)和系统资源初始化(例如日志文件、共享内存段等)工作。

在这个阶段,Apache为了获得系统资源最大的使用权限,将以特权用户root(X系统)或超级管理员administrator(Windows系统)完成启动。


Apache和“php处理机”的装配过程就是在这个阶段完成的。

“php处理机”就是负责解释和执行你的php代码的系统模块。这个名字是我特意创造的,目的是为了帮助你理解本节的内容,后面的章节还会给出更专业的名称。


你单独做过php的安装配置吗?

如果你做过类似的工作,下面的内容很容易理解;如果你没有做过,可以尝试安装一下,有助于加深你的理解。不过,我的文章向来深入浅出,我会尽量把这个过程讲得更浅显一些。其实php的安装非常简单,如果你很感兴趣的话,可以到网上随便搜一篇安装指南,按步骤照做就可以了。

把php最终集成到Apache系统中,还需要对Apache进行一些必要的设置。这里,我们就以php的mod_php5 SAPI运行模式为例进行讲解,至于SAPI这个概念后面我们还会详细讲解。

假定我们安装的版本是Apache2 和 Php5,那么需要编辑Apache的主配置文件http.conf,在其中加入下面的几行内容:

Unix/Linux环境下:

LoadModule php5_module modules/mod_php5.so

AddType application/x-httpd-php .php

注:其中modules/mod_php5.so 是X系统环境下mod_php5.so文件的安装位置。

 

Windows环境下:

LoadModule php5_module d:/php/php5apache2.dll

AddType application/x-httpd-php .php

注:其中d:/php/php5apache2.dll 是在Windows环境下php5apache2.dll文件的安装位置。

这两项配置就是告诉Apache Server,以后收到的Url用户请求,凡是以php作为后缀,就需要调用php5_module模块(mod_php5.so/ php5apache2.dll)进行处理。

 

这个过程可以参考以下的示意图:



运行阶段


运行阶段概述

  在运行阶段,Apache主要工作是处理用户的服务请求。

    在这个阶段,Apache放弃特权用户级别,使用普通权限,这主要是基于安全性的考虑,防止由于代码的缺陷引起的安全漏洞。象微软的IIS就曾遭受“红色代码(Code Red)”和“尼姆达(Nimda)”等恶意代码的溢出攻击。

     运行阶段流程
    Apache将请求处理循环分为11个阶段,依次是:Post-Read-Request,URI Translation,Header Parsing,Access Control,Authentication,Authorization,MIME Type Checking,FixUp,Response,Logging,CleanUp。

 Apache Hook机制

     Apache的Hook机制是指:Apache 允许模块(包括内部模块和外部模块,例如mod_php5.so,mod_perl.so等)将自定义的函数注入到请求处理循环中。换句话说,模块可以在 Apache的任何一个处理阶段中挂接(Hook)上自己的处理函数,从而参与Apache的请求处理过程。


    mod_php5.so/ php5apache2.dll就是将所包含的自定义函数,通过Hook机制注入到Apache中,在Apache处理流程的各个阶段负责处理php请求。

 

    关于Hook机制在Windows系统开发也经常遇到,在Windows开发既有系统级的钩子,又有应用级的钩子。常见的翻译软件(例如金山词霸等等)的 屏幕取词功能,大多数是通过安装系统级钩子函数完成的,将自定义函数替换gdi32.dll中的屏幕输出的绘制函数。

 

    Apache请求处理循环详解
    Apache请求处理循环的11个阶段都做了哪些事情呢?
   

    1、Post-Read-Request阶段

    在正常请求处理流程中,这是模块可以插入钩子的第一个阶段。对于那些想很早进入处理请求的模块来说,这个阶段可以被利用。

    2、URI Translation阶段
    Apache在本阶段的主要工作:将请求的URL映射到本地文件系统。模块可以在这阶段插入钩子,执行自己的映射逻辑。mod_alias就是利用这个阶段工作的。

    3、Header Parsing阶段
    Apache在本阶段的主要工作:检查请求的头部。由于模块可以在请求处理流程的任何一个点上执行检查请求头部的任务,因此这个钩子很少被使用。mod_setenvif就是利用这个阶段工作的。

 

    4、Access Control阶段
    Apache在本阶段的主要工作:根据配置文件检查是否允许访问请求的资源。Apache的标准逻辑实现了允许和拒绝指令。mod_authz_host就是利用这个阶段工作的。

    5、Authentication阶段
     Apache在本阶段的主要工作:按照配置文件设定的策略对用户进行认证,并设定用户名区域。模块可以在这阶段插入钩子,实现一个认证方法。

 

    6、Authorization阶段
    Apache在本阶段的主要工作:根据配置文件检查是否允许认证过的用户执行请求的操作。模块可以在这阶段插入钩子,实现一个用户权限管理的方法。

    7、MIME Type Checking阶段
    Apache在本阶段的主要工作:根据请求资源的MIME类型的相关规则,判定将要使用的内容处理函数。标准模块mod_negotiation和mod_mime实现了这个钩子。

    8、FixUp阶段
    这是一个通用的阶段,允许模块在内容生成器之前,运行任何必要的处理流程。和Post_Read_Request类似,这是一个能够捕获任何信息的钩子,也是最常使用的钩子。

    9、Response阶段
    Apache在本阶段的主要工作:生成返回客户端的内容,负责给客户端发送一个恰当的回复。这个阶段是整个处理流程的核心部分。

    10、Logging阶段
    Apache在本阶段的主要工作:在回复已经发送给客户端之后记录事务。模块可能修改或者替换Apache的标准日志记录。

 

    11、CleanUp阶段
    Apache在本阶段的主要工作:清理本次请求事务处理完成之后遗留的环境,比如文件、目录的处理或者Socket的关闭等等,这是Apache一次请求处理的最后一个阶段。

Apache的性能调优

假如apache的配置

<IfModule prefork.c>
    StartServers         8
    MinSpareServers      5
    MaxSpareServers      20
    MaxClients           256
    MaxRequestsPerChild  4000
</IfModule>

在没有启用serverlLimit的情况下,使用ab测试:

ab -n 10000 -c 1000  http://192.168.1.191/test.php


如果继续保持同样的并发量继续测试(测试完后马上继续测试),由于apache的大部分子进程还没有被kill掉,创建子进程的时间就是少了,即有部分子进程已经预派生出来了。即n=20000(ab -n 20000-c 1000  http://192.168.1.191/test.php)时,时间应该不是137 *2 = 274S.


如果过一段时间在测试,即等apache kill进程,直到进程数等于MaxSpareServers (20)再测试,时间还是差不多的(137s左右)。

如果n=40000(ab -n 40000 -c 1000  http://192.168.1.191/test.php)观察服务器 apache的进程数:ps -ef | grep httpd | wc -l 。当apache的进程数到达256个后不再增加。

如果配置serverLimit

<IfModule prefork.c>

    serverLimit          1000

    StartServers         8
    MinSpareServers      5
    MaxSpareServers      20
    MaxClients           1000
    MaxRequestsPerChild  4000
</IfModule>

apache的进程就可以突破256的限制了。

调优设置:

      1)如果服务器只是的某个时段的并发量很多,设置serverLimit ,并修改MaxClients  。

      2)如果服务器持续性地高负载,可考虑同时加大MinSpareServers和MaxSpareServers

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值