服务器我爱编程

Apache运行机制

2017-11-22  本文已影响456人  伊Summer

1.Apache概述

  Apache是目前世界上使用最为广泛的一种Web Server,它以跨平台、高效和稳定而闻名。
  Apache并不是没有缺点,它最为诟病的一点就是变得越来越重,越来越复杂,被普遍认为是重量级的 WebServer。而且Apache的server为process-based server ,也就是基于多进程的HTTP服务器,它需要对每个用户请求创建一个子进程进行响应,这样的缺点是,如果并发的请求非常多(在大型门户网站很常见),就会需要非常多的进程,从而占用极多的cpu资源和内存。因此对于并发处理不是Apache的强项。
  使用另一种webServer,叫做asynchronous servers 异步服务器,比如lighttpd,nginx等等,这些WebServer的优点是运行效率很 高,但缺点也很明显,成熟度往往要低于Apache。

2.Apache组件逻辑图

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

Apache组件逻辑图

3.Apache的生命周期图

Apache的生命周期(prefork模式)示意图

4. Apache的三种工作模式

  Apache服务的三种工作模式:preforkworkerevent

prefork的工作原理及配置

工作原理:

  一个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并作出应答。Apache总是试图保持一些备用的 (spare)或是空闲的子进程用于迎接即将到来的请求。这样客户端就无需在得到服务前等候子进程的产生。在Unix系统中,父进程通常以root身份运行以便邦定80端口,而 Apache产生的子进程通常以一个低特权的用户运行。User和Group指令用于配置子进程的低特权用户。运行子进程的用户必须要对他所服务的内容有读取的权限,但是对服务内容之外的其他资源必须拥有尽可能少的权限。
  这样可以减少频繁创建和销毁进程的开销,每个子进程只有一个线程,在一个时间点内,只能处理一个请求。这是一个成熟稳定,可以兼容新老模块,也不需要担心线程安全问题,但是一个进程相对占用资源,消耗大量内存,不擅长处理高并发的场景。


prefork的工作原理图

配置说明:

如何配置在Apache的配置文件httpd.conf的配置方式:

<IfModule mpm_prefork_module>
    StartServers             5
    MinSpareServers          5
    MaxSpareServers          10
    MaxRequestWorkers        250
    MaxConnectionsPerChild   1000
</IfModule>

worker的工作原理及配置

工作原理:

和prefork模式相比,worker使用了多进程和多线程的混合模式,worker模式也同样会先预派生一些子进程,然后每个子进程创建一些线程,同时包括一个监听线程,每个请求过来会被分配到一个线程来服务。线程比起进程会更轻量,因为线程是通过共享父进程的内存空间,因此,内存的占用会减少一些,在高并发的场景下会比prefork有更多可用的线程,表现会更优秀一些;另外,如果一个线程出现了问题也会导致同一进程下的线程出现问题,如果是多个线程出现问题,也只是影响Apache的一部分,而不是全部。由于用到多进程多线程,需要考虑到线程的安全了,在使用keep-alive长连接的时候,某个线程会一直被占用,即使中间没有请求,需要等待到超时才会被释放(该问题在prefork模式下也存在)。


worker的工作原理图

配置说明:

配置在Apache的配置文件httpd.conf的配置方式:

<IfModule mpm_worker_module>
    StartServers             3
    ServerLimit              16
    MinSpareThreads          75
    MaxSpareThreads          250
    ThreadsPerChild          25
    MaxRequestWorkers        400
    MaxConnectionsPerChild   1000
</IfModule>

这里建议设置为非零,注意原因:
1)能够防止(偶然的)内存泄漏无限进行,从而耗尽内存。
2)给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量(重生的机会)。

Worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild 值决定的,应该大于等于MaxRequestWorkers。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。默认最大的子进程总数是16,加大时 也需要显式声明ServerLimit(最大值是20000)。需要注意的是,如果显式声明了ServerLimit,那么它乘以 ThreadsPerChild的值必须大于等于MaxRequestWorkers,而且MaxRequestWorkers必须是ThreadsPerChild的整数倍,否则 Apache将会自动调节到一个相应值。

event的工作原理及配置

工作原理:

这是Apache最新的工作模式,它和worker模式很像,不同的是在于它解决了keep-alive长连接的时候占用线程资源被浪费的问题,在event工作模式中,会有一些专门的线程用来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务器的线程,执行完毕后,又允许它释放。这增强了在高并发场景下的请求处理。


event的工作原理图

配置说明:

配置在Apache的配置文件httpd.conf的配置方式:

<IfModule mpm_event_module>
    StartServers             3
    ServerLimit              16
    MinSpareThreads          75
    MaxSpareThreads          250
    ThreadsPerChild          25
    MaxRequestWorkers        400
    MaxConnectionsPerChild   1000
</IfModule>

5.Apache的运行

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

5.1 启动阶段

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

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

Apache中的“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启动简图

注:在unix/linux下, so后缀文件是一个DSO文件,DSO与windows系统下的dll是等价概念,都是把一堆函数封装在一个二进制文件中。调用它们的进程把它们装入内存后,会将其映射到自己的地址空间。
DSO全称为Dynamic Shared Object,即动态共享对象。DLL全称为Dynamic Link Library动态链接库
Apache 服务器的体系结构的最大特点,就是高度模块化。如果你为了追求处理效率,可以把这些dso模块在apache编译的时候静态链入,这样会提高Apache 5%左右的处理性能。

5.2运行阶段

运行阶段概述

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

运行阶段流程

Apache将请求处理循环分为以下11个阶段:

Apache请求处理的11个阶段图

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

上一篇下一篇

猜你喜欢

热点阅读