深度优化Apache

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度优化Apache相关的知识,希望对你有一定的参考价值。

关于Apache的优化分为以下几个步骤:

  • Apache的Gzip(deflate)功能;
  • Apache的缓存设置;
  • Apache禁止目录遍历;
  • Apache隐藏版本目录;
  • Apache日志分割;
  • Apache配置防盗链;

一、Apache的gzip(deflate)功能

gzip可以极大的加速网站,使用gzip功能有时压缩比率高到80%以上,最少都有40%以上,所以说gzip功能是非常强大的,还是不错的。

在Apache2之后的版本,模块名不叫gzip,而叫mod_deflate

未使用gzip时,网页中传输文件的过程,如图:
技术图片

使用gzip时,网页中传输文件的过程,如图:
技术图片

本次博文案例环境,可以参考博文:Apache的安装部署及工作模式详解

如果要使用gzip(deflate)的功能,一定要打开两个模块:

LoadModule deflate_module  modules/mod_deflate.so
//模块的作用:对传输到客户端的代码进行gzip压缩
LoadModule headers_module modules/mod_headers.so
//模块的作用:告诉客户端的浏览器,传输的文件使用了gzip压缩。如果不开启的话,则无法正常显示网页内容
[root@localhost ~]# apachectl -M | grep deflate
//检查mod_deflate模块是否安装,如果没有任何返回信息则表示没有安装

安装方法有两种:

  • 编译时添加“--enable-deflate”选项即可安装;
  • 使用DSO方式进行安装;

本身Apache已经安装完成,所以这里就是用DSO方式进行安装了

[root@localhost ~]# cd /usr/src/httpd-2.4.23/modules/filters/
//切换到Apache源码包mod_deflate所在的目录下
[root@localhost filters]#  /usr/local/http-2.4.23/bin/apxs -c -i -a mod_deflate.c
//使用apxs命令进行安装

apxs命令参数的解释:

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

在安装过程中会出现这样的错误信息,如图:
技术图片
这样的错误信息即表示缺少zlib-devel的安装包,使用“yum -y install zlib-devel”即可,再次重新安装mod_deflate模块!

[root@localhost filters]# ll /usr/local/http-2.4.23/modules/mod_deflate.so 
-rwxr-xr-x. 1 root root 98160 11月 22 18:53 /usr/local/http-2.4.23/modules/mod_deflate.so
//确认文件已经存在

检查Apache主配置文件出现以下情况:

[root@localhost ~]# 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

解决方法:

需要在Apache主配置文件的 LoadModule deflate_module modules/mod_deflate.so 这行的上一行添加LoadFile /usr/local/zlib/lib/libz.so
即可,如图:
技术图片

[root@localhost ~]# apachectl -t
Syntax OK                  //检查其配置文件没有错误
[root@localhost ~]# apachectl restart         
//重新启动Apache服务

接下来修改Apache主配置文件,使其开启gzip压缩传输功能:

LoadModule deflate_module  modules/mod_deflate.so
//这个模块的作用:对传输到客户端的代码进行gzip压缩
LoadModule headers_module modules/mod_headers.so
//这个模块的作用:告诉客户端的浏览器,传输的文件使用了gzip压缩。如果不开启的话,则无法正常显示网页内容
//查看Apache主配置文件必须保证这两个模块已经被启用

在Apache主配置文件中(个人建议在末尾)添加如下内容:

<IfModule mod_deflate.c>           //表示需要启用mod_deflate模块
DeflateCompressionLevel 9        //压缩程度的等级
SetOutputFilter DEFLATE           //设置输出过滤器,对输出启用压缩功能
AddOutputFilterByType DEFLATE text/*          //设置对文件是文本格式的进行压缩
SetEnvIfNoCase Reques t_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary      
//设置不对后缀为 gif,jpg,jpeg,png 的图片文件进行压缩。?:表示不会捕获 ( )里内容了 
</IfModule>

//以下内容是设置日志输出
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          //指定日志的存放路径

考虑到粘贴复制的问题,这里附上Apache文件中添加的内容(不带注释)

<IfModule mod_deflate.c>
DeflateCompressionLevel 9
SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/*
SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary
</IfModule>

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

修改完成之后,重新启用Apache服务,并使用谷歌浏览器进行测试(使用F12开启开发者模式,并使用F5进行刷新),如图:
技术图片


[root@localhost ~]# cat /usr/local/http-2.4.23/logs/deflate_log.log
//查看deflate的日志(日志路径在配置文件中已经定义)
"GET / HTTP/1.1" -/- (-%)
"GET /favicon.ico HTTP/1.1" -/- (-%)
"GET / HTTP/1.1" -/- (-%)
"GET / HTTP/1.1" 76/4725 (1%)
"GET / HTTP/1.1" 76/4725 (1%)   //可以看出压缩比例达到了99%
"-" -/- (-%)

注意:图片是不需要被压缩的,flash的swf文件也是不用压缩的(这两个东西压缩之后会出现意想不到的效果)

二、Apache的缓存设置

Apache的缓存设置主要依赖于 mod_expires 模块 ,启用模块后,可以减少20%~30%左右的重复请求,让重复的用户请求结果都缓存在本地。注意更新快的文件不要这么做

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

未启用 mod_expires模块expire缓存的效果:
技术图片

启用mod_expires模块expire缓存,方法如下:

LoadModule expires_module modules/mod_expires.so 
//查看Apache的主配置文件,必要要保证这个模块被启用

然后在Apache主配置文件末尾添加以下内容:

<IfModule mod_expires.c>             //表示启用expires模块
ExpiresActive On                             //启用expires功能
ExpiresByType text/html "access plus 2 minute"         
//设置后缀为html的文本文件保存时间为两分钟
ExpiresByType image/jpeg "access plus 1 mouth"        
//设置后缀为jpeg的图片信息保存时间为一个月
ExpiresDefault "now plus 0 minute"
//其他默认没有被定义的不进行缓存
</IfModule>

不带注释的配置文件:

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html "access plus 2 minute"
ExpiresByType image/jpeg "access plus 1 mouth"
ExpiresDefault "now plus 0 minute"
</IfModule>

测试效果如下:
技术图片
技术图片

缓存机制的配置格式:

ExpiresByType type/encoding "<base> [plus] {<num><type>}"
ExpiresDefault "<base> [plus] {<num><type>}"

1、其中<base>是下列之一:
access(相对于客户端访问的时间)
now(相当于access)
modification(相对于最后一次修改源文件后的缓存时间)
2、该plus关键字是可选的。num 应该是整数值,并且type是以下之一:
years
months
weeks
days
hours
minutes
seconds

也可以使用以下格式来定义缓存机制:

ExpiresByType image/jpeg A2592000   //表示图片的缓存是1个月
ExpiresByType text/html M604800    //表示HTML文档的有效期是最后修改时刻后的一星期
//"M"表示源文件的最后修改时刻,"A"表示客户端对源文件的访问时刻。后面的时间则以秒计 算。 

具体介绍可以参考官方文档

三、Apache禁止目录遍历

访问Apache时,默认访问的时Apache网页根目录下的index.html,如何这个文件不存在的话,就会出现以下情况:
技术图片
为了防止出现以上情况需要修改Apache的配置文件:
技术图片
重新启动服务之后,就会出现这种情况:
技术图片

四、Apache隐藏版本目录

不进行修改,默认的版本信息:
技术图片
这样轻易的出现在互联网上,显然是不安全的。可以通过以下操作进行优化处理,方法如下:

在Apache主配置文件中启用 httpd-default.conf 
Include conf/extra/httpd-default.conf 
//去除之前的#号
[root@localhost ~]# vim /usr/local/http-2.4.23/conf/extra/httpd-default.conf 
//找到
ServerTokens Full 
ServerSignature On
//修改为以下内容
ServerTokens Prod
ServerSignature Off

重新启动服务之后,再次进行查看:
技术图片

如果需要彻底的改变版本之类的信息,那么需要在编译之前,修改源码包下 include 目录下的 ap_release.h 文件 。

[root@localhost ~]# vim /usr/src/httpd-2.4.23/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日志分割

随着网站的访问量越来越大,产生的日志文件也就会越来越大,如果不对日志进行分隔处理,日志文件会越存越大,不易备份,而且只能一次性将Apache的日志全部删除,这样就会丢失很多对网站宝贵的信息,因此管理好这些海量的日志对网站来说十分重要。

对日志进行分隔处理可以通过以下两种方法:

方法 1:使用 rotatelogs(apache 自带的工具)每隔一天记录一个日志

修改Apache的主配置文件,更改内容如下:
//找到以下两行,进行注释:
ErrorLog logs/error_log 
CustomLog logs/access_log common 
//然后最好在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
//这里是要填写rotatelogs工具的绝对路径

在上面添加的内容中,86400为轮转的时间,单位是秒(也就是一天生成一个日志文件)。

[root@localhost ~]# systemctl restart httpd
//重启Apache服务
[root@localhost ~]# ls /usr/local/http-2.4.23/logs/
access_2019-11-23.log  access_log  error_2019-11-23.log  error_log  httpd.pid
//查看日志文件,第一次可能只会出现错误日志,访问一下,访问日志即可产生

这样就已经实现了日志按天进行分割存放!

由于 apache 自带的日志轮询工具 rotatelogs,据说在进行日志切割时容易丢日志,因此我们通常使用 cronolog (也就是方法2)进行日志轮询。

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

同样也是在Apache的主配置文件中注释掉以下两行:
ErrorLog "logs/error_log"
CustomLog "logs/access_log" common

下载cronolog源码包

[root@localhost ~]# tar zxf cronolog-1.6.2.tar.gz -C /usr/src
[root@localhost ~]# cd /usr/src/cronolog-1.6.2/
[root@localhost cronolog-1.6.2]#  ./configure && make && make install
//解压之后进行编译安装
[root@localhost ~]# vim /usr/local/http-2.4.23/conf/httpd.conf 
//编辑Apache的主配置文件
//将方法1中写入的日志切割配置项删除,写入下面的两行配置
    CustomLog "|/usr/local/sbin/cronolog logs/access-%Y-%m-%d.log" combined
    ErrorLog "|/usr/local/sbin/cronolog logs/error-%Y-%m-%d.log"
//同样这里写的也是cronolog工具的绝对路径
为了更好的进行测试,建议将原本的日志文件进行删除、移动操作
[root@localhost ~]# rm -rf /usr/local/http-2.4.23/logs/*log
[root@localhost ~]# ls /usr/local/http-2.4.23/logs/
httpd.pid
[root@localhost ~]# ls /usr/local/http-2.4.23/logs/
access-2019-11-23.log  error-2019-11-23.log  httpd.pid
//测试访问一下,访问日志和错误日志即可产生

这样就已经实现了日志按天进行分割存放!

如果 Apache 中有多个虚拟主机,最好每个虚拟主机中放置一个这样的代码,并将日志文件名改成不同的名字。

如果网站的访问实在太大,也可以进行按小时分隔,方法如下:
基于第二种方法实现:

[root@localhost ~]# vim /usr/local/http-2.4.23/conf/httpd.conf 
//将原本的两行配置内容修改如下:
    CustomLog "|/usr/local/sbin/cronolog logs/access-%Y-%m-%d.log.%H" combined
    ErrorLog "|/usr/local/sbin/cronolog logs/error-%Y-%m-%d.log.%H"
//就是在原本的配置上添加了“%H”表示按小时进行分隔
[root@localhost ~]# systemctl restart httpd
//重启Apache服务

自行进行测试访问,接下来查看日志文件,如图:
技术图片

生产环境下,常用方法:

按天轮询:
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 

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

以上是关于深度优化Apache的主要内容,如果未能解决你的问题,请参考以下文章

Apache深度优化

Apache深度优化

Apache深度优化

提效 7 倍,Apache Spark 自适应查询优化在网易的深度实践及改进

提效7倍,Apache Spark 自适应查询优化在网易的深度实践及改进

ElasticSearch 亿级数据检索深度优化