Apache深度优化

Apache深度优化

文章目录

1)开启apache的Gzip(defate)功能

gzip 可以极大的加速网站,有时压缩比率高到 80%,最少都有 40%以上,还是相当不错的。 在 Apache2 之后的版本,模块名不叫 gzip,而叫 mod_deflate

未使用 Gzip:
Apache深度优化插图
开始使用Gzip:
Apache深度优化插图(1)
如果要开启 deflate 的话,一定要打开下面二个模块

LoadModule deflate_module modules/mod_deflate.so

LoadModule headers_module modules/mod_headers.so

设置压缩比率,取值范围在 1(最低) 到 9(最高)之间,不建议设置太高,虽然有很高的压缩率, 但是占用更多的 CPU 资源.

mod_deflate 模块检查及安装

检查模块是否安装:

[root@apache ~]# apachectl -M | grep deflte

如果没有安装,有两种安装方法:

a、编译时安装方法

在编译安装Apache的时候跟上–enable-deflate 即可实现安装,Apache安装部署点击这里

b、DSO方式安装

切到apache 源码包 mod_deflate 所在 的目录下

[root@apache ~]# cd /root/httpd-2.4.23/modules/filters/

以 dso 的方式编译安装到 apache 中

[root@apache filters]# apxs -c -i -a mod_deflate.c

如果报错:

[root@apache filters]# apxs -c -i -a mod_deflate.c
/usr/local/apr/build-1/libtool --silent --mode=compile gcc -std=gnu99 -prefer-pic   -DLINUX -D_REENTRANT -D_GNU_SOURCE -g -O2 -pthread -I/usr/local/http-2.4.23/include  -I/usr/local/apr/include/apr-1   -I/usr/local/apr-util/include/apr-1   -c -o mod_deflate.lo mod_deflate.c && touch mod_deflate.slo
mod_deflate.c:51:18: fatal error: zlib.h: No such file or directory
 #include "zlib.h"
                  ^
compilation terminated.
apxs:Error: Command failed with rc=65536
.

原因是缺少了zlib-devel 的安装包,装上就可以了

[root@apache filters]# yum -y install zlib-devel

再次安装模块,检查mod_deflate是否安装,成功安装这里会显示出该文件

[root@apache filters]# ll /usr/local/http-2.4.23/modules/mod_deflate.so
-rwxr-xr-x. 1 root root 98104 6月   9 09:20 /usr/local/http-2.4.23/modules/mod_deflate.so

apxs 命令参数说明:

  • -i:此选项表示需要执行安装操作,以安装一个或多个动态共享对象到服务器的 modules 目 录中
  • -a:此选项自动增加一个 LoadModule 行到 httpd.conf 文件中,以启用此模块,或者,如果 此行已经存在,则启用之
  • -c:此选项表示需要执行编译操作

如果重启的时候出现错误:

[root@apache ~]# apachectl -t
httpd: Syntax error on line 104 of /usr/local/http-2.4.23/conf/httpd.conf: Cannot load modules/mod_deflate.so into server: /usr/local/http-2.4.23/modules/mod_deflate.so: undefined symbol: inflate
[root@apache ~]# apachectl -M
httpd: Syntax error on line 104 of /usr/local/http-2.4.23/conf/httpd.conf: Cannot load modules/mod_deflate.so into server: /usr/local/http-2.4.23/modules/mod_deflate.so: undefined symbol: inflate
[root@apache ~]# httpd -M
httpd: Syntax error on line 104 of /usr/local/http-2.4.23/conf/httpd.conf: Cannot load modules/mod_deflate.so into server: /usr/local/http-2.4.23/modules/mod_deflate.so: undefined symbol: inflate

需要在 LoadModule deflate_module modules/mod_deflate.so 的前面加载 zlib.so 这里需要注意的是 LoadModule deflate_module 需要放在 LoadModule php5_module 之后 LoadFile /usr/lib/libz.so(x64 系统中该库文件位于/usr/lib64 目录下,可以软链接到/usr/lib 下 或者就在 LoadModule deflate_module modules/mod_deflate.so 这行的上一行添加 LoadFile /usr/lib64/libz.so 即可

[root@apache ~]# vim /usr/local/http-2.4.23/conf/httpd.conf
LoadFile /usr/lib64/libz.so # 追加
LoadModule deflate_module modules/mod_deflate.so # 去掉注释
LoadModule headers_module modules/mod_headers.so # 去掉注释

这样 apache 就会启用这两个模块,

mod_deflate 是压缩模块,就是对要传输到客户端的代码进行 gzip 压缩

mod_headers 模块的作用是告诉浏览器页面使用了 gzip 压缩,如果不开启 mod_headers 那么浏览器就会 对 gzip 压缩过的页面进行下载,而无法正常显示

LoadModule /usr/lib64/libz.so:如果使用DSO方式安装的deflate模块需要声明,没用可以不用写

在添加压缩级别等参数:

在 httpd.conf 中加入以下代码,可以加到任何空白地方,不了解 apache 的话,如果担心加 错地方,就放到 http.conf 文件的最后一行

注:在添加代码前最好先查一查要添加的代码是否存在

<IfModule mod_deflate.c>
DeflateCompressionLevel 9
SetOutputFilter DEFLATE 
AddOutputFilterByType DEFLATE text/*
AddOutputFilterByType DEFLATE application/x-httpd-php application/x-httpd-fastphp
SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI .(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI .(?:pdf|mov|avi|mp3|mp4|rm)$ no-gzip dont-vary
</IfModule>

DeflateCompressionLevel 9:

压缩程度的等级,预设可以采用 6 这个数值,以维持 耗用处理器效能与网页压缩质量的平衡

SetOutputFilter DEFLATE:

设置输出过滤器,对输出启用压缩,必须的,就像一个 开关一样,告诉 apache 对传输到浏览器的内容进行压缩

AddOutputFilterByType DEFLATE text/*:

设置对文件是文本的内容进行压缩,例如 text/html text/css text/plain 等

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 等的文件进行压缩

设置日志输出
DeflateFilterNote Input input_info
DeflateFilterNote Output output_info
DeflateFilterNote Ratio ratio_info
LogFormat '"%r" %{output_info}n/%{input_info}n (%{ratio_info}n%%)' deflate
CustomLog logs/deflate_log.log deflate

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:

声明日志格式

修改完成后保存退出并重启 apache服务

[root@apache ~]# systemctl restart httpd

使用谷歌浏览器测试访问,如下图显示结果:(提示:在访问测试页之前按 F12 键)
Apache深度优化插图(2)

查看日志:

[root@apache ~]# cat /usr/local/http-2.4.23/logs/deflate_log.log
"GET /test.html HTTP/1.1" 6421/19949 (32%)
"GET /test1.html HTTP/1.1" 1360/4266 (31%)

注:图片是不需要启用 GZip 压缩的,从 GZip 检测结果来看,压缩后的图片体积竟然大过原 体积!这就解释了为什么图片不用启用 GZip 压缩的原因了!

可以检测了几个门户网站的图片,还有 Google、baidu 的图片,统统都没有启用图片 GZip 压缩,只是启用了 html、css、js 等文件的 GZip 压缩,这就更加说明了 GZip 压缩不适用于图 片上。另外,除了图片之外,flash 的 swf 文件也是不用启用 GZip 压缩的

2)配置 mod_expires 模块

这个非常有用的优化,mod_expires 可以减少 20-30%左右的重复请求,让重复的用户对指定 的页面请求结果都 CACHE 在本地,根本不向服务器发出请求。但要注意更新快的文件不要 这么做

这个模块控制服务器应答时的 Expires 头内容和 Cache-Control 头的 max-age 指令。有效期 (expiration date)可以设置为相对于源文件的最后修改时刻或者客户端的访问时刻。

未启用 expire 的效果:

[root@apache ~]# curl -I 192.168.1.70/12.png
HTTP/1.1 200 OK
Date: Tue, 09 Jun 2020 02:11:04 GMT
Server: Apache/2.4.23 (Unix)
Last-Modified: Sat, 28 Sep 2019 02:39:14 GMT
ETag: "206701-59393e8841880"
Accept-Ranges: bytes
Content-Length: 2123521
Content-Type: image/png
启用 expire 缓存:

mod_expires 的安装配置:

启用 expires_module

LoadModule expires_module modules/mod_expires.so # 去掉注释

然后添加 Expires 配置规则

<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>

语法:

  • ExpiresByType:定义缓存页面
  • text/html:指定缓存界面的类型
  • A60:缓存页面的时间
  • ExpireActive On:开启缓存功能
  • ExpiresByType text/html M60:页面最后一次修改缓存60
  • ExpiresByType image/png A60:图片缓存,和ExpiresByType image/png "access plus 1 month"意思相同
  • ExpiresDefault “now plus 0 minute”:其他页面不进行缓存

验证:

[root@apache ~]# curl -I 192.168.1.70/12.png
HTTP/1.1 200 OK
Date: Tue, 09 Jun 2020 02:14:55 GMT
Server: Apache/2.4.23 (Unix)
Last-Modified: Sat, 28 Sep 2019 02:39:14 GMT
ETag: "206701-59393e8841880"
Accept-Ranges: bytes
Content-Length: 2123521
Cache-Control: max-age=60
Expires: Tue, 09 Jun 2020 02:15:55 GMT
Content-Type: image/png

ExpiresDefault 和 ExpiresByType 指令同样能够用易懂的语法格式进行定义:

ExpiresDefault " [plus] {}"

ExpiresByType type/encoding " [plus] {}"

其中bash是下列之一:

  • access
  • now (等价于’access ')
  • modification

plus 关键字是可选的。num必须是整数,type是下列之一

  • years
  • moths
  • 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 Expires Module 的介绍,可以参阅其官方文档:

3)Apache禁止目录遍历

未禁用的效果:
Apache深度优化插图(3)

将 Options Indexes FollowSymLinks 中的 Indexes 去掉,就可以禁止 Apache 显示该目录结构。

Indexes 的作用就是当该目录下没有 index.html 文件时,就显示目录结构

在配置文件(httpd.conf)中搜索Options,找到Options Indexes FollowSymLinks 并修改为Options FollowSymLinks

重启服务验证:
Apache深度优化插图(4)

4)Apache隐藏版本信息

测试默认 apache 的状态信息

[root@apache ~]# curl -I 192.168.1.70
HTTP/1.1 403 Forbidden
Date: Tue, 09 Jun 2020 02:29:20 GMT
Server: Apache/2.4.23 (Unix) # 版本信息直接暴露
Content-Type: text/html; charset=iso-8859-1
1、主配置中启用httpd-default.conf
Include conf/extra/httpd-default.conf  # 去掉注释
2、修改 httpd-default.conf

文件:/usr/local/http-2.4.23/conf/extra/httpd-default.conf

找到
ServerTokens Full
ServerSignature On
改成
ServerTokens Prod
ServerSignature Off

重启 apache 测试

[root@apache ~]# apachectl restart
[root@apache ~]# curl -I 192.168.1.70
HTTP/1.1 403 Forbidden
Date: Tue, 09 Jun 2020 02:34:30 GMT
Server: Apache
Content-Type: text/html; charset=iso-8859-1

如果你需要彻底将版本之类的信息进行改头换面,你就需要在编译之前做准备或者进行从新 编译了。在重新编译时,修改源码包下 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 #

上述列出的行,已经给出了注释,大家可以修改成自己想要的,然后编译安装之后,对方就彻底不知道你的版本号了

5)Apache日志分割

为什么要分割日志
随着网站的访问越来越大,WebServer 产生的日志文件也会越来越大,如果不对日志进行分 割,那么只能一次将大的日志(如 Apache 的日志)整个删除,这样也丢失了很多对网站比较 宝贵的信息,因为这些日志可以用来进行访问分析、网络安全监察、网络运行状况监控等, 因此管理好这些海量的日志对网站的意义是很大的
方法 1:使用 rotatelogs(apache 自带的工具)每隔一天记录一个日志

编辑Apache 的主配置文件,更改内容如下:

注释掉如下两行

ErrorLog "logs/error_log"
CustomLog "logs/access_log" common

然后添加如下两行

ErrorLog "|/usr/local/http-2.4.23/bin/rotatelogs -l logs/error_%Y%m%d.log 86400"
CustomLog "|/usr/local/http-2.4.23/bin/rotatelogs -l logs/access_%Y%m%d.log 86400" combined

注:其中 86400 为轮转的时间单位为秒

注:rotatelogs这个要写绝对路径,可以使用which来查询它的路径

验证:查看 logs 目录下的日志文件

[root@apache ~]# ls /usr/local/http-2.4.23/logs/
access_20200609.log  access_log  deflate_log.log  error_20200609.log  error_log  httpd.pid

由于 apache 自带的日志轮询工具 rotatelogs,据说在进行日志切割时容易丢日志,因此我们 通常使用 cronolog 进行日志轮询

方法 2、使用 cronolog 为每一天建立一个新的日志

安装 cronolog 程序

下载 cronolog
提取码:uzra

[root@apache ~]# tar zxf cronolog-1.6.2.tar.gz 
[root@apache ~]# cd cronolog-1.6.2/
[root@apache 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@apache ~]# ls /usr/local/http-2.4.23/logs/
access_20200609.log  access_log       error_20200609.log  error_log
access-20200609.log  deflate_log.log  error-20200609.log  httpd.pid

注意: 这两个管道日志文件程序还有一点不同之处是使用 cronolog 时如果日志是放在某个不存 在的路径则会自动创建目录,而使用 rotatelogs 时不能自动创建,这一点要特别注意

6)配置防盗链

有时候,你的网站莫名其妙的访问量变大,不要高兴的太早,有可能是被别人盗链了。 举个例子:比如你搭了个 discuz 论坛,里面有些热点图片、视频;然后别人将他网站上访问 图片的地址重定向到你的 discuz 上,这样他的服务器就可以空闲出来了;也就是说别人访问 他网站的图片视频,消耗的确是你服务器的资源

解决这个问题的方法是配置下防盗链,让外来的盗不了链

方法 1:Apache 防盗链的第一种实现方法,可以用 rewrite 实现

打开 httpd.conf,确保有这么一行配置:

LoadModule rewrite_module modules/mod_rewrite.so # 去掉注释

防盗链配置

<Directory "/usr/local/http-2.4.23/htdocs">这个区域下添加

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://192.168.1.70/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://192.168.1.70$ [NC]
RewriteCond %{HTTP_REFERER} !^http://192.168.1.70/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://192.168.1.70$ [NC]
RewriteRule .*\.(gif|jpg|swf)$http://192.168.1.70/image/error.png[R,NC,L]

注:相关选项的解释

  • RewriteEngine On:

启用 rewrite,要想 rewrite 起作用,必须要写上

  • RewriteCond test-string condPattern :

写在 RewriteRule 之前,可以有一或 N 条,用于测试 rewrite 的匹配条件,具体怎么写,后面会详细说到

  • RewriteRule Pattern Substitution:

规则

  • %{HTTP_REFERER}:

服务器变量,HTTPReferer 是 header 的一部分,当浏览器向 web 服务器发送请求的时候,一般会带上 Referer,告诉服务器我是从哪个页面链接过来的,服 务器藉此可以获得一些信息用于处理。比如从我主页上链接到一个朋友那里,他的服务器就 能够从 HTTP Referer 中统计出每天有多少用户点击我主页上的链接访问他的网站

  • [ NC]:

指的是不区分大小写,[R]强制重定向 redirect

  • 字母 L 表示如果能匹配本条规则,那么本条规则是最后一条(Last),忽略之后的规则

防盗链配置的说明:

192.168.1.70:

表示自己的信任站点,如果有域名的可以写域名

gif|jpg|swf:

要保护文件的扩展名(以|分开)。以这些为扩展名的文件,必须通过红色标注的网址引用, 才可以访问

192.168.1.70/image/error.png:

定义被盗链时替代的图片,让所有盗链 jpg、gif、swf 等文件的网页,显示网页文档根目 录下的 image/ error.png 文件。注意:替换显示的图片不要放在设置防盗链的目录中,并且该图片文件体积越小越好。当然你也可以不设置替换图片,而是使用下面的语句即可:RewriteRule .*.(gif|jpg|png)$ - [F]

注:[F] (强制 URL 为被禁止的 forbidden),强制当前 URL 为被禁止的,即,立即反馈一 个 HTTP 响应代码 403(被禁止的)

验证

再打开一个虚拟机(192.168.1.50),验证防盗链是否配置成功:

1、安装一个httpd服务:

[root@localhost ~]# yum -y install httpd

2、模拟web页面:

[root@localhost ~]# vim /var/www/html/index.html
<a  href="http://192.168.1.70/12.png">lianjie</a>

Apache深度优化插图(5)
Apache深度优化插图(6)

方法 2

通过判断浏览器头信息来阻止某些请求,即利用 SetEnvIfNoCase 和 access。

这个方法可以通过阻止某些机器人或蜘蛛爬虫抓取你的网站来节省你的带宽流量

语法: SetEnvIfNoCase attribute regex [!]env-variable[=value] [[!]env-variable[=value]] … SetEnvIfNoCase 当满足某个条件时,为变量赋值,即根据客户端请求属性设置环境变量

注:Referer :指明了请求当前资源原始资源的 URL,使用 referer 是可以防盗链 然后在找到自己网站对应的配置的地方(如在主配置文件中或虚拟主机中),加入下列代码:

SetEnvIfNoCase Referer "^$" local_ref
SetEnvIfNoCase Referer"^http://www.benet.com/.*$" local_ref
SetEnvIfNoCase Referer"^http://benet.com/.*$"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>
没有账号? 忘记密码?

社交账号快速登录