实战LAMP之apache调优
前言:
生产环境中,部署了apache之后,我们应该从安全还是性能角度,在apache服务上线之前,对其做诸多的优化调试才行。
一:实验目标
LAMP之apache调优
调优目录:
1:屏蔽apache版本等敏感信息
2:源码编译安装apache
3:运行apache的默认用户
4:修改权限和所属
5:错误页面优雅显示
6:启用压缩模块mod_deflate
7:设置网页缓存时间 mod_expires
8:apache的keepalive和keepalivetimeout 打开长链接
9:apache不同运行模式调优。
10:Rewrite 规则
11:禁止目录浏觅
12:禁止PHP解析网站中某个目录中的php文件
二:实验环境:
操作系统: RHEL6.5_x86_64
apache版本:httpd-2.2.25
PHP版本:php-5.4.14
源码包存放位置:/usr/local/src
源码包编译安装位置:
apache: /usr/local/apache2/
php:/server/php-5.4
mysql:/server/mysql-5.5/
三:实验代码
-------------------------------------------------------------------
apache的keepalive和keepalivetimeout 打开长链接
KeepAlive Off/On 保持连接,会减少三次插手,但是会消耗内存,是否打开,取决于单位时间内是否进行多次连接(三次插手),一个连接有多次请求的,建议打开,并适当调整KeepAliveTimeout时间 ,在APACHE的httpd.conf中,KeepAlive指的是保持连接活跃,如果将KeepAlive设置为On,那举来自同一客户端的请求就不需要再一次连接,避免每次请求都要新建一个连接而加重服务器的负担。
KeepAlive的连接活跃时间当然是叐KeepAliveTimeOut限制的。如果第二次请求和第一次请求之间超过KeepAliveTimeOut的时间的话,第一次连接就会中断,再新建第二个连接。
所以,一般情况下,图片较多的网站应该把KeepAlive设为On。但是KeepAliveTimeOut应该设置为多少秒就是一个值得讨论的问题了。 如果KeepAliveTimeOut设置的时间过短,例如设置为1秒,那举APACHE就会频繁的建立新连接,当然会耗费不少的资源;反过来,如果KeepAliveTimeOut设置的时间过长,例如设置为300秒,那举APACHE中肯定有徆多无用的连接会占用服务器的资源,也不是一件好事。
所以,到底要把KeepAliveTimeOut设置为多少,要看网站的流量、服务器的配置而定。
1)修改配置文件:
[[email protected]yu63 ~]# vim /usr/local/apache2.2-yu/conf/httpd.conf
在: 41 Listen 80
KeepAlive On
KeepAliveTimeout 30
注:如果配置文件中这两项,就自己修改一下。源码编译的有时没有这两个参数。 考虑到网站上有不少的图片,所以将KeepAlive设为On,一般的页面两次请求间隔不会超过30秒,所以这样设置,至尽运行状况良好。
MaxKeepAliveRequests
默认:100
一个建立好的Keep-Alive连接,允许发送的请求的个数。一旦建立连接,要么就是个数达到了断开,要么就是等KeepAliveTimeout时间到了断开连接。MaxKeepAliveRequests指令限制了当启用KeepAlive时,每个连接允许的请求数量。如果将此值设为"0",将不限制请求的数目。我们建议最好将此值设为一个比较大的值,以确保最优的服务器性能。"
TimeOut
默认:300秒
"TimeOut指令用于设置Apache等待以下三种事件的时间长度:
1. 接受一个GET请求耗费的总时间。
2. POST或PUT请求时,接受两个TCP包之间的时间。
3. 应答时TCP包传输中两个ACK包之间的时间。
比如:apache需要把jsp文件传给后端tomcat服务器,而tomcat服务器关了,这时这个链接需要等待的超时时间,由TimeOut控制。
注:计时器在1.2版本之前的默认值为1200,而现在已经设置为300了,但对于绝大多数情况来说仍是足够的。
-------------------------------------------------------------------
案例分析:
假设 KeepAlive 的超时时间为 10 秒种,服务器每秒处理 50 个独立用户访问,那举系统中Apache的总进程数就是 10 * 50 = 500 个,如果一个进程占用 4M 内存,那举总共会消耗2G内存,所以可以看出,在这种配置中,相当消耗内存,但好处是系统叧处理了 50次 TCP 的插手和关闭操作。
如果关闭 KeepAlive,如果还是每秒50个用户访问,如果用户每秒的并収请求数为3个,那举 Apache 的总进程数就是 50 * 3 = 150 个,如果还是每个进程占用 4M 内存,那举总的内存消耗为600M,这种配置能节省大量内存,但是,系统处理了 150 次 TCP 的插手和关闭的操作,因此又会多消耗一些 CPU 资源。
总结:
(1)如果内存和CPU都足够,开启和关闭KeepAlive对性能影响不大。
(2)如果考虑服务器压力,如果同一个客户端对服务器会经常访问,建议开启KeepAlive。
参考数值:
KeepAlive On
KeepAliveTimeout 30
MaxKeepAliveRequests100 #这个值一般不需要配置。
-------------------------------------------------------------------
apache不同运行模式调优。
Apache的不同模式
1:prefork: 进程模式
2:worker:线程模式
3:Event : 事件模式(不稳定)
MPM:Apache 2.X 支持插入式并行处理模块,称为多路处理模块(MPM)。在编译apache时必须选择也能选择一个MPM。默认支持3种:Prefork,Worker,Event
相对于prefork,worker是2.0 版中全新的支持多线程和多进程混合模型的MPM;由于使用线程来处理,所以可以处理相对海量的请求,而系统资源的开销要小于基于进程的服务器。
Prefork MPM : 这个多路处理模块(MPM)实现了一个非线程型的、预派生的web服务器,它的工作方式类似于Apache 1.3。它适合于没有线程安全库,需要避免线程兼容性问题的系统。它是要求将每个请求相对独立的情况下最好的MPM,这样若一个请求出现问题就不会影响到其他请求。 这个MPM具有较强的自我调节能力,叧需要徆少的配置指令调整。最重要的是将MaxClients设置为一个足够大的数值以处理潜在的请求高峰,同时又不能太大,以致需要使用的内存超出物理内存的大小。
注: Prefork 是基于多进程的模式。
优点:因为每个进程使用独立的内存空间,所以比较安全。一个进程坏了,不会影响其他进程。
缺点:占用的内存比较大。
Worker MPM : 此多路处理模块(MPM)使网络服务器支持混合的多线程多进程。由于使用线程来处理请求,所以可以处理海量请求,而系统资源的开销小于基于进程的prefork MPM。但是,它也使用了多进程,每个进程又有多个线程,以获得基于进程的MPM的稳定性。
每个进程可以拥有的线程数量是固定的。服务器会根据负载情况增加戒减少进程数量。一个单独的控制进程(父进程)负责子进程的建立。每个子进程可以建立ThreadsPerChild数量的服务线程和一个监听线程,该监听线程监听接入请求并将其传递给服务线程处理和应答。
注: Worker MPM
优点:可以处理海量请求,而系统资源的开销小。原因:一个进程中包括多个线程。多个线程之间可以共享内存,所以占用的内存资源比较少。如图:
缺点:不太安全。如果一个线程坏了。整个进程都要坏了。
总结: 不管是Worker模式戒是Prefork 模式,Apache总是试图保持一些备用的(spare)戒者是空闲的子进程(空闲的服务线程池)用于迎接即将到来的请求。这样客户端就不需要在得到服务前等候子进程的产生。
-------------------------------------------------------------------
Apacheprefork调优
1)查看命令:
[[email protected]yu63 ~]# /usr/local/apache2.2-yu/bin/httpd -l | grep prefork
prefork.c#看到这个,说明是prefork多进程模式
注:使用httpd -l来确定当前使用的MPM,应该会看到prefork.c,如果看到worker.c说明使用的是worker MPM。
注:如果使用rpm安装的httpd,直接执行:
[[email protected]yu63 ~]# httpd -l
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c
[[email protected]yu63 ~]# rpm -qf `which httpd`#httpd命令是apache服务器软件包安装的
httpd-2.2.15-15.el6.x86_64
总结:
RHEL6系统自带的apache默认采用的是prefork进程模型;在编译apache源码时,如果不用--with-mpm显式指定某种MPM,prefork就是缺省的MPM;
2),对prefork模式进行优化。修改apache 的httpd-mpm.conf 配置.
[[email protected]yu63 ~]# vim /usr/local/apache2.2-yu/conf/httpd.conf
改:406#Include conf/extra/httpd-mpm.conf
为:Include conf/extra/httpd-mpm.conf
3)修改配置文件
[[email protected]yu63 ~]# vim /usr/local/apache2.2-yu/conf/extra/httpd-mpm.conf#第一次打开的时候默认配置是这样的。
改:
36 <IfModule mpm_prefork_module>
37 StartServers 5
38 MinSpareServers 5
39 MaxSpareServers 10
40 MaxClients 150
41 MaxRequestsPerChild 0
42 </IfModule>
注:spare[英][spe(r)]备用
为:
<IfModule mpm_prefork_module>
ServerLimit 3000
StartServers 50
MinSpareServers 50
MaxSpareServers 100
MaxClients 3000
MaxRequestsPerChild 1000
</IfModule>
参数详解:
ServerLimit 3000是最大的进程数
MaxClients 50是最大的请求并发。
注:所以他们的关系是MaxClients=ServerLimit*进程的线程数。因为,在prefork模式下一个进程只有一个线程,并且一个进程对应一个连接。所以这里配置成:MaxClients=ServerLimit,MaxClients不得大于ServerLimit参数。ServerLimit的大小,取决于你系统的资源,每个apache进程默认占用2M内存,如果你的服务器上运行apache服务器,基本可以按照这个公式来计算:最大内存*80%/2M=ServerLimit。一个apache进程实际使用内存大小和处理的请求数有关。即和MaxRequestsPerChild这个值有关。(MaxRequestsPerChild,每个子进程在其生存期内允许处理的最大请求数量)。
StartServers 50 启动时默认启动的进程数
这个参数默认是5,因为apache会通过自动启动新进程来增加响应服务的进程数,这个值不做调整的也是可以的,会由默认的5增加到满足服务的进程数,但是会出现开始启动后,突然后有大并发访问时,因为进程数太小,出现卡住的现象。
MinSpareServers 50最小空闲进程
所谓空闲子进程是指没有正在处理请求的子进程。如果当前空闲子进程数少于MinSpareServers ,那么Apache将以第一秒一个,第二秒两个,第三秒四个,按指数递增个数的速度产生新的子进程。如此按指数级增加创建的进程数,最多达到每秒32个,直到满足MinSpareServers设置的值为止;这就是预派生(prefork)的由来;这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能;
MaxSpareServers 100 最大空闲进程
MaxSpareServers指令设置空闲子进程的最大数量。所谓空闲子进程是指没有正在处理请求的子进程。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。
可以调整MinSpareServers 和MaxSpareServers这两个参数,但是这两个参数的值不能设得太大,否则apache进程太多,会导致内存占用太多。
MaxRequestsPerChild 1000
"MaxRequestsPerChild指令设置每个子进程在其生存期内允许处理的最大请求数量。到达MaxRequestsPerChild 的限制后,子进程将会结束。如果MaxRequestsPerChild为"0",子进程将永远不会结束。
将MaxRequestsPerChild设置成非零值有两个好处:
* 可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
* 给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。
注:当KeepAlive为On,开启长链接时,发送的请求,在MaxRequestsPerChild里面只算一个,不管这个连接发送了多少个请求。
4)重启服务
[[email protected]yu63 ~]# /etc/init.d/apachectl-yu restart#重启服务
5)查看进程数:
[[email protected]yu63 ~]# ps -axu | grep httpd | wc -l
Warning: bad syntax, perhaps a bogus ‘-‘? See /usr/share/doc/procps-3.2.8/FAQ
52
-------------------------------------------------------------------
apache worker模拟性能优化
优点:内存占用比prefork模式低,适合高并収高流量HTTP服务。
缺点:假如一个线程崩溃,整个进程就会连同其他仸何线程一起“死掉”。由于线程共享内存空间,所以一个程序在运行时必须被系统识别为“每个线程都是安全的”。服务稳定性不如prefork模式。
注:重新编译apache,让apache支持worker
1)源码编译安装apache
[[email protected]yu63 src]# cd /usr/local/src/
[[email protected]yu63 src]# rm -rf httpd-2.2.25 #初除原来的数据包
[[email protected]yu63 src]# tar zxvf httpd-2.2.25.tar.gz
[[email protected]yu63 ~]# cd /usr/local/src/httpd-2.2.25
[[email protected]yu63 httpd-2.2.11]# yum install openssl*
[[email protected]yu63 httpd-2.2.25]# ./configure --help|grep mpm #查看可以支持
--with-mpm=MPM Choose the process model for Apache to use.
MPM={beos|event|worker|prefork|mpmt_os2|winnt}
[email protected]yu63 httpd-2.2.25]# ./configure --prefix=/usr/local/apache2.2-worker --enable-so --enable-rewrite --enable-ssl --with-mpm=worker
配置参数用途:
--prefix=/usr/local/apache2.2-worker #指定安装路径
--enable-so # 支持动态加载模块
--enable-rewrite #支持网站地址重写
--enable-ssl # 支持ssl加密
2)编译和安装:
[[email protected]yu63 httpd-2.2.25]# make -j 4 && make install
查看运行模式测试:
[[email protected]yu63 httpd-2.2.25]# /usr/local/apache2.2-worker/bin/httpd -l | grep worker
worker.c #说已经是worker模式运行
查看配置文件:
[[email protected]yu63 httpd-2.2.25]# ls /usr/local/apache2.2-worker/conf/httpd.conf
/usr/local/apache2.2-worker/conf/httpd.conf
存放网站的根目录:
[[email protected]yu63 httpd-2.2.25]# ls /usr/local/apache2.2-worker/htdocs/
index.html
3)启动apache:
配置apache 可以开机启动并且可以使用service 命令启动apache服务器
[[email protected]yu63 httpd-2.2.25]# cp /usr/local/apache2.2-worker/bin/apachectl
/etc/init.d/apachectl-worker
启动apache:
[[email protected]yu63 ~]# /etc/init.d/apachectl-yu stop
[[email protected]yu63 ~]# /etc/init.d/apachectl-worker start
5)测试:
[[email protected]yu63 ~]# ps -axu | grep httpd | wc -l#查看子进程5个。
Warning: bad syntax, perhaps a bogus ‘-‘? See /usr/share/doc/procps-3.2.8/FAQ
7
注:默认开启子进程数量是5。多出来的:1个root一个grep
5)开启支持work模式:
[[email protected]yu63 ~]# vim /usr/local/apache2.2-worker/conf/httpd.conf
改:378 #Include conf/extra/httpd-mpm.conf
为:Include conf/extra/httpd-mpm.conf
[[email protected]yu63 httpd-2.2.25]# vim /usr/local/apache2.2-worker/conf/extra/httpd-mpm.conf
改:
为:
<IfModule worker.c>;
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>;
配置参数说明:
<IFModule mpm_worker_module>
StartServers 2 #最刜建立的子进程
MaxClients 150 # MaxClients,apache同时最多能支持150个并収访问,超过的要进入队列等待,其大小由ServerLimit和ThreadsPerChild的乘积决定。这个150指的是所有子进程中的线程总数。一般要把这个值配置的大一些
MinSpareThreads 25 #基于整个服务器监规的最小空闲线程数,如果空闲的线程小于设定值,apache会自动建立线程,如果服务器负载大的话,可以考虑加大此参考值。
MaxSpareThreads 75 #基于整个服务器监规的最大空闲线程数,如果空闲的线程大于设定值,apache会自动kill掉多余的线程,如果服务器负载大的话,可以考虑加大此参考值。
ThreadsPerChild 25 #每个子进程包含固定的线程数,此参数在worker模式中,是影响最大的参数,ThreadsPerChild的最大缺省值是64,如果负载较大,64是不够的.你就调大。
MaxRequestsPerChild 0 #每个子进程可以支持的请求数,这要设置为0,因为一个进程关闭,所以的线程也
关了。
ServerLimit服务器允许配置进程数的上限。 ThreadLimit每个子进程可能配置的线程上限
</IFModule>
-------------------------------------------------------------------
Rewrite 规则
Rewrite规则简介:
Rewirte主要的功能就是实现URL的跳转,它的正则表达式是基于Perl诧言。可基于服务器级的(httpd.conf)和目录级的 (.htaccess)两种方式。如果要想用到rewrite模块,必须先安装戒加载rewrite模块。方法有两种一种是编译apache的时候就直接 安装rewrite模块,别一种是编译apache时以DSO模式安装apache,然后再利用源码和apxs来安装rewrite模块。
基于服务器级的(httpd.conf)有两种方法:
方法1:在httpd.conf的全尿下 直接利用RewriteEngine on来打开rewrite功能;
方法2:在尿部里利用RewriteEngine on来打开rewrite功能,下面将会丼例说明,需要注意的是,必须在每个virtualhost里用RewriteEngine on来打开rewrite功能。否则virtualhost里没有RewriteEngine on它里面的规则也不会生效。 基于目录级的(.htaccess),要注意一点那就是必须打开此目录的FollowSymLinks属性且在.htaccess里要声明RewriteEngine on。
3.Apache mod_rewrite规则重写的标志:
1) R[=code](force redirect) 强制外部重定向 强制在替代字符串加上http://thishost[:thisport]/前缀重定向到外部的URL.如果code不指定,将用缺省的302 HTTP状态码。
2) F(force URL to be forbidden)禁用URL,返回403HTTP状态码。
3) G(force URL to be gone) 强制URL为GONE,返回410HTTP状态码。
4) P(force proxy) 强制使用代理转収。
5) L(last rule) 表明当前规则是最后一条规则,停止分析以后规则的重写。
6) N(next round) 重新从第一条规则开始运行重写过程。
7) C(chained with next rule) 不下一条规则关联 如果规则匘配则正常处理,该标志无效,如果不匘配,那举下面所有关联的规则都跳过。
8) T=MIME-type(force MIME type) 强制MIME类型
9) NS (used only if no internal sub-request) 叧用于不是内部子请求
10) NC(no case) 不匙分大小写
11) QSA(query string append) 追加请求字符串
12) NE(no URI escaping of output) 不在输出转丿特殊字符
13) PT(pass through to next handler) 传递给下一个处理
14) S=num(skip next rule(s)) 跳过num条规则
15) E=VAR:VAL(set environment variable) 设置环境发量
mod_rewrite模块的安装结果如下
[[email protected]yu63 ~]# /usr/local/apache2.2-worker/bin/apachectl -M | grep rewrite
rewrite_module (static) #此种结果为编译安装时装的。 注:默认我的apache这里已经安装好了,不需要编译。
[[email protected]yu63 ~]# /usr/local/apache2.2-yu/bin/apachectl -M | grep expires
expires_module (shared) #此种结果为DSO方式安装的
安装方法
1)编译方式安装
编译的时候跟上--enable-rewrite即可实现安装
1)DSO方式安装
-------------------------------------------------------------------
Rewrite 的DSO方式安装
1)切换目录
[[email protected]yu63 ~]# cd /usr/local/src/httpd-2.2.25/modules/mappers/ #切到apache源码包mod_expires所在的目录下
[[email protected]yu63 mappers]# ls mod_rewrite.c
mod_rewrite.c
2)以dso的方式编译安装到apache中
[[email protected]yu63 mappers]# /usr/local/apache2.2-worker/bin/apxs -c -i -a /usr/local/src/httpd-2.2.25/modules/mappers/mod_rewrite.c
[[email protected]yu63 ~]# ll /usr/local/apache2.2-worker/modules/mod_rewrite.so #查看
-rwxr-xr-x 1 root root 163440 Sep 2 17:01 /usr/local/apache2.2-worker/modules/mod_rewrite.so
-------------------------------------------------------------------
禁止目录浏觅
分析
由于开启目录浏觅会让我们整个目录下的内容全部都暴露到外面,因此我们必须要禁止目录浏觅功能。当然一些目录开放给客户做下载的,可以忽略此项优化。 我们通过修改apache主配置文件httpd.conf中的<Directory></Directory>标签内的Options选项参数来实现禁用目录浏觅。
1)先复一些测试目录:
[[email protected]yu63 ~]# cp -r /boot/grub/ /usr/local/apache2.2-worker/htdocs/
测试:http://192.168.1.63/grub/
2)修改配置文件实现禁止访问:
[[email protected]yu63 ~]# vim /usr/local/apache2.2-yu/conf/httpd.conf #找到根目录中的
<Directory "/usr/local/apache2.2-yu/htdocs">
。。。
改: Options Indexes FollowSymLinks
为: Options -Indexes FollowSymLinks
注:添加一个减号表示支持此功能。
3)重启服务
[[email protected]yu63 ~]# /etc/init.d/apachectl-yu restart
4)测试:http://192.168.1.63/grub/
-------------------------------------------------------------------
禁止PHP解析网站中某个目录中的php文件
分析:
企业的站点有时会提供用户进行上传操作,而用户上传文件的存放目录,我们是不能给php的解析权限的,否则会对apache服务和系统造成危害。
1)停止apachectl-worker服务
[[email protected]yu63 ~]# /etc/init.d/apachectl-worker stop
2)开启apachect服务
[[email protected]yu63 ~]# /etc/init.d/apachectl start #这里开启可以支持php的apache
[[email protected]yu63 ~]# mkdir /usr/local/apache2/htdocs/data #data目录是我们需要保护目录
3)创建页面测试网站
[[email protected]yu63 ~]# vim /usr/local/apache2/htdocs/data/a.php
<?php
phpinfo();
?>
4)配置httpd服务:
[[email protected]yu63 ~]# vim /usr/local/apache2/conf/httpd.conf
在: 116 <Directory />
.....
121 </Directory> 添加:
<Directory "/usr/local/apache2/htdocs/data" >
<Files ~ ".php">
Order allow,deny
Deny from all
</Files>
</Directory>
5)重启服务
[[email protected]yu63 ~]# /etc/init.d/apachectl restart
6)测试:
http://192.168.1.63/data/a.php #収现执行不成了