实战apache调优下
实战apache调优下
1 Apache运行模式-prefork-worker运行模式介绍
2 prefork运行模式详解
3 worker运行模式详解
4 rewrite-禁止网站下某个目录执行PHP文件-Apache调优总结
5 禁止浏览目录和php文件被解析-使用CDN做网站加速
1 apache运行模式-prefork-worker运行模式介绍
1.1 Apache不同运行模式调优
Web服务器Apache目前一共有三种稳定的MPM(Multi-Processing Module,多进程处理模块)模式。如:Prefork(进程模式)、worker(线程模式)、Event (事件模式,2.2版本的时候属于测试版本,2.4版本后开始生产的版)。
2 prefork运行模式详解
1、Prefork MPM : Prefork MPM实现了一个非线程的、预派生的web服务器。它在Apache启动之初,就先预派生一些子进程,然后等待连接;可以减少频繁创建和销毁进程的开销,每个子进程只有一个线程,在一个时间点内,只能处理一个请求。这是一个成熟稳定,可以兼容新老模块,也不需要担心线程安全问题,但是一个进程相对占用资源,消耗大量内存,不擅长处理高并发的场景。
最重要的是将MaxClients设置为一个足够大的数值以处理潜在的请求高峰,同时又不能太大,以致需要使用的内存超出物理内存的大小。所以现在已经不常用这个模式了。 而且apache2.4版本以后,默认使用的是worker模式。
注: Prefork 是基于多进程的模式。
优点:因为每个进程使用独立的内存空间,所以比较安全。一个进程坏了,不会影响其他进程。
缺点:占用的内存比较大。
运行原理图如下:
2、Worker MPM : 和prefork模式相比,worker使用了多进程和多线程的混合模式,worker模式也同样会先预派生一些子进程,然后每个子进程创建一些线程,同时包括一个监听线程,每个请求过来会被分配到一个线程来服务。线程比起进程会更轻量,因为线程是通过共享父进程的内存空间,因此,内存的占用会减少一些,在高并发的场景下会比prefork有更多可用的线程,表现会更优秀一些;另外,如果一个线程出现了问题也会导致同一进程下的线程出现问题,如果是多个线程出现问题,也只是影响Apache的一部分,而不是全部。由于用到多进程多线程,需要考虑到线程的安全了,在使用keep-alive长连接的时候,某个线程会一直被占用,即使中间没有请求,需要等待到超时才会被释放(该问题在prefork模式下也存在)。
运行原理图如下:
注: Worker MPM优点:可以处理海量请求,而系统资源的开销小。原因:一个进程中包括多个线程。多个线程之间可以共享内存,所以占用的内存资源比较少。
缺点:不太安全。如果一个线程坏了。 整个进程都要坏了。另外存在keep-alive长连接占用资源时间过长。
如何避免进程中某个线程坏了? 一个进程中所有线程完成一定数量的请求后,自动关闭,再重打开。就可以避免内存溢出等问题。 就像一个电脑开机时间长了,会卡,需要重启一下。
总结: 不管是Worker模式或是Prefork 模式,Apache总是试图保持一些备用的(spare)或者是空闲的子进程(空闲的服务线程池)用于迎接即将到来的请求。这样客户端就不需要在得到服务前等候子进程的产生。这就是预先派生进程或线程。
3、Event MPM:event模式是在2.4版本中才可以稳定运行。这是Apache最新的工作模式,它和worker模式很像,不同的是在于它解决了keep-alive长连接的时候占用线程资源被浪费的问题,在event工作模式中,会有一些专门的线程用来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务器的线程,执行完毕后,又允许它释放。这增强了在高并发场景下的请求处理。
当某个连接没有请求时,会主动关闭连接,在work模式下,必须等keep-alive超时,才可以释放。
总结:在configure配置编译参数的时候,可以使用 --with-mpm=prefork|worker|event 来指定编译为那一种MPM。也可以编译为三种都支持:--enable-mpms-shared=all,这样在编译的时候会在modules目录下自动编译出三个MPM文件的so,然后通过修改httpd.conf配置文件更改MPM
1.2 查看Apache运行模式
先查看Apache的运行模式有两种方法。
方法1:
[root@localhost ~]# /usr/local/apache2.4/bin/httpd -l
Compiled in modules:
core.c
mod_so.c
http_core.c
worker.c
#使用httpd -l来确定当前使用的MPM,看到worker.c说明使用的是worker MPM。咱们这里默认使用的是 worker模式。prefork模式已经被淘汰了,所以我们主要讲一下worker和event两个模式。
方法2:
[root@localhost ~]# /usr/local/apache2.4/bin/httpd -V #也可以查看apache运行模式
Server version: XWS/8.1.2 (Unix)
Server built: Oct 9 2018 21:01:51
Server's Module Magic Number: 20120211:68
Server loaded: APR 1.4.8, APR-UTIL 1.5.2
Compiled using: APR 1.4.8, APR-UTIL 1.5.2
Architecture: 64-bit
Server MPM: worker
扩展:查看使用rpm安装的httpd默认使用的运行模式
[root@localhost ~]# yum install httpd -y
[root@localhost ~]# httpd -V
Server version: Apache/2.4.6 (CentOS)
Server built: Jun 27 2018 13:48:59
Server's Module Magic Number: 20120211:24
Server loaded: APR 1.4.8, APR-UTIL 1.5.2
Compiled using: APR 1.4.8, APR-UTIL 1.5.2
Architecture: 64-bit
Server MPM: prefork #可以看到rpm安装的还是旧的prefork模式的。
2 实战-对prefork模式性能优化
2.1 了解prefork模式性能优化相关参数
导入httpd-mpm.conf配置文件到apache主文件中:
[root@localhost ~]# vim /usr/local/apache2.4-xuegod/conf/httpd.conf
改:485 #Include conf/extra/httpd-mpm.conf
为:485 Include conf/extra/httpd-mpm.conf
[root@localhost apache2.4# vim /usr/local/apache2.4/conf/extra/httpd-mpm.conf #查看主要参数。
1、prefork模式常用配置参数
#这是prefork模式的配置参数,虽然配置文件中有参数,但是不启作用,因为我们是以worker模式在运行apache,以下参数说明。
28 <IfModule mpm_prefork_module>
29 StartServers 5 # 启动apache时创建的服务进程数量
30 MinSpareServers 5 # 最小空闲进程数, Spare :[speə(r)] 备用
31 MaxSpareServers 10 # 最大空闲进程数
32 MaxRequestWorkers 250 # 最大并发进程数。
33 MaxConnectionsPerChild 0 # 最大连接数限制。如果设置为0,表示没有限制。 </IfModule>
2、MinSpareServers指令设置空闲子进程的最小数量。
MinSpareServers指令设置空闲子进程的最小数量。所谓空闲子进程是指没有正在处理请求的子进程。如果当前空闲子进程数少于MinSpareServers ,那么Apache将以第一秒一个,第二秒两个,第三秒四个,按指数递增个数的速度产生新的子进程。如此按指数级增加创建的进程数,最多达到每秒32个,直到满足 MinSpareServers设置的值为止;这就是预派生(prefork)的由来;这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能;如下图:
3、MaxSpareServers 10 最大空闲进程
MaxSpareServers指令设置空闲子进程的最大数量。所谓空闲子进程是指没有正在处理请求的子进程。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。如下图:
可以调整MinSpareServers 和MaxSpareServers这两个参数,但是这两个参数的值不能设得太大,否则apache进程太多,会导致内存占用太多。
注:在一台压力大(并发访问2000)的服务器上,MaxSpareServers这个值设置的是200。保留最大并发数的10分之一。设置了这个值的好处是不会有太多的空闲的进程在消耗资源,关闭空闲apache进程的同时,会释放内存,进而减少系统资源消耗。
4、MaxRequestWorkers 250 最大并发进程数。
MaxRequestWorkers : 最大同时处理请求的进程数量,也是最大的同时连接数,表示了apache的最大请求并发能力,超过该数目后的请求,将排队。
5、MaxRequestsPerChild 0 最大连接数限制
MaxConnectionsPerChild : 进程生命周期内,处理的最大请求数目。达到该数目后,进程将死掉。如果设置为0,表示没有限制。该参数的意义在于,避免了可能存在的内存泄露带来的系统问题。
将MaxRequestsPerChild设置成非零值有两个好处:
* 可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
* 给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。
如:MaxConnectionsPerChild 25000。当进程处理了25000个请求后,apache管理进程会去终止此进程继续处理新的请求,当此进程处理完所有的已建立的请求后,管理进程会杀掉此进程,重新生成一个新的进程
注:当KeepAlive 为On, 开启长链接时,发送的请求,在MaxRequestsPerChild里面只算一个,不管这个连接发送了多少个请求。
3 实战:对worker、event模式性能优化
3.1 实战:对worker模式性能优化
Apache2.0以后的版本在性能方面改进最明显的变化就在于使用worker模式。
优点:内存占用比prefork模式低,适合高并发高流量HTTP服务。
缺点:假如一个线程崩溃,整个进程就会连同其他任何线程一起“死掉”。由于线程共享内存空间,所以一个程序在运行时必须被系统识别为“每个线程都是安全的”。服务稳定性不如prefork模式。后期根据每个进程处理的请求数,重启worker进程,
[root@localhost apache2.4]# vim /usr/local/apache2.4/conf/extra/httpd-mpm.conf #查看主要参数
1、worker模式常用配置参数
#这是worker模式的配置参数
44 <IfModule mpm_worker_module>
45 StartServers 3 #启动时进程数。
46 MinSpareThreads 75 #最小空闲线程数。 # thread[英][θred] 线程
47 MaxSpareThreads 250 #最大空闲线程数。
48 ThreadsPerChild 25 #每个进程可以启动的线程数量。
49 MaxRequestWorkers 400 #所有线程数量的最大值,通常表示了一个web服务可以同时处理的请求数。
50 MaxConnectionsPerChild 0 #最大连接数限制。
51 </IfModule>
配置参数详细说明:
<IFModule mpm_worker_module>
StartServers 3 #最初建立的子进程
MinSpareThreads 75 #基于整个服务器监视的最小空闲线程数,如果空闲的线程小于设定值,apache会自动建立线程,如果服务器负载大的话,可以考虑加大此参考值。
MaxSpareThreads 250 #基于整个服务器监视的最大空闲线程数,如果空闲的线程大于设定值,apache会自动kill掉多余的线程,如果服务器负载大的话,可以考虑加大此参考值。
ThreadsPerChild 25 #表示每个进程包含的线程数,如果是并发量比较大,可以考虑加大这个值。此参数在worker模式中,是影响最大的参数。
MaxRequestWorkers 400 #所有线程数量的最大值,通常表示了一个web服务的最大并发值。MaxRequestWorkers必须是ThreadsPerChild的整数倍,否则Apache会提示调整到一个相近的值。MaxRequestWorkers=StartServers* ThreadsPerChild
MaxConnectionsPerChild 0 #每个子进程可以处理的最大请求数。达到该数目后,进程将死掉。如果设置为0,表示没有限制。
如:MaxConnectionsPerChild 25000。当进程处理了25000个请求后,apache管理进程会去终止此进程继续处理新的请求,当此进程处理完所有的已建立的请求后,管理进程会杀掉此进程,重新生成一个新的进程。配置如下:
<IfModule mpm_worker_module>
StartServers 8 #启动时进程数。
MinSpareThreads 75 #最小空闲线程数。 # thread[英][θred] 线程
MaxSpareThreads 250 #最大空闲线程数。
ThreadsPerChild 25 #每个进程可以启动的线程数量。
MaxRequestWorkers 400 #所有线程数量的最大值 。
MaxConnectionsPerChild 2500 #最大连接数限制。
</IfModule>
上述参数配置思路:一个进程中有250个线程。 一个进程处理25000个请求。 平均一个线程处理25000/250=100个请求。这样配置还是合理的。
3.2 实战:Apache基于worker模式的生产环境配置实例
1、查看每个进程使用的内存大小
连接数理论上是越大越好,但是得根据硬件,服务器的CPU,内存,带宽等因素,来配置当前的Apache连接数。
[root@localhost ~]# ps -aux | grep httpd | wc -l
[root@localhost ~]# ps -aux | grep httpd #查看默认连接数是3,第一个以root身份运行的httpd进程,是apache的父进程,它不会处理用户请求,是用来管理httpd进程的。所以一共是3个进程。
查看httpd 占用内存的平均数: 使用ps查看RSS列,每个进程占用的内容。
[root@localhost ~]# ps -axu | grep http | awk '{print $6}'
2964
4360
4360
4360
980
注:默认单位是K,可以看到三个进程每个使用的是4360K内存,一共使用了4360*3=13.08M内存,这是初始的内存大小。
后期随着apache进程处理的web请的增加,每个进程使用的内存数量还会增加的。 因为每个人的网站和业务不一样。所以每个Apache进程使用的内存大小也不一样。但是大家可以在自己的服务器上线1天后,使用此命令查看一下,每个进程使用的内存大小,这样可以准确算出每个进程使用的内存数量。
查看进程使用的内存的总大小:
[root@localhost ~]# ps aux | grep http |awk '{sum += $6;n++};END{print sum}'
查看每个进程使用内存的平均:
[root@localhost ~]# ps aux | grep http |awk '{sum += $6;n++};END{print sum/n}'
注:这样就可以根据每个进程使用内存的大小,来算一下我们最多可以给多少内存。
2、扩展:在选择服务器时,如何确认cpu和内存搭配?
通用型服务器选择标准:cpu核心和内存大小,一般比例为1:4 ,如8核cpu,32G内存;16核心CPU,64G内存。
计算型服务器选择标准:cpu核心和内存大小,一般比例为1:2 ,如8核cpu,16G内存;16核心CPU,32G内存。
内存型服务器选择标准:cpu核心和内存大小,一般比例为1:8 ,如8核cpu,64G内存;16核心CPU,128G内存。
3、实战场景:一台服务器,16核心CPU,64G内存。 apache最大可以设置多少个work进程。
思路:先减去服务器系统本身所需要的资源,剩下的才能给apache使用。具体分配内存场景,可以参考以下案例。
例1:当一台服务器是8G内存时,2G留给系统使用,6G留给apache使用。
例2:当一台服务器是16G内存时,4G留给系统使用,12G留给apache使用。
例3:当一台服务器是32G内存时,8G留给系统使用,24G留给apache使用。
例4:当一台服务器是64G内存时,8G留给系统使用,56G留给apache使用。
总结:系统最多使用8G内存,就足够了稳定运行了。
那么对于64G内存的服务器,apache可以使用56G内存,假如每个work进程稳定运行时,平均使用56M内存。最大work进程数为:56*1024/56=1024个。
根据上述情况,修改后的http-mpm.conf的worker的配置后为:
[root@localhost ~]# vim /usr/local/apache2.4/conf/extra/httpd-mpm.conf
44 <IfModule mpm_worker_module>
45 StartServers 1024
46 MinSpareThreads 750
47 MaxSpareThreads 2500
48 ThreadsPerChild 250
49 MaxRequestWorkers 25000
50 MaxConnectionsPerChild 25000
51 </IfModule>
重启Apache,再打开网站看看是否还会有慢的问题了。
[root@localhost ~]# /etc/init.d/apachectl restart
测试:
动态观察apache的最大连接数:
[root@localhost ~]# watch -n 1 "pgrep httpd|wc -l"
3.3 生产环境配置实例
实战环境:一台服务器cpu是8核心,物理是内存32G ,想达到2000并发的apache,worker模式的配置参数如下:
<IfModule mpm_worker_module>
StartServers 16
MinSpareThreads 75
MaxSpareThreads 1250
ThreadsPerChild 125
MaxRequestWorkers 2000
MaxConnectionsPerChild 12500
</IfModule>
详解每个参数的配置合理性如下:
<IfModule mpm_worker_module>
StartServers 16 #启动时进程数。一般设同cpu核心数一样或是cpu核心数的2倍。我调成16和cpu核心一样。
MinSpareThreads 75 #最小空闲线程数。假设一个网站每天正常被用户使用的时间为早上7:00到晚上2:00。那么MinSpareThreads应该配置为,这一时间段,最小并发访问量的3倍。比如7:00最少并发为25,那就配置成75。
MaxSpareThreads 1250 #最大空闲线程数。一般配置为1天中最大并发量的1半。如这台服务器能处理的最大并量为2500。那么此值应该为1250。因为内存闲着也是闲着,可以按linux下尽可能使用内存的原则,配置成1250.这样在突然到来更多访问量时,响应会更及时。
ThreadsPerChild 125 #每个进程可以启动的线程数量。生成环境中,在带宽和硬盘性能充足的情况下,希望这个这台可以完成2000左右的并发。那么此值应该为:2000/ StartServers的值(我这里是16)=125 。但是一个进程不可能包括无数的线程,包括太多,会导致进程不稳定,容易崩溃。所以我们认为一个进程最多包括125线程,就很好了。所以如果还想处理更多的请求,可以把StartServers的值增加,而不是增大ThreadsPerChild的值。 因为ThreadsPerChild值过大,会导致apache运行不稳定。系统调优,稳定是一切的前提。
MaxRequestWorkers 2000 #所有线程数量的最大值,通常表示了一个web服务的最大并发值。MaxRequestWorkers必须是ThreadsPerChild的整数倍,否则apache会提示调整到一个相近的值。MaxRequestWorkers=StartServers* ThreadsPerChild。 我们这里是:16*125=2000
MaxConnectionsPerChild 12500 # 最大连接数限制。每个子进程可以处理的最大请求数。如果设置为0,表示没有限制。 我们设置为MaxConnectionsPerChild 12500。当进程处理了12500个请求后,apache管理进程会去终止此进程继续处理新的请求,当此进程处理完所有的已建立的请求后,管理进程会杀掉此进程,重新生成一个新的进程。结合当前的配置,我们得出结论:apache一个进程中有125个线程。 apache一个进程处理12500个请求。 平均一个线程处理12500/125=100个请求。这样配置还是合理的。一个线程处理太多的请求,也会出现内存溢出,导致进程崩溃。
3.3 event模式调优
[root@localhost apache2.4]# vim conf/extra/httpd-mpm.conf #配置如下
61 <IfModule mpm_event_module>
62 StartServers 3
63 MinSpareThreads 75
64 MaxSpareThreads 250
65 ThreadsPerChild 25
66 MaxRequestWorkers 400
67 MaxConnectionsPerChild 0
68 </IfModule>
event模式调优和worker模式一样的,不同的是在于它解决了keep-alive长连接的时候占用线程资源被浪费的问题。所以理伦上event模式比worker模式好。
总结:生产环境下对于要求更高伸缩性的站点可以选择使用worker 或 event模式; 需要可靠性或者与旧软件兼容的站点可以使用 prefork模式。现在网站使用worker模式比较多。worker也比较成熟。event模式从Apache2.4版本才开始有。
4 Apache的Rewrite规则使用技巧
4.1 Rewrite规则简介
1、Rewirte主要的功能就是实现URL的跳转,它的正则表达式是基于Perl语言。可基于服务器级的(httpd.conf)和目录级的 (.htaccess)两种方式。如果要想用到rewrite模块,必须先安装或加载rewrite模块。
安装Rewirte模块两种方式:
方法一:是编译apache的时候就直接 安装rewrite模块。
方法二:编译Apache时以DSO模式安装Apache,然后再利用源码和apxs来安装rewrite模块。
2、基于服务器级的(httpd.conf)有两种方法:
方法1:在httpd.conf的全局下 直接利用RewriteEngine on来打开rewrite功能;
方法2:在局部里利用RewriteEngine on来打开rewrite功能,下面将会举例说明,需要注意的是,必须在每个virtualhost里用RewriteEngine on来打开rewrite功能。否则virtualhost里没有RewriteEngine on它里面的规则也不会生效。
4.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) 不在输出转义特殊字符。
例如:RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] 将能正确的将/foo/zoo转换成/bar?arg=P1=zed
13) PT(pass through to next handler) 传递给下一个处理。
14) S=num(skip next rule(s)) 跳过num条规则。
15) E=VAR:VAL(set environment variable) 设置环境变量。
4.4 mod_rewrite模块检查及安装
检查mod_expires模块是否安装的方法如下:
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl -M | grep rewrite
rewrite_module (static) #此种结果为编译安装时装的。 注:默认我的Apache这里已经安装好了,不需要编译。
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl -M | grep expires
expires_module (shared) #此种结果为DSO方式安装的。
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl -M | grep rewrite # 没有查看到rewrite模块。
互动:我们在之前编译时已经加了--enable-rewrite选项,为什么此没有找到rewrite模块?
[root@localhost ~]# ls /usr/local/apache2.4/modules/mod_rewrite.so
/usr/local/apache2.4/modules/mod_rewrite.so #可以看到系统中有这个模块的
解决:这是因为我们还没有启用rewrite模块。
[root@localhost ~]# vim /usr/local/apache2.4/conf/httpd.conf
改:156 #LoadModule rewrite_module modules/mod_rewrite.so #删除前面的#号,启用rewrite模块。
为:156 LoadModule rewrite_module modules/mod_rewrite.so
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl -M | grep rewrite
rewrite_module (shared) #已经可以查看到rewrite模块了。
扩展:如果之前安装apache时,没有添加--enable-rewrite选项,那需要使用下面的方法手动编译出来这个模块。 具体如下:
a)编译方式安装
编译的时候跟上--enable-rewrite即可实现安装。
b)DSO方式安装
[root@localhost ~]# cd /usr/local/src/httpd-2.4.28/modules/mappers/
#切到apache源码包mod_expires所在的目录下
[root@localhost mappers]# ls mod_rewrite.c #查看mod_rewrite.c文件
以dso的方式编译安装到apache中
[root@localhost mappers]# /usr/local/apache2.4/bin/apxs -c -i -a /usr/local/src/httpd-2.4.28/modules/mappers/mod_rewrite.c
4.5 实战1:举例
1、实现client请求的主机前缀不是www.xuegod.cn和192.168.1.63都跳转到主机前缀为http://www.xuegod.cn 。例如当用户在地址栏写入http://xuegod.cn和bbs.xuegod.com直接跳转到http://www.xuegod.cn登录网站。
[root@localhost ~]# vim /usr/local/apache2.4/conf/httpd.conf
在:156 LoadModule rewrite_module modules/mod_rewrite.so 之后插入以下内容。
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www.xuegod.cn [NC]
RewriteCond %{HTTP_HOST} !^192.168.1.63 [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://www.xuegod.cn/ [L]
注释:
RewriteEngine on #打开rewirte功能。
RewriteCond %{HTTP_HOST} !^www.xuegod.cn [NC] #声明Client请求的主机中前缀不是。www.xuegod.cn,[NC]的意思是忽略大小写。
RewriteCond %{HTTP_HOST} !^192.168.1.63 [NC] #声明Client请求的主机中前缀不是。192.168.1.63,[NC]的意思是忽略大小写。
RewriteCond %{HTTP_HOST} !^$ #声明Client请求的主机中前缀不为空,[NC]的意思是忽略大小写。
RewriteRule ^/(.*) http://www.xuegod.cn/ [L]
#含义是如果Client请求的主机中的前缀符合上述条件,则直接进行跳转到http://www.xuegod.cn/,[L]意味着立即停 止重写操作,并不再应用其他重写规则。这里的.*是指匹配所有URL中不包含换行字符,()括号的功能是把所有的字符做一个标记,以便于后面的应用. 就是引用前面里的(.*)字符。
[root@localhost ~]# /etc/init.d/apachectl graceful #重新加载配置
[root@localhost ~]# echo "www.xuegod.cn" > /usr/local/apache2.4/htdocs/index.html #创建一个测试index.html页
2、 添加hosts记录文件:
[root@localhost ~]# vim /etc/hosts #插入以下内容。
192.168.1.63 www.xuegod.cn
192.168.1.63 xuegod.com.cn
192.168.1.63 xuegod.com
192.168.1.63 bbs.xuegod.com
注:我稍后测试,使用的是centos7下自带的浏览器,如果你使用的是物理机中的浏览器,需要修改一下自己物理机上的hosts文件。建议大家跟我一样,直接使用centos7虚拟机上的浏览器来测试结果。
3、打开浏览器,测试地址重写功能
打开链接http://www.xuegod.cn/ 和http://192.168.1.63/ #可以正常访问,没有进行跳转,如下图:
输入链接http://xuegod.com.cn/ 回车后也会直接跳转到http://www.xuegod.cn / 如下图:
同样当输入链接http://bbs.xuegod.com/ 回车后也会直接跳转到http://www.xuegod.cn /
总结:通过上面的例子,说明rewrite跳转成功。
4.6 实战2:将www.360buy.com 域名时跳转到www.jd.com
[root@localhost ~]# vim /usr/local/apache2.4/conf/httpd.conf
删除之前添加的rewrite规则:
157 RewriteEngine on
158 RewriteCond %{HTTP_HOST} !^www.xuegod.cn [NC]
159 RewriteCond %{HTTP_HOST} !^192.168.1.63 [NC]
160 RewriteCond %{HTTP_HOST} !^$
161 RewriteRule ^/(.*) http://www.baidu.com/ [L]
在原来位置插入以下内容:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.360buy.com [NC]
RewriteRule ^/(.*) http://www.jd.com/ [L]
[root@localhost ~]# vim /etc/hosts #hosts文件中追加
192.168.1.63 www.360buy.com
192.168.1.63 www.jd.com
[root@localhost ~]# /etc/init.d/apachectl graceful
测试:
http://www.360buy.com/ 直接转到www.jd.com 如下图:
4.7 实战3:对Apache进行防盗链的配置
实战场景:一些小网站为了盈利,通过盗链来实现对自己网站内容的丰富,这无疑加大了企业的空间和流量的成本,因此我们需要对Apache进行防盗链的配置。
防盗链配置如下:
[root@localhost ~]# vim /usr/local/apache2.4/conf/httpd.conf
删除:
157 RewriteEngine on
158 RewriteCond %{HTTP_HOST} ^www.360buy.com [NC]
159 RewriteRule ^/(.*) http://www.jd.com/ [L]
在原位置插入以下内容:
<IfModule rewrite_module>
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://sunsky.pw/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://sunsky.pw$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.sunsky.pw/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.sunsky.pw$ [NC]
RewriteRule .*\.(gif|jpg|swf)$ http://www.sunsky.pw [R,NC]
</IfModule>
如上配置之后,我们重启Aache服务即可生效。
[root@localhost ~]# /etc/init.d/apachectl restart
5 禁止浏览目录和php文件被解析-使用CDN做网站加速
5.1 禁止浏览目录
由于开启目录浏览会让我们整个目录下的内容全部都暴露到外面,因此我们必须要禁止目录浏览功能。当然一些目录开放给客户做下载的,可以忽略此项优化。
我们通过修改apache主配置文件httpd.conf中的<Directory></Directory>标签内的Options选项参数来实现禁用目录浏览。
[root@localhost ~]# cp -r /boot/grub2/ /usr/local/apache2.4/htdocs/ #先复制一些测试数据
[root@localhost ~]# chown apache:apache /usr/local/apache2.4/htdocs/grub2/ -R #修改一下拥有者,因为默认只有root用户对grub2有权限,如果不修改权限,会因为没有权限,而报403错误。
测试:打开 链接http://192.168.1.63/grub2/ ,发现当grub2目录下没有index.html文件时,会直接把目录中的文件表出来,这不是我们想要的。
现在禁止访问目录下的内容:
[root@localhost ~]# vim /usr/local/apache2.4/conf/httpd.conf #找到根目录中的。
261 <Directory "/usr/local/apache2.4/htdocs">
。。。
改:275 Options Indexes FollowSymLinks
为:275 Options FollowSymLinks
注:你只需要将上面代码中的 Indexes 去掉,就可以禁止 Apache 显示该目录结构。用户就不会看到该目录下的文件和子目录列表了。Indexes 的作用就是当该目录下没有 index.html 文件时,就显示目录结构,去掉 Indexes,Apache 就不会显示该目录的列表了。另外在Options Indexes FollowSymLinks的Indexes前面加上-减号符号。 即: Options -Indexes FollowSymLinks 也可以实现。在Indexes前,加 + 代表允许目录浏览;加 – 代表禁止目录浏览。
[root@localhost ~]# /etc/init.d/apachectl restart
测试:http://192.168.1.63/grub2/
5.2 禁止网站中某个目录中的php文件被解析
实战场景:企业的站点有时会提供用户进行上传操作,比如让用户上传一个文件或头像图片,而用户上传文件的存放目录,我们是不能给php的解析权限的,否则会对Apache服务和系统造成危害。
设置不允运行/usr/local/apache2/htdocs/data 目录下的php结尾的文件
[root@localhost ~]# mkdir /usr/local/apache2.4/htdocs/data
[root@localhost ~]# vim /usr/local/apache2.4/conf/httpd.conf
在:
248 <Directory "/usr/local/apache2.4/htdocs">
。。。
274 </Directory>
之后,添加以下内容:
<Directory "/usr/local/apache2/htdocs/data" >
<Files ~ ".php">
Order allow,deny
Deny from all
</Files>
</Directory>
[root@localhost ~]# /etc/init.d/apachectl restart #就可以了。
5.3 使用CDN做网站加速
简单地说,就是通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的缓存服务器内。通过DNS负载均衡的技术,判断用户来源就近访问cache服务器取得所需的内容,杭州的用户访问接近杭州服务器上的内容,北京访问接近北京服务器上的内容。这样可以有效减少数据在网络上传输的事件,提高速度。把静态内容发布到CDN减少了用户影响时间20%或更多。
CDN技术示意图:
国内有名的CND公司:网宿,蓝汛(chinacache),快网
5.4 Apache网站架构优化
好的网站架构是网站性能强大关键,更是网站安全的关键。
在生产环境中建议将程序页面服务器、图片附件服务器和上传服务器三者的功能尽量分离。
分离方法:
1、分离最佳方式是分别使用独立的服务器(需要程序支持)
2、次选方案在前端负载均衡器通过haproxy/nginx来根据用户请求的目录或扩展名来对后端的服务器发出请求。
例如:请求http://www.xuegod.cn/a/b.jpg就抛给图片服务器(CDN最好),这里是根据扩展名.jpg分发
请求http:// /www.xuegod.cn /upload/login.php就抛给apache服务器,这里是根据URL路径分发。
均不符合上面两个要求的,默认就都是抛给主web服务器。