一、优化目的:
公司中现有多个 apache 平台,其中网元管理系统、升级和注册授权系统、离线浏览系统和应用组所开发的系统都是运行在专用的 服务器中,他们都是以业务为主的系统,所拥有的硬件资源比较多,可以着重优化 apache 的运行速度,以适当的资源换取更高的运行速度 。
但是设备中运行的各个配置程序,他们是以性能为主的系统,所运行的环境就要相对恶劣,硬件资源限制 非常多,不能供 web 程序随意使用,他们的优化方向应该是保证运行速度的基础上尽力压低资源消耗 。
受限于此,很多外挂式加速程序都无法使用了,比如 memcache 、 eaccelerator 等,使用这些工具 的前提就是内存足够大,或者资源足够多,通常是专用的 apache 服务器上才会用到,也就是我们的第一类系统中才可以使用的,在一个嵌入系统中使用其实是得不尝失的。 下面将着重研究两种情况都使用的优化方法。
二、运行环境
无论何时, apache 所运行的硬件环境都是对性能影响最大的因素,即使不能对硬件进行升级,也最好给 apache 一个单独的主机以免受到其他应 用的干扰。但很明显,我们的配置页面程序无法满足这个要求。
各个硬件指标中,对性能影响最大的是内存,对于静态内容(图片、 javascript 文件、 css 文件等),它决定了 apache 可以缓存多少内容,它缓存的内 容越多,在硬盘上读取内容的机会就越少,而存取硬盘上的特定文件是一件很费时的操作,大内存可以极大提高静态站点的速度;对动态高负载站点来说,每个请求 保存的时间更多一些, apache 的 mpm 模块会为每个请求派生出相应的进程或线程分别处理,而进程或线程的数量与内存的消耗近似成正比,因此 增大内存对提高动态站点的负载和运行速度也极为有利
其次是硬盘的速度,静态站点尤为突出, apache 不断的在读取文件并发送给相应的请求,硬盘的读写是极其频繁的;动态站点也要不断的加载 web 程序 (php 等 ) ,一个请求甚至要读取十几个文件才能处理完 成,因此尽可能的提高硬盘速度和质量对提高 apache 的性能是有积极意义的。
最后是 cpu 和网络, cpu 影响的是 web 程序执行速度,网络影响流量大小。
影响性能的另一因素是操作系统, php 程序在类 unix 环境中的执行速度仍然比 windows 中要快,我们的系统都能满足这个要求了。
三、 apache 普通配置参数
1 、静态还是动态
使用 apache 的动态载入模块非常方便,因为在 需要时模块才会被载入。虽然有些性能开销,但同时有利于减少服务器对内存的需求。
静态载入虽然一次性载入所有需要的模块,增加内存消耗。因此我们全部采用动态载入的方法。
2 、 hhostnamelookups off
域名查找:这增加了处理每个请求的开销,首先,服务器会对 dns 系统做一个反向查询以找出客户系统的主 机名,然后又进行正向查询看获得的主机名是否真实指向客户的 ip 。大多数情况下,你可以简单的关闭这个功能,如果你经常处理服务器日志,这个工作完全可以在以后进 行。你可以通过在设置文件中加入指示 hostnamelookups off 来关闭这个功能。
3 、 options -followsymlinks
符号连接:当打开这个选项时, apache 将检查每个请求中是否包含对符号连接的引用,这将对请求中包含的每个路径调用一次 lstat() 系统调用。除非你准备使用符 号连接,否则用 options -followsymlinks 来关掉它。
4 、 sethandler server-status
服务器状态信息,默认已经关闭。该模块尽管这对测试与监控服务器很有用,但它也为服务器带来了额外 的开销,你可以通过寻找任何类似 sethandler server-status 的指示来关闭,如果可能,你可以在安装 apache 时移除这个模块。
5 、 options -indexes
关闭目录浏览
6 、 directoryindex index.php index.html
在可以更精确的时候尽可能不要使用通配符之类的灵活选项,删除不需要的选项,明确的指定设置文件列 表,最常用的放在最前。
7 、 cgi 模 块
除非你有很好的理由否则就允许 cgi 的执行,将似有的 cgi 文件放到一个特定的目录并为之设定正确的权限,这避免了 apache 对每一个请求都要判断一次要求的 是一个静态文件还是一个动态文件。
8 、写入日志
写入日志信息是一个很花费时间的工作, apache 保持日志文件的打开状态以节省打开文件的时间,如果没有必要存储日志信息,你可以关闭这个选项以节 省出更多的处理器时间,只需要在设置文件中把日志那一行注释掉就可以关掉它。
如果必须保留日志,你可以关闭 hostnamelookups 选项 ( 见上文 ) 然后把日志文件拷备到另一台机器上做进一步 分析。
9 、 allowoverride none
.htaccess 文件可以极大的扩展 apache 的设置参数,而无需每次你改变 设计都要编辑 apache 主设置文件,但对这个文件的使用也降低了服务器的性能。
如果使用这个文件, apache 必需首先在当前目录中查找是否 存在这个文件,如果存在就解析这个文件并在当前目录中应用文件中的设置。更坏的是, apache 不仅要查看当前的目录,还要查看当前目录的所有上层目录是否包括 htaccess 文件以根据所有这些文件最终 确定设置。
如果你想最优化服务器的性能,你应该禁 止使用 htaccess 文件,任何基本目录的设置都可以在主设置文件中进行,而主设置文件仅在服务器启动时解析一次。为了禁用 htaccess 文件,在任何节里加上指示 allowoverride none 。
10 、 timeout 5
timeout 设置 apache 等待一个连接读写操作的时间长度,也就是连接建立后, apache 等待客户端完成请求发送的时 间,或者是响应开始之后, apache 写出数据到客户端连接的时间长度。
无论对于哪种应用来说, 300 秒的缺省值都有些过长了,因为这就意味着,如果客户端发生了某种未知因素导致的迟滞的话,服务器的 一个连接和与之对应的所有资源都要维持 300 秒,这个对于重载的服务器来说是在是有些过长,所以,我建议将其设置得小一些,这个长度只要足够保证 各种客户端的应用能够正常传递数据即可。这里需要考虑的因素主要有各种客户端的连接状况和服务器的繁忙程度。一般来说,我建议设置为 3~5 。
11 、 keepalive on
这个选项明确 httpd 进程对每个请求的链接是否保持长链接。如果保持长链接,则从同一个客户端的连续两次请求会使用同一 个连接,而不用重复发送请求。
对于下载类的应用,因为连接时间都比较长,因此这个值设置成 on 还是 off 关系不大,从节约每一滴资源角度考 虑,可以设置为 off 。
对于网页类应用来说,如果你的静态页面上有 一些图标、图片、和 js 、 css 等 东西的话,并且如果有超过两个的资源的话,我建议是设置为 on 。
12 、 maxkeepaliverequests 100
最多保持多少个活动的长链接
13 、 keepalivetimeout 5
连接的保持时间,超过时间就回收
apache 进程在使用内存时,是“渐长”的。也就是说,直到这个进程死掉,使用内存的数量是一直增长而不会减 少的。这样的话, apache 进程使用内存的多少,就决定于你的应用程序最大使用内存量了。
keepalivetimeout 这个参数决定了,在什么都不做之前,一个 http 进程能够等待多长时间?设想一下,如 果 keepalive 设置为 on, 而 keepalivetimeout 设置为一个比较大的数字, apache 占用内存会很快的增长。这是因为,一个 apache 进程完成了一个任务(并达到了一定的内存占用,想一下“渐进”模式),并不会马上退出,而是等待一 个 keepalivetimeout 时间。假设用户的链接请求持续不断的到来,则积累起来的无用的 apache 进程就会相当多,直到 timeout ,这些进程才会被杀死。
但是, keepalive 的确对于静态的文件,比如图像文件的传送是很有效的,因此, keepalive 要设置为 on ,但是 keepalvietimeout 要设置的小 些,比如 5s
14 、 serversignature off
默认情况下,很多 apache 安装时会显示版本号及操作系统版本,甚至会显示服务器上安装的是什么样的 apache 模块。这些信息可以为黑客所 用,并且黑客还可以从中得知你所配置的服务器上的很多设置都是默认状态。
所以,请加入如下两条:
serversignature off
servertokens prod
serversignature 出现在 apache 所产生的像 404 页面、目录列表等页面的底部。 servertokens 目录被用来判断 apache 会在 server http 响应包的头部填充什么信息。如果把 servertokens 设为 prod ,那么 http 响应包头就会被设置成: server : apache
四、 MPM 模块
多处理方式 (multi-processing module/mpm) 他允许特定平台处理多个并发连接
apache 的 mpm 模块可运行在多种模式之下,其中 beos 、 mpmt_os2 分别是 beos 和 os/2 上缺省的 mpm , perchild 主要设计目的是以不同的用 户和组的身份来运行不同的子进程。这在运行多个需要 cgi 的虚拟主机时特别有用,会比 1.3 版中的 suexec 机制做得更好。 leader 和 threadpool 都是基于 worker 的变体,还处于实验性阶段,某些情况下并不会按照预期设想的那样工作,所以 apache 官方也并不推荐使用。因此, 我们主要阐述 prefork 和 worker 这两种和性能关系最大的产品级 mpm ( 有关其它的 mpm 详细说明,请参见 apache 官方文档: http://httpd.apache.org/docs-2.0/mod/) 。
1 、 prefork 的工作原理及配置
prefork 就是 unix 平台上缺省的 mpm 。它所采用的预派生子进程方式也是 apache 1.3 中采用的模式。 prefork 本身并没有使用到线程, 2.0 版使用它是为了与 1.3 版保持兼容性;另一方面, prefork 用单独的子进程来处理不同的 请求,进程之间是彼此独立的,这也使其成为最稳定的 mpm 之一。
如果是使用 debian 的 apt 安装的 apache ,使用 "apache2ctl -l" 来确定当前 使用的 mpm ,应 该会看到 prefork.c (如果看到 worker.c 说明使用的是 worker mpm ,依此类推),在 apache2.conf 中可以找到这一段配置
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
prefork 的工作原理是,控制进程在最初 建立 "StartServers" 个子进程后,为了满足 "MinSpareServers" 设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级 增加创建的进程数,最多达到每秒 32 个,直到满足 MinSpareServers 设置的值为止。这就是预派生( prefork )的由来。这种模式可以不必 在请求到来时再产生新的进程,从而减小了系统开销以增加性能。
MaxSpareServers 设置了最大的 空闲进程数,如果空闲进程数大于这个值, apache 会自动 kill 掉一些多余进程。这个值不要设得过大,但如果设的值比 MinSpareServers 小, apache 会自动把其调整为 MinSpareServers+ 1 。如 果站点负载较大,可考虑同时加大 MinSpareServers 和 MaxSpareServers 。
MaxRequestsPerChild 设 置的是每个子进程可处理的请求数。每个子进程在处理了 "MaxRequestsPerChild" 个请求后将自动销毁。 0 意味着无限,即子进程永不销毁。虽然缺省设 为 0 可以使每个子 进程处理更多的请求,但如果设成非零值也有两点重要的好处:
可防止意外的内存泄漏;
在服务器负载下降的时侯会自动减少子进 程数。
因此,可根据服务器的负载来调整这个 值。但也不能太小,不然系统不断的开启新的 apache 进程,造成资源浪费。
MaxClients 是这些指令中最为重要的 一个,设定的是 apache 可以同时处理的请求,是对 apache 性能影响最大的参数。其缺省值 150 是远远不够的,如果请求总数已达到这个值(可通过 ps -ef|grep http|wc -l 来 确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源还剩下很多而 http 访问却很慢的主要原因。系统管理员可以根据硬件配置和负载情况来动态调整这个值。虽然理论上这个值 越大,可以处理的请求就越多,但 apache 默认的限制不能大于 256 。如果把这个值设为大于 256 ,那么 apache 将无法起动。事实上, 256 对于负载稍重的站点也是不够的。在 apache 1.3 中,这是个硬限制。如果要加大这个值,必须在“ configure ”前手工修改的源代码树 下的 src/include/httpd.h 中查找 256 ,就会发现“ #define hard_server_limit 256” 这 行。把 256 改为要增大的值(如 4000 ),然后重新编译 apache 即可。在 apache 2.0 中新加入了 serverlimit 指令,使得无须重编 译 apache 就 可以加大 maxclients 。
StartServers 10
MinSpareServers 10
MaxSpareServers 15
ServerLimit 600
MaxClients 300
MaxRequestsPerChild 600
2 、 worker 的工作原理及配置
相对于 prefork , worker 是 2.0 版中全新的支持多线程和多进程混合模 型的 mpm 。由于 使用线程来处理,所以可以处理相对海量的请求,而系统资源的开销要小于基于进程的服务器。但是, worker 也使用了多进程,每个进程又生成多个线程,以获得基于进程服 务器的稳定性。这种 mpm 的工作方式将是 apache 2.0 的发展趋势。
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
worker 的工作原理是,由主控制进程生成 "startservers" 个子进程,每 个子进程中包含固定的 "threadsperchild" 线程数,各个线程独立地处理请求。同样,为了不在请求到来时再生成线程, minsparethreads 和 maxsparethreads 设置了最少 和最多的空闲线程数;而 maxclients 设置了所有子进程中的线程总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进 程。
minsparethreads 和 maxsparethreads 的最大缺省 值分别是 75 和 250 。这两个参数对 apache 的性能影响并不大,可以按照实 际情况相应调节。
threadsperchild 是 worker mpm 中与性能相关最密切的 指令。 threadsperchild 的最大缺省值是 64 ,如果负载较大, 64 也是不够的。这时要显式使用 threadlimit 指令,它的最大缺省值是 20000 。上述两个值位于源码树 server/mpm/worker/worker.c 中的以下两行:
究竟是选取 prefork 还是 worker 需要具体分析,相对而言高负载 下 perfork 拥 有更高的稳定性和运行速度,而 worker 的资源消耗更小。也已经有人在对两种工作模式作了各种测试: http://jed.dzhope.com/read.php/298.htm
实际情况看来, worker 现在还没能达到所期望的效果,性 能比 frefork 差 一些,资源消耗少一点。更可惜的是 debian 下 worker 还不能与 PHP5 完美结合,所以只能选用 perfork 了。
五、性能测试
为了获得优化有性能提高的幅度,评估优化工作的成效,需要对 apache2 服务器进行测试。
测试环境:
apache2 和 php5 服务器: debian4.0 、 apache2.2.3 、 php5.2.0-8+etch0 、 256M 内存
在另一台机器上使用 apachebench 工具模拟多个浏览器向服务器的测试页面发起 HTTP 请求,为了减少网络带宽的影响,测试页面的返回值尽可能的小,此处只有 1 byte ,并为发起测试的机器和服务器组 建了一个单独的局域网。每种并发测试 11 次,以后 10 次的结果为准,取平均值。
以下是测试的数据:其中并发数是指 apachebench 同时发起的请求个数,优化前和优化后是指平均每个请求花费的处理时间,单位毫秒
并发数 |
优化前(毫秒) |
优化后(毫秒) |
10 |
2.048 |
1.7549 |
50 |
2.1389 |
1.927 |
100 |
2.2084 |
1.9238 |
200 |
2.7689 |
2.5915 |
400 |
3.0523 |
2.797 |
由图中可以看出,优化后的效果还是很明显的,无论是在低并发还是高并发下,都有效的提高了请求的相应 时间。
需要指出的是,尽管高负载时优化后性能提高的百分比并不明显,但在并发数 400 时,测试 18 次失败 7 次,而优化后测试 14 次失败 3 次。优化不仅仅提高了服务器的性能,还提高 了负载的能力。
六、结论
优化可以有效的提高 apache2 的性能。
对于 WMS 等设备上的配置页面,第三部分的“ apache 普通配置参数”可以应用, MPM 主要是以资源换取速度的优化,可以酌情调整。
对于 EMS 、升级系统和应用系统,可以全面优化以提高性能和高负载能力。