因为采用的是分布式安装,所以需要对http端和php端进行相关的优化,以便提高访问速度。
一、开启Apache的Gzip(deflate)功能
gzip可以极大的加速网站,有时压缩比率高到80%,最少都有40%以上。在Apache2之后的版本,模块名不叫gzip,而叫mod_deflate。
未使用Gzip
开启使用Gzip
1.查看并启用mod_deflate压缩传输
查看mod_deflate:
[root@http ~]# apachectl -M | grep deflate
如果有显示,则表示已启用压缩;
[root@http ~]# apachectl -M | grep deflate
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::8a19:a71e:21a5:16ec. Set the 'ServerName' directive globally to suppress this message
deflate_module (shared)
如果没有显示,则需要手动启动deflate模块。
开启deflate需要打开下面两个模块。
[root@http ~]# vim /usr/local/httpd/conf/httpd.conf
定位并去除"#"
LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
参数解释
mod_deflate:是压缩模块,就是对要传输到客户端的代码进行gzip压缩;
mod_headers:告诉浏览器页面使用了gzip压缩,如果不开启,浏览器就会对gzip压缩过的页面进行下载,而无法正常显示。
设置压缩比率,取值范围在1(最低)到9(最高)之间,不建议设置太高,虽然有很高的压缩率,但是占用更多的CPU资源。
2.在httpd.conf配置文件末尾,添加deflate参数配置
[root@http ~]# vim /usr/local/httpd/conf/httpd.conf
末尾添加:
<IfModule mod_deflate.c>
DeflateCompressionLevel 6
SetOutputFilter DEFLATE
#AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-javascript application/x-httpd-php
#AddOutputFilterByType DEFLATE image/*
AddOutputFilterByType DEFLATE text/*
AddOutputFilterByType DEFLATE application/ms* application/vnd* application/postscript application/javascript application/x-javascript
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>
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
参数解释
DeflateCompressionLevel 9 #压缩等级,预设可采用6,以维持耗用处理器效能与网页压缩质量的平衡。
SetOutputFilter DEFLATE #设置输出过滤器,对输出启用压缩,必须的,就像一个开关,告诉apache对传输到浏览器的内容进行压缩。
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等文件进行压缩。
#设置日志输出!
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
3.保存退出,重启服务
[root@http ~]# systemctl restart httpd
浏览器测试访问,如下图显示结果(在访问测试页之前按F12键)。
4.查看日志
[root@http htdocs]# cat ../logs/deflate_log.log
"GET /test.html HTTP/1.1" 6421/19949 (32%)
"GET /test1.html HTTP/1.1" 1360/4266 (31%)
注意:图片不需要启用Gzip,从Gzip检测结果来看,压缩后的图片体积竟然大过原体积。可以检测Google、baidu的图片,都没有启用图片Gzip,只启用了html、css、js等文件的Gzip,这就更加说明Gzip不适用于图片。另外,除了图片之外,flash的swf文件也是不启用Gzip的。
二、优化启用网站缓存expires
这是非常有用的优化,mod_expires可以减少20-30%左右的重复请求,让重复的用户对指定的页面请求结果都cache在本地,根本不向服务器发出请求。但要注意更新快的文件不要这么做。
这个模块控制服务器应答时的Expires头内容和Cache-Control头的max-age指令。有效期可以设置为相对于源文件的最后修改时刻或客户端的访问时刻。
未启用expire的效果
[root@http ~]# curl -I 192.168.31.83/12.png
HTTP/1.1 200 OK
Date: Tue, 25 Oct 2016 15:52:37 GMT
Server: Apache/2.4.23 (Unix)
Last-Modified: Sun, 23 Oct 2016 15:34:10 GMT
ETag: "8c9f-53f8a01b18080"
Accept-Ranges: bytes
Content-Length: 35999
Vary: Accept-Encoding
Content-Type: image/png
1.修改网站配置文件,启用expires模块
[root@http ~]# vim /usr/local/httpd/conf/httpd.conf
定位并去除"#"
LoadModule expires_module modules/mod_expires.so
2.在配置文件末尾添加,expires配置参数
[root@http ~]# vim /usr/local/httpd/conf/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@http ~]# curl -I 192.168.31.83/12.png
HTTP/1.1 200 OK
Date: Tue, 25 Oct 2016 16:00:57 GMT
Server: Apache/2.4.23 (Unix)
Last-Modified: Sun, 23 Oct 2016 15:34:10 GMT
ETag: "8c9f-53f8a01b18080"
Accept-Ranges: bytes
Content-Length: 35999
Cache-Control: max-age=60
Expires: Tue, 25 Oct 2016 16:01:57 GMT
Vary: Accept-Encoding
Content-Type: image/png
参数详解
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"表示客户端对源文件的访问时刻。后面的时间则以秒计算。
3.保存退出,重启服务
[root@http ~]# systemctl restart httpd
三、禁止网站目录遍历
将Options Indexes FollowSymLinks中的Indexes去掉,就可以禁止Apache显示该目录结构。
Indexes的作用就是当该目录下没有index.html文件时,就显示目录结构。
[root@http ~]# vim /usr/local/httpd/conf/httpd.conf
定位:Options Indexes FollowSymLinks 去除Indexes
[root@http ~]# systemctl restart httpd
四、Apache隐藏版本信息
1.主配置文件启用httpd-default.conf
[root@http ~]# vim /usr/local/httpd/conf/httpd.conf
定位并去除"#"
Include conf/extra/httpd-default.conf
2.修改httpd-default.conf配置
[root@http ~]# vim /usr/local/httpd/conf/extra/httpd-default.conf
改成:
ServerTokens Prod
ServerSignature Off
3.重启httpd服务
[root@http ~]# systemctl restart httpd
如果需要彻底将版本之类的信息进行改头换面,就需要在编译之前做准备或者进行重新编译。在重新编译时,修改源码包下include目录下的ap_release.h文件。
[root@http include]# vim 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 25 #补丁级别
#define AP_SERVER_DEVBUILD_BOOLEAN 0 #
上述列出的行可以修改成自己想要的,然后编译安装之后,对方就彻底不知道你的版本号了。
五、配置httpd日志轮替切割
随着网站的访问越来越大,WebServer产生的日志文件也越来越大,如果不对日志进行分割,那么只能一次将大的日志(如Apache的日志)整个删除,这样也丢失了很多对网站比较宝贵的信息,因为这些日志可以用来进行访问分析、网络安全监察、网络运行状况监控等,因此管理好这些日志对网站的意义很大。
方法一、使用rotatelogs(apache自带的工具)每隔一天记录一个日志。
1.禁用默认日志保存配置
[root@http ~]# vim /usr/local/httpd/conf/httpd.conf
定位并禁用:
#ErrorLog "logs/error_log"
#CustomLog "logs/access_log" common
2.添加的轮替策略
[root@http ~]# vim /usr/local/httpd/conf/httpd.conf #如有虚拟主机,也可以放在虚拟主机配置文件中。
或
[root@http ~]# vim /usr/local/httpd/conf/extra/httpd-vhosts.conf
...
ErrorLog "|/usr/local/httpd/bin/rotatelogs -l logs/error_%Y%m%d.log 86400"
CustomLog "|/usr/local/httpd/bin/rotatelogs -l logs/access_%Y%m%d.log 86400" combined
...
注:其中86400为轮转的时间单位为秒
3.重启httpd服务
[root@http ~]# systemctl restart httpd
验证:查看logs目录下的日志文件
[root@http ~]# ls /usr/local/httpd/logs
access_20200611.log dummy-host2.example.com-access_log error_20200612.log
access_20200612.log dummy-host2.example.com-error_log error_log
access_log dummy-host.example.com-access_log httpd.pid
benet.com-access_log dummy-host.example.com-error_log
benet.com-error_log error_20200611.log
由于rotatelogs在进行日志切割时容易丢日志,因此通常使用cronolog进行日志轮询。
方法二、使用cronolog为每一天建立一个新的日志(只能按照时间戳进行切割)。
步骤:安装 cronolog 程序
下载cronolog软件包
[root@http ~]# tar zxf cronolog-1.6.2.tar.gz
[root@http ~]# cd cronolog-1.6.2/
[root@http 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中有多个虚拟主机,最好每个虚拟主机中放置一个这样的代码,并将日志文件名改成不同的名字。
扩展
1.这个保证了每天一个文件夹,文件夹下每个小时产生一个log。
CustomLog "|/usr/local/sbin/cronolog logs/%Y%m%d/access_log.%H" combined
2.按天轮询(生产环境常见用法,推荐使用)。
CustomLog "|/usr/local/sbin/cronolog logs/access_www_%Y%m%d.log" combined
3.按小时轮询(生产环境较常见用法)。
CustomLog "|/usr/local/sbin/cronolog logs/access_www_%Y%m%d%H.log" combined
注意
1.这两个管道日志文件程序还有一点不同之处是使用cronolog时,如果日志是放在某个不存在的路径则会自动创建目录,而使用rotatelogs时不能自动创建。
2.系统日志及系统服务日志,由专门日志轮替配置服务管理。
配置文件为:/etc/logrotate.conf
六、配置防盗链
有时网站莫名其妙的访问量变大,不要高兴的太早,有可能被别人盗链了。
举个例子:比如你搭了个discuz论坛,里面有些热点图片、视频;然后别人将他网站上访问图片的地址重定向到你的discuz上,这样他的服务器就可以空闲出来;也就是说别人访问他网站的图片视频,消耗的却是你服务器的资源;解决这个问题的方法是配置防盗链,让外来的盗不了链。
方法一、Apache防盗链的第一种实现方法,可以用rewrite实现。
1.主配置文件启用rewrite模块
[root@http ~]# vim /usr/local/httpd/conf/httpd.conf
定位并去除"#"
LoadModule rewrite_module modules/mod_rewrite.so
2.打开虚拟主机配置文件
[root@http ~]# vim /usr/local/httpd/conf/extra/httpd-vhosts.conf
在<VirtualHost>内部添加:
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.(gif|jpg|swf):要保护文件的扩展名(以|分开)。以这些为扩展名的文件,必须通过信任的站点网址引用,才可以访问。
3.http://www.benet.com/about/nolink.png:定义被盗链时替代的图片,让所有盗链jpg、gif、swf等文件的网页,显示网页文档根目录下的about/nolink.png文件。注意:替换显示的图片不要放在设置防盗链的目录中,并且该图片文件体积越小越好。当然你也可以不设置替换图片,而是使用下面的语句即可:
RewriteRule .*\.(gif|jpg|png)$ - [F]
注:[F](强制URL为被禁止的forbidden),强制当前URL为被禁止的,即立即反馈一个HTTP响应代码403(被禁止的)。
3.重启httpd服务
[root@http ~]# systemctl restart httpd
方法二、通过判断浏览器头信息来阻止某些请求,即利用SetEnvIfNoCase和access。这个方法可以通过阻止某些机器人或蜘蛛爬虫抓取你的网站来节省你的带宽流量。
语法:
SetEnvIfNoCase attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...
SetEnvIfNoCase 当满足某个条件时,为变量赋值,即根据客户端请求属性设置环境变量。
注意:Referer:指明了请求当前资源原始资源的URL,使用referer是可以防盗链,然后在找到自己网站对应的配置的地方(如在主配置文件中或虚拟主机中),加入下列代码:
[root@http ~]# vim /usr/local/httpd/conf/extra/httpd-vhosts.conf
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版本以下的:
方法1:
Order Deny,Allow
Allow from env=local_ref
Deny from all
方法2:
Order Allow,Deny
Allow from env=local_ref
#2.4版本以上的方法如下:
Require all denied
Require env local_ref
</filesmatch>