Apache优化
一、开启 apache 的的Gzip(deflate)功能
gzip 可以极大的加速网站,有时压缩比率高到 80%,最少都有 40%以上,还是相当不错的。在 Apache2 之后的版本,模块名不叫 gzip,而叫 mod_deflate
1. 如果要开启 deflate 的话,一定要打开下面二个模块(在httpd.conf)
LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
mod_deflate 模块检查及安装(如果没有安装下面有方法)
[root@localhost conf]# /usr/local/http-2.4/bin/apachectl -M | grep deflate
deflate_module (shared)
2. 打开 httpd.conf 后,先将上面两行配置前面的#号去掉,这样 apache 就会启用这两个模块,其中
mod_deflate 是压缩模块,就是对要传输到客户端的代码进行 gzip 压缩;
mod_headers模块的作用是告诉浏览器页面使用了 gzip 压缩,如果不开启 mod_headers 那么浏览器就会对 gzip 压缩过的页面进行下载,而无法正常显示。
3.在 httpd.conf 中加入以下代码,可以加到任何空白地方,不了解 apache 的话,如果担心加错地方,就放到 http.conf 文件的最后一行
注:在添加代码前最好先查一查要添加的代码是否存在
<IfModule mod_deflate.c>
DeflateCompressionLevel 6# 压缩程度的等级,预设可以采用 6 这个数值,以维持耗用处理器效能与网页压缩质量的平衡。
SetOutputFilter DEFLATE #设置输出过滤器,对输出启用压缩,必须的,就像一个开关一样,告诉 apache 对传输到浏览器的内容进行压缩
#AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-javascript application/x-httpd-php
#AddOutputFilterByType DEFLATE image/*
AddOutputFilterByType DEFLATE text/*#设置对文件是文本的内容进行压缩,例如 text/html text/css text/plain 等.
AddOutputFilterByType DEFLATE application/ms* application/vnd* application/postscript application/javascript application/x-javascript #对 javascript 文件进行压缩
AddOutputFilterByType DEFLATE application/x-httpd-php application/x-httpd-fastphp #对 php 类型的文件进行压缩.
SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary #设置不对后缀gif,jpg,jpeg,png 的图片文件进行压缩。注:?:表示不会捕获 ( )里内容了
SetEnvIfNoCase Request_URI .(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary#同上,就是设置不对 exe,tgz,gz 等的文件进行压缩
SetEnvIfNoCase Request_URI .(?:pdf|mov|avi|mp3|mp4|rm)$ no-gzip dont-vary #同上就是设置不对 pdf,avi,mp3 等的文件进行压缩
</IfModule>
4. 设置日志输出!
DeflateFilterNote Input input_info#声明输入流的 byte 数量
DeflateFilterNote Output output_info#声明输出流的 byte 数量
DeflateFilterNote Ratio ratio_info#声明压缩的百分比
LogFormat '"%r" %{output_info}n/%{input_info}n (%{ratio_info}n%%)' deflate#声明日志格式
CustomLog logs/deflate_log.log deflate
5.修改完成后保存退出并重启 httpd 服务
使用谷歌浏览器测试访问,如下图显示结果:(提示:在访问测试页之前按 F12 键)
6. 查看日志:
[root@localhost htdocs]# cat /usr/local/http-2.4/logs/deflate_log.log
"GET /test1.html HTTP/1.1" 963/33581 (2%)
"GET /test1.html HTTP/1.1" 963/33581 (2%)
"GET /test1.html HTTP/1.1" 963/33581 (2%)
注:图片是不需要启用 GZip 压缩的,从 GZip 检测结果来看,压缩后的图片体积竟然大过原体积!这就解释了为什么图片不用启用 GZip 压缩的原因了!
如果没有安装:
1. 编译时安装方法
编译的时候跟上--enable-deflate 即可实现安装
2. 编译安装后可以用DSO 方式安装
[root@/]# cd /root/httpd-2.4/modules/filters/ #切到 apache 源码包 mod_deflate 所在的目录下
# /usr/local/http-2.4/bin/apxs -c -i -a mod_deflate.c #以 dso 的方式编译安装到 apache 中
/usr/local/http2.2/bin/apxs -c -i -a /root/httpd-2.2/modules/metadata/mod_headers.c#以dso的方式编译安装到 apache 中
[root@/]# ll /usr/local/http-2.4/modules/mod_deflate.so #检查 mod_deflate 是否安装,成功安装这里会显示出该文件
-rwxr-xr-x. 1 root root 98144 Oct 22 23:14 /usr/local/http-2.4/modules/mod_deflate.so
二、配置 mod_expires 模块
这个非常有用的优化,mod_expires 可以减少 20-30%左右的重复请求,让重复的用户对指定的页面请求结果都 CACHE 在本地,根本不向服务器发出请求。但要注意更新快的文件不要这么做。
这个模块控制服务器应答时的 Expires 头内容和 Cache-Control 头的 max-age 指令。有效期(expiration date)可以设置为相对于源文件的最后修改时刻或者客户端的访问时刻
1.未启用 expire 的效果:
[root@localhost htdocs]# curl -I 192.168.223.128/2.jpg
HTTP/1.1 200 OK
Date: Thu, 19 Apr 2018 11:42:45 GMT
Server: Apache/2.4.23 (Unix)
Last-Modified: Tue, 14 Jul 2009 05:32:31 GMT
ETag: "bde6b-46ea3c3d3b9c0"
Accept-Ranges: bytes
Content-Length: 777835
Content-Type: image/jpeg
2. 启用 expire 缓存:
mod_expires 的安装配置:(httpd.conf)
启用 expires_module
LoadModule expires_module modules/mod_expires.so
3.然后添加 Expires 配置规则(httpd.conf最后面加就可以)
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "now plus 1 month"
ExpiresByType application/x-javascript "now plus 5 day"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/bmp "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 month"
ExpiresByType image/png "access plus 1 minute"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
ExpiresDefault "now plus 0 minute"
</IfModule>
验证:
[root@localhost htdocs]# curl -I 192.168.223.128/2.jpg
HTTP/1.1 200 OK
Date: Thu, 19 Apr 2018 11:48:51 GMT
Server: Apache/2.4.23 (Unix)
Last-Modified: Tue, 14 Jul 2009 05:32:31 GMT
ETag: "bde6b-46ea3c3d3b9c0"
Accept-Ranges: bytes
Content-Length: 777835
Cache-Control: max-age=2592000
Expires: Sat, 19 May 2018 11:48:51 GMT
Content-Type: image/jpeg
ExpiresDefault 和 ExpiresByType 指令同样能够用易懂的语法格式进行定义:
ExpiresDefault "<base> [plus] {<num><type>}"
ExpiresByType type/encoding "<base> [plus] {<num><type>}"
其中<base>是下列之一:
• access
• now (等价于' access ')
• modification
plus 关键字是可选的。<num>必须是整数,<type>是下列之一:
• years
• months
• weeks
• days
• hours
• minutes
• seconds
例如,下列 3 个指令都表示文档默认的有效期是一个月:
ExpiresDefault "access plus 1 month"
ExpiresDefault "access plus 4 weeks"
ExpiresDefault "access plus 30 days"
有效期可以通过增加"<num><type>"子句进一步调整:
ExpiresByType text/html "access plus 1 month 15 days 2 hours"
ExpiresByType image/gif "modification plus 5 hours 3 minutes"
注意,如果你使用基于最后修改日期的设置,"Expires:"头将 不会 被添加到那些并非来自于磁盘文件的内容。这是因为这些内容并不存在"最后修改时间"的属性。
# GIF 有效期为 1 个月(秒数)
ExpiresByType image/gif A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/png A2592000
ExpiresByType image/x-icon A2592000
ExpiresByType application/x-javascript A604800
ExpiresByType text/plain A604800
# HTML 文档的有效期是最后修改时刻后的一星期
ExpiresByType text/html M604800
</IfModule>
"M"表示源文件的最后修改时刻,"A"表示客户端对源文件的访问时刻。后面的时间则以秒计算。
三、Apache禁止目录遍历
将httpd.conf文件的 Options Indexes FollowSymLinks 中的 Indexes 去掉,就可以禁止 Apache 显示该目录结构。
Indexes 的作用就是当该目录下没有 index.html 文件时,就显示目录结构。
开启时:
禁止时:
四、apache隐藏版本信息
测试默认 apache 的状态信息
[root@localhost htdocs]# curl -I 192.168.223.128/2.jpg
HTTP/1.1 200 OK
Date: Thu, 19 Apr 2018 12:42:34 GMT
Server: Apache/2.4.23 (Unix)
Last-Modified: Tue, 14 Jul 2009 05:32:31 GMT
ETag: "bde6b-46ea3c3d3b9c0"
Accept-Ranges: bytes
Content-Length: 777835
Cache-Control: max-age=2592000
Expires: Sat, 19 May 2018 12:42:34 GMT
Content-Type: image/jpeg
1. 主配置中启用 httpd-default.conf
Include conf/extra/httpd-default.conf
2. 修改 httpd-default.conf
文件:/usr/local/http-2.4/conf/extra/httpd-default.conf
找到:
ServerTokens Full
ServerSignature On
改成:
ServerTokens prod
ServerSignature Off
重启 apache 测试
测试隐藏版本号后 apache 的状态信息
[root@localhost extra]# curl -I 192.168.223.128/2.jpg
HTTP/1.1 200 OK
Date: Thu, 19 Apr 2018 12:49:59 GMT
Server: Apache
Last-Modified: Tue, 14 Jul 2009 05:32:31 GMT
ETag: "bde6b-46ea3c3d3b9c0"
Accept-Ranges: bytes
Content-Length: 777835
Cache-Control: max-age=2592000
Expires: Sat, 19 May 2018 12:49:59 GMT
Content-Type: image/jpeg
3. 如果你需要彻底将版本之类的信息进行改头换面,你就需要在编译之前做准备或者进行从新编译了。在重新编译时,修改源码包下 include 目录下的 ap_release.h 文件
#define AP_SERVER_BASEVENDOR "Apache Software Foundation" #服务的供应商名称
#define AP_SERVER_BASEPROJECT "Apache HTTP Server" #服务的项目名称
#define AP_SERVER_BASEPRODUCT "Apache" #服务的产品名
#define AP_SERVER_MAJORVERSION_NUMBER 2 #主要版本号
#define AP_SERVER_MINORVERSION_NUMBER 4 #小版本号
#define AP_SERVER_PATCHLEVEL_NUMBER 23 #补丁级别
#define AP_SERVER_DEVBUILD_BOOLEAN 0 #
上述列出的行,已经给出了注释,大家可以修改成自己想要的,然后编译安装之后,对方就彻底不知道你的版本号了。
五、 Apache日志切割
为什么要分割日志
随着网站的访问越来越大,WebServer 产生的日志文件也会越来越大,如果不对日志进行分割,那么只能一次将大的日志(如 Apache 的日志)整个删除,这样也丢失了很多对网站比较宝贵的信息,因为这些日志可以用来进行访问分析、网络安全监察、网络运行状况监控等,因此管理好这些海量的日志对网站的意义是很大的
1. 方法 1: 使用 rotatelogs(apache自带的工具)每隔一天
辑 Apache 的主配置文件,更改内容如下:
注释掉如下两行
ErrorLog "logs/error_log"
CustomLog "logs/access_log" common
然后添加如下两行
ErrorLog "|/usr/local/http-2.4/bin/rotatelogs -l logs/error_%Y%m%d.log 86400"
CustomLog "|/usr/local/http-2.4/bin/rotatelogs -l logs/access_%Y%m%d.log 86400" combined
注:其中 86400 为轮转的时间单位为秒
验证:查看 logs 目录下的日志文件
[root@localhost conf]# ls /usr/local/http-2.4/logs/
access_20180419.log deflate_log.log error_log access_log error_20180419.log httpd.pid
由于 apache 自带的日志轮询工具 rotatelogs,据说在进行日志切割时容易丢日志,因此我们通常使用 cronolog 进行日志轮询。
2. 方法 2 、使用 cronolog为每一天建立一个新的日志
安装 cronolog 程序
下载 cronolog
[root@localhost src]# tar zxf cronolog-1.6.2.tar.gz
[root@localhost src]# cd cronolog-1.6.2/
[root@localhost cronolog-1.6.2]# ./configure && make && make install
主配置文件中的使用方法
ErrorLog "|/usr/local/sbin/cronolog logs/error-%Y%m%d.log"
CustomLog "|/usr/local/sbin/cronolog logs/access-%Y%m%d.log" combined
如果 Apache 中有多个虚拟主机,最好每个虚拟主机中放置一个这样的代码,并将日志文件名改成不同的名字。
扩展:
这个保证了每天一个文件夹文件夹下每个小时产生一个 log
CustomLog "|/usr/local/sbin/cronolog logs /%Y%m%d/access_log.%H" combined
按天轮询(生产环境常见用法,推荐使用):
CustomLog "|/usr/local/sbin/cronolog logs/access_www_%Y%m%d.log" combined
按小时轮询(生产环境较常见用法):
CustomLog "|/usr/local/sbin/cronolog logs /access_www_ %Y%m%d%H.log" combined
验证:查看
logs
目录下的日志文件
[root@localhost logs]# ls
access-20180419.log deflate_log.log error_log access_log error-20180419.log httpd.pid
注意:
这两个管道日志文件程序还有一点不同之处是使用 cronolog 时如果日志是放在某个不存在的路径则会自动创建目录,而使用 rotatelogs 时不能自动创建,这一点要特别注意
六、配置防盗链
有时候,你的网站莫名其妙的访问量变大,不要高兴的太早,有可能是被别人盗链了。举个例子:比如你搭了个 discuz 论坛,里面有些热点图片、视频;然后别人将他网站上访问图片的地址重定向到你的 discuz 上,这样他的服务器就可以空闲出来了;也就是说别人访问他网站的图片视频,消耗的确是你服务器的资源;
解决这个问题的方法是配置下防盗链,让外来的盗不了链;
1. 方法 1 :Apache 防盗链 的第一种实现方法,可以用 rewrite 实现。
首先要httpd.conf,确保有这么一行配置:
LoadModule rewrite_module modules/mod_rewrite.so
在确认 Apache 的 rewrite module 可用:
[root@localhost logs]# apachectl -M | grep rewrite
rewrite_module (shared)
然后在找到自己网站对应的配置的地方(如在主配置文件中或虚拟主机中),加入下列代码:
ServerName www.benet.com
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://benet.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://benet.com$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.benet.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.benet.com$ [NC]
RewriteRule .*\.(gif|jpg|swf)$ http://www.benet.com/about/nolink.png [R,NC,L]
注:相关选项的解释
1.RewriteEngine On #启用 rewrite,要想 rewrite 起作用,必须要写上
2.RewriteCond test-string condPattern #写在 RewriteRule 之前,可以有一或 N 条,用于测试rewrite 的匹配条件,具体怎么写,后面会详细说到。
3.RewriteRule Pattern Substitution #规则
4. %{HTTP_REFERER}:服务器变量, HTTPReferer 是 header 的一部分,当浏览器向 web服务器发送请求的时候,一般会带上 Referer,告诉服务器我是从哪个页面链接过来的,服务器藉此可以获得一些信息用于处理。比如从我主页上链接到一个朋友那里,他的服务器就能够从 HTTP Referer 中统计出每天有多少用户点击我主页上的链接访问他的网站。
5.[ NC]指的是不区分大小写,[R]强制重定向 redirect
6. 字母 L 表示如果能匹配本条规则,那么本条规则是最后一条(Last),忽略之后的规则
注:
RewriteCond %{HTTP_REFERER} !^$
上面这一行意在允许空“HTTP_REFERER”的访问,即允许用户在浏览器地址栏中直接输入图片地址时图片文件的显示。
RewriteCond %{HTTP_REFERER} !benet\.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !www\.benet\.com/.*$ [NC]
设置允许访问的 HTTP 来源,包括网站自身。
RewriteRule .*\.(gif|jpg|swf)$ http://www.benet.com/about/nolink.png [R,NC,L]
将不满足 referer 条件的访问重定向至 nolink.png。 nolink.png 位于允许“盗链”的目录 about中,要相当注意,不然,警告信息和图片将无法在对方网站上显示。
注意:测试时要清除济浏览器缓存
防盗链配置的说明:
1. 红色部分: 表示自己的信任站点。对我的站点来说,设置为 http://www.benet.com 和http://benet.com
2. 绿色部分: 要保护文件的扩展名(以|分开)。以这些为扩展名的文件,必须通过红色标注的网址引用,才可以访问。
3. 蓝色部分: 定义被盗链时替代的图片,让所有盗链 jpg、gif、swf 等文件的网页,显示网页文档根目录下的 about/ nolink.png 文件。 注意:替换显示的图片不要放在设置防盗链的目录中,并且该图片文件体积越小越好。当然你也可以不设置替换图片,而是使用下面的语句即可:RewriteRule .*\.(gif|jpg|png)$ -[F]
注:[F] (强制 URL 为被禁止的 forbidden),强制当前 URL 为被禁止的,即,立即反馈一个 HTTP 响应代码 403(被禁止的)。
2、方法 2:通过判断浏览器头信息来阻止某些请求,即利用SetEnvIfNoCase和 access。
这个方法可以通过阻止某些机器人或蜘蛛爬虫抓取你的网站来节省你的带宽流量。
语法:
SetEnvIfNoCase attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...
SetEnvIfNoCase 当满足某个条件时,为变量赋值,即根据客户端请求属性设置环境变量。
注:Referer :指明了请求当前资源原始资源的 URL,使用 referer 是可以防盗链
注意:(LoadModule rewrite_modulemodules/mod_rewrite.so这个上个方法已经开启了这里就不用开了,否则也要开启)
然后在找到自己网站对应的配置的地方(如在主配置文件中或虚拟主机中),加入下列代码:
SetEnvIfNoCase Referer "^$" local_ref
SetEnvIfNoCase Referer "^http://192.168.223.128/.*$" local_ref
SetEnvIfNoCase Referer "^http://192.168.223.128/.*$" local_ref
<filesmatch "\.(mp3|mp4|zip|rar|jpg|gif|png)">
在上面的下面加上跟自己一样的
# 2.4 版本以下的
方法一:
Order Deny,Allow
Allow from env=local_ref
Deny from all
方法二:
Order Allow,Deny
Allow from env=local_ref
#2.4 版本以上,方法如下:
Require all denied
Require env local_ref
</filesmatch>