Apache采用模块化的体系结构,它的大部分功能都被分割成相互独立的模块,这样的结构能够经过增长和删除模块就能够扩展和修改Apache提供的功能,另外一方面,对于Apache 功能的理解也变得很是容易。html
httpd源代码文件有2000个,包括180多个目录数据库
httpd2.0apache
----server :此目录是整个Apache核心功能实现,包括请求处理、协议处理等,此目录下面还包括多线程处理模块(mpm),主要是用来实现多线程并发的。windows
----modules:包括Apache全部的模块,并且一个模块占用一个目录 mod_ssl mod_proxy mod_perl浏览器
----include:Apache必需的头文件,包括一些极其重要的头文件 http_main.h http_protocol.h http_request.h 等安全
----os :操做系统平台依赖文件服务器
----srclib:Apache开发和运行须要的基础库,主要包括 apr_util apr 和 pcre网络
----support:用于辅助Apache的小工具 tools数据结构
----test:APR的测试函数多线程
Apache 的核心组件
Apache的核心组件包括 配置文件组件(http_config)、进程并发组件(MPM)、链接处理组件(http_connection)、HTTP协议处理组件(http_protocol)、HTTP请求处理组件(http_request)、HTTP核心组件(http_core)、核心模块组件(mod_core) 共七部分。七大组件直接不少都是相互调用的关系,好比MPM与HTTP_core相互调用,可是http_config
是单向调用其余几个组件,而后 main()函数调用http_config组件。除了上述说的七个核心组件还有日志处理组件、虚拟主机处理组件,以及过滤模块组件。
(1) main.c
Apache是用C语言开发的,main.c是全部程序的入口,main()函数也包括不少处理操做,包括配置文件、虚拟主机配置等,还有一个处理并发的主循环,在主循环中Apache所作的事情就是执行MPM模块,MPM将产生多个进程或多个线程来Listen 指定端口(80 443),并处理该端口上的链接和请求。具体代码以下:
[html] view plaincopy
for(;;)
{
....
if(ap_mpm_run())
break;
....
}
(2) HTTP请求处理组件
子请求:在并发量比较高的网站,对一个特定的请求,为了加快处理速度,会从当前请求中派生出多个子请求,由这些子请求去并发地处理,(好比:mod_autoindex 模块进行索引的时候会针对目录中的每个文件产生一个子请求);当子请求处理完毕后再返回到父请求中。
重定向请求:apache处理请求时,当前的请求可能会被重定向(访问一个网页会先跳转到登陆页面),重定向时当前定向会产生新的请求,由新请求继续处理。
4. Apache运行流程
(1) Apache启动过程
apache的启动包括两个阶段,高权限启动阶段和低权限运行阶段,一般称之为两阶段启动方式。
apache中的绝大部份内存都是基于内存池分配的,在apache启动时必须首先初始化内存池资源;而后apache会读取和解析apache的配置文件(httpd.conf) ;在启动的最后阶段,apache将经过调用ap_mpm_run函数并将控制权交给MPM,只有当MPM执行失败或结束后才把控制权交还给主程序,并且MPM在处理HTTP链接时用的权限是普通用户的权限,这样会避免黑客攻击apache会获取root权限。
MPM有两种并发方式:prefork worker,其中 prefork是以进程为基本单位,每个请求可能会产生多个进程,这样若是在window系统中,一个进程占的资源比较大,这样apache负载的并发就比较小;因此在Linux系统中是prefork模式,在window系统中通常采用 worker模式。
(2) Apache 连接处理
在收到client端的HTTP请求并创建socket链接后,apache就获取了client对应的IP,经过这个IP能够肯定该IP地址对应的虚拟主机族(?),让回更新相关的虚拟主机的相关信息。
一旦client与Apache创建链接,请求数据将被读取出来,而后HTTP_PROTOCOL 模块将开始对该报文进行解析,请求的解析包括:
HTTP请求头: GET index.html HTTP/1.1
HTTP请求域: Accept:*/*
HTTP请求体:对一些特殊的请求,好比POST 会在报文中保存数据
读取的请求信息会保存在数据结构 request_rec 中。
(3) 请求处理
对于HTTP报文,Apache调用ap_process_request 函数对请求进行实质处理,Apache中请求处理包括三个阶段:请求解析阶段、安全处理阶段、请求准备阶段,而每个阶段也能够细分多个子阶段
请求解析阶段:
a) URL字符转义
一般状况下,浏览器会自动转换请求地址栏中一些特殊字符,好比空格(%20),而对服务器而言,它就要将%xx 格式的字符串从新还原成原来的字符串
b) 优化 URL :有时URL中包括一下多余的/ http://www.baidu.com/...// 这样把多余的/ 给删除,把相对路径的 ../ ./ 都换成绝对路径
c) URL名称转换:若是在apache上面有alias,若是URL是一个别名就把它转换为真实的域名 URL
d) URL重定向:若是apache里面有配置文件 rewrite 设置,则把请求的URL进行重定向到新的 URL
安全处理:
就是前面说的 AAA认证,不过这里是具体实现(挂钩对应的模块进行访问控制、身份认证、用户受权)
请求准备阶段:
a) type_checker:apache在处理客户请求的资源前,先要肯定用户请求资源的类型(html txt gif ),而后再进行内容生成
b) fixups:补丁修复,apache开发须要近现代其余优化操做能够在这里实现
(4) 内容生成
请求处理最重要的内容就是响应内容生成,对于静态的HTML文件直接读取文件返回给客户端就能够了;对对一些脚本CGI、js还有一下动态数据库文件,须要apache调用对应的处理器生成客户请求的内容;生成内容会进入过滤器进行内容过滤(本身设置过滤的内容和规则),经过最后一个过滤器(网络过滤器后),把内容发送到网络,最后传输到客户端,并在浏览器中显示。
Apache 层次结构
Apache 能够分为5层,分别是 操做系统平台功能层,可移植运行库层(操做系统适配层),Apache核心功能层,Apache可选功能层和Apache第三方功能库
(1) 操做系统平台功能层:
Apache实质上仍是运行在操做系统上面的应用程序,所以必须使用操做系统自己提供的底层功能,好比进程和线程、进程和线程的通讯,网络套接字通讯和文件操做等
同事Apache也是跨平台(能够在不一样的操做系统上运行)
(2) 可移植运行库(APR)
APR(Apache portable runtime) 是操做系统的适配层,经过APR也实现了Apache的跨平台。由于不一样的操做系统提供的底层API不一样,也就是实现同一个操做所用的函数方法不一样,这时在Apache和操做系统中间设计一个APR,这样APR根据不一样的操做系统分别实现一个相同的功能,这样apache能够调用APR的提供的一个API接口。
这样,若是Apache要建立一个进程,这时会调用 APR中的 apr_proc_create()函数,此时APR会自动识别操做系统的类型根据不一样的类型调用操做系统经过的API,如是Unix系列则会调用unix中的fork()方法实现建立进程;若是是windows系统,则调用createProcess()建立进程。
因此,Apache在处理与操做系统有关的事物时,不用考虑是基于哪个操做系统,直接用APR的统一API接口就可,具体的由APR来实现跨操做系统。
实际上任何应用程序均可以借助APR进行跨平台。
(3) 核心功能层
a) 核心功能层主要实现Apache的基本功能和核心功能,包括读取和响应HTTP请求,处理HTTP协议;核心功能层包括核心程序和核心模块
核心程序主要是实现Apache的基本功能:
启动和终止apache
处理配置文件(config.c)
接受和处理HTTP链接
读取HTTP请求并对该请求进行处理
处理HTTP协议
核心功能层另外一个是 核心模块,apache的大部分模块是可选择的,能够有也能够没有,可是有两个模块是必须的,即:mod_core和 mod_so
mod_core:负责处理配置文件中的大部分配置指令,并根据这些指令运行apache
mod_so:负责在须要的时候动态加载其他模块,缺乏了该模块其余模块没法加载
多进程并发处理模块MPM(这里理解一个client请求成功并创建一个TCP链接,则这是一个进程),MPM虽然hi能够选择的,可是如今apache必需要用到多进程并发,因此这个模块也是必须的模块
b) Apache 最基本的核心功能由apache 核心完成,除此以外,核心没法提供的功能则所有由模块提供。为了容许这些模块能完成控制apache的处理,apache核心程序提供了对应的API;这些API是指每一个模块中包含的一系列的函数(核心程序处理HTTP请求的时候用来将信息传递给模块),以及一些列apr的函数。
(4) 可选功能层
Apache有不少模块,包括mod_ssl mod_proxy mod_perl ;apache的文件都是C语言开发的,若是有perl脚本写的模块,必须把mod_perl 模块加载,不然不能运行
(5) 第三方支持库
apahe的一些模块会使用到第三方的开发库,好比 mod_ssl 使用了 openssl;mod_perl 使用了perl 开发库,这些库并不属于apache,是第三方库。