Apache调优之apache防盗链、日志拆分和ab压力测试

 

1、apache防盗链

盗链,全称是盗取链接,假如我们的网站有很多好看的图片,别人可以查看我们网站图片的链接,然后应用在他的网站上,这样的话,去访问他的网站,实际上消耗的是我们的流量(因为实际链接在我们这里),这样我们就不得不去配置防盗链,使得别人不能复制我们图片的链接

要实现防盗链,我们就必须先理解盗链的实现原理,提到防盗链的实现原理就不得不从HTTP协议说起,在HTTP协议中,有一个表头字段叫referer,采用URL的格式来表示从哪儿链接到当前的网页或文件。换句话说,通过referer,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以跟踪到显示它的网页地址。有了referer跟踪来源就好办了,这时就可以通过技术手段来进行处理,一旦检测到来源不是本站即进行阻止或者返回指定的页面。

 

Apache 防盗链的第一种实现方法,可以用 Rewrite 实现。首先要确认 Apache 的 rewrite module 可用:能够控制 Apache httpd.conf 文件的,打开 httpd.conf,确保有这么一行配置:LoadModule rewrite_module modules/mod_rewrite.so

然后在相应虚拟主机配置的地方,加入下列代码:

ServerName www.chinaz.com

# 防盗链配置 参数

RewriteEngine On

RewriteCond %{HTTP_REFERER} !^http://chinaz.com/.*$ [NC]

RewriteCond %{HTTP_REFERER} !^http://chinaz.com$ [NC]

RewriteCond %{HTTP_REFERER} !^http://www.chinaz.com/.*$ [NC]

RewriteCond %{HTTP_REFERER} !^http://www.chinaz.com$ [NC]

RewriteRule .*\.(gif|jpg|swf)$ http://www.chinaz.com/img/nolink.gif [R,NC]

其中,chinaz.com/www.chinaz.com 表示自己的信任站点。gif|jpg|swf 表示要保护文件的扩展名(以|分开)。nolink.gif 盗链后的重定向页面/图片。用以输出警示信息,这张图片应该尽可能的小,当然你也可以不设置替换图片,而是使用下面的语句即可:RewriteRule .*\.(gif|jpg|png)$ - [F]  注:[F] (强制URL为被禁止的 forbidden),强制当前URL为被禁止的,即,立即反馈一个HTTP响应代码403(被禁止的)。

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中,要相当注意,不然,警告信息和图片将无法在对方网站上显示。 

有些用户使用的是虚拟主机,没有服务器的控制权,无法修改 httpd.conf 文件和重启服务器。那么请确认你的虚拟主机支持 .htaccess,将上面的配置写入 .htaccess 文件,放入根目录或图片所在的目录即可:

# 防盗链配置

RewriteEngine On

RewriteCond %{HTTP_REFERER} !^http://chinaz.com/.*$ [NC]

RewriteCond %{HTTP_REFERER} !^http://chinaz.com$ [NC]

RewriteCond %{HTTP_REFERER} !^http://www.chinaz.com/.*$ [NC]

RewriteCond %{HTTP_REFERER} !^http://www.chinaz.com$ [NC]

RewriteRule .*\.(gif|jpg|swf)$ http://www.chinaz.com/img/nolink.gif [R,NC]

通过判断referer变量的值,判断图片或资源的引用是否合法,只有在设定范围内的 referer,才能访问指定的资源,从而实现了防盗链(Anti-Leech)的目的。需要指出的是:不是所有的用户代理(浏览器)都会设置 referer 变量,而且有的还可以手工修改 referer,也就是说,referer 是可以被伪造的。

 

方法2:通过判断浏览器头信息来阻止某些请求,即利用SetEnvIfNoCase和access。这个方法可以通过阻止某些机器人或蜘蛛爬虫抓取你的网站来节省你的带宽流量。

语法: SetEnvIfNoCase attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...

SetEnvIfNoCase 当满足某个条件时,为变量赋值,即根据客户端请求属性设置环境变量。

注:Referer :指明了请求当前资源原始资源的URL,使用referer是可以防盗链

然后在找到自己网站对应的配置的地方(如在主配置文件中或虚拟主机中),加入下列代码: 

SetEnvIfNoCase Referer "^$" local_ref

SetEnvIfNoCase Referer "www.benet.com/.*$" local_ref

SetEnvIfNoCase Referer "benet.com/.*$" local_ref

 

 

测试:

在还没有设置防盗链时,网站www.lyq.com的配置如图1所示

                            图1


网站lyq.gdcp.cn的配置如图2所示

                          图2


访问网页:

访问www.lyq.com,如图3所示

                                    图3

访问lyq.gdcp.cn,如图4所示

                                 图4


配置了防盗链时,服务器www.lyq.com的配置,如图5所示(服务器lyq.gdcp.cn不用修改)

                             图5


访问页面:

访问www.lyq.com,如图6所示

                              图6

访问lyq.gdcp.cn,如图7和图8所示

                               图7

                                图8


2、日志拆分

使用工具Cronnolog进行日志切割。

1.下载及安装

wget http://cronolog.org/download/cronolog-1.6.2.tar.gz

tar zxvf cronolog-1.6.2.tar.gz

cd cronolog-1.6.2

./configure

make &&  make install

 

2.用which命令查看路径验证安装

which cronolog

默认路径为:/usr/local/sbin/cronolog

 

3.配置

vi /usr/local/apache/conf/httpd.conf

CustomLog “|/usr/local/sbin/cronolog /usr/local/apache/logs/access_%Y%m%d.log” combined   #定义访问日志

ErrorLog “|/usr/local/sbin/cronolog /home/www/ex/log/error_%Y%m%d.log”                    #定义错误日志

保存配置文件后,重启apache。

命令:service httpd restart

 

第二种方法

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

注释掉如下两行

ErrorLog logs/error_log

CustomLog logs/access_log common

然后添加如下两行

ErrorLog "|/usr/local/apache/bin/rotatelogs /usr/local/apache/logs/errorlog.%Y-%m-%d-%H_%M_%S 2M +480"

CustomLog "|/usr/local/apache/bin/rotatelogs /usr/local/apache/logs/accesslog.%Y-%m-%d-%H_%M_%S 2M +480" common

 

意义如下:

errorlog.%Y-%m-%d-%H_%M_%S为生成日志的格式,类似于这样:errorlog.2010-04-15-11_32_30 ,以年月日时分秒为单位的,2M 为日志的大小,即为日志达到多大后生成新的日志文件,支持的单位为K,M,G,本处为2M。+480 为时差,文件的时间为美国时间,中国的时差要比美国多8个小时也就是480分钟,所以要加上480分钟。

 

rotatelogs说明:

rotatelogs logfile [ rotationtime [ offset ]] | [ filesizeM ]

rotationtime指的是设定多少秒后进行日志切割,如这里的300秒,在设定的时间之后系统将自动切割日志;offset指的是日志时间的偏移量,如果不设置该偏移量,则默认为0,且显示的时间与北京时间会不一样,与北京时间相差8个小时,故建议将其设置为+480,单位为分钟;filesizeM指的是日志多大之后自动切割,可接受的单位为K,M,G,上面的ErrorLog设置为400M之后自动切割日志。

其他的设置方法如下:

每天生成一个错误日志文件

ErrorLog "|bin/rotatelogs.exe -l logs/error-%Y-%m-%d.log 86400"

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

rotatelogs - 滚动Apache日志的管道日志程序

rotatelogs是一个配合Apache管道日志功能使用的简单程序。举例:

CustomLog "|bin/rotatelogs /var/logs/logfile 86400" common

此配置会建立文件"/var/logs/logfile.nnnn",其中的nnnn是名义上的日志启动时的系统时间(此时间总是滚动时间的倍数,可以用于cron脚本的同步)。在滚动时间到达时(在此例中是24小时以后),会产生一个新的日志。

CustomLog "|bin/rotatelogs /var/logs/logfile 5M" common

此配置会在日志文件大小增长到5兆字节时滚动该日志。

ErrorLog "|bin/rotatelogs /var/logs/errorlog.%Y-%m-%d-%H_%M_%S 5M"

此配置会在错误日志大小增长到5兆字节时滚动该日志,日志文件名后缀会按照如下格式创建:errorlog.YYYY-mm-dd-HH_MM_SS 。

语法

rotatelogs [ -l ] logfile [ rotationtime [ offset ]] | [ filesizeM ]

选项

-l

使用本地时间代替GMT时间作为时间基准。注意:在一个改变GMT偏移量(比如夏令时)的环境中使用-l会导致不可预料的结果。

logfile

它加上基准名就是日志文件名。如果logfile中包含"%",则它会被视为用于strftime()的格式字符串;否则它会被自动加上以秒为单位的".nnnnnnnnnn"后缀。这


两种格式都表示新的日志开始使用的时间。

rotationtime

日志文件滚动的以秒为单位的间隔时间。

offset

相对于UTC的时差的分钟数。如果省略,则假定为"0"并使用UTC时间。比如,要指定UTC时差为"-5小时"的地区的当地时间,则此参数应为"-300"。

filesizeM

指定以filesizeM文件大小滚动,而不是按照时间或时差滚动。

可移植性

下列日志文件格式字符串可以为所有的strftime()实现所支持,见各种扩展库对应的strftime()的手册。

%A星期名全称(本地的)

%a3个字符的星期名(本地的)

%B月份名的全称(本地的)

%b3个字符的月份名(本地的)

%c日期和时间(本地的)

%d2位数的一个月中的日期数

%H2位数的小时数(24小时制)

%I2位数的小时数(12小时制)

%j3位数的一年中的日期数

%M2位数的分钟数

%m2位数的月份数

%pam/pm12小时制的上下午(本地的)

%S2位数的秒数

%U2位数的一年中的星期数(星期天为一周的第一天)

%W2位数的一年中的星期数(星期一为一周的第一天)

%w1位数的星期几(星期天为一周的第一天)

%X时间(本地的)

%x日期(本地的)

%Y4位数的年份

%y2位数的年份

%Z时区名

%%符号"%"本身

 

 

 

 

测试:

使用编辑Apache的主配置文件httpd.conf的方法,如图9所示

                               图9


到log目录下查看是否有该日志文件,如图10所示

                                图10


查看日志文件,如图11所示

                                图11


3、ab压力测试

ab命令原理 

Apache的ab命令模拟多线程并发请求,测试服务器负载压力,也可以测试nginx、lighthttp、IIS等其它Web服务器的压力。ab命令对发出负载的计算机要求很低,既不会占用很多CPU,也不会占用太多的内存,但却会给目标服务器造成巨大的负载,因此是某些DDOS***之必备良药,老少皆宜。自己使用也须谨慎。否则一次上太多的负载,造成目标服务器直接因内存耗光死机,而不得不硬重启,得不偿失。

在带宽不足的情况下,最好是本机进行测试,建议使用内网的另一台或者多台服务器通过内网进行测试,这样得出的数据,准确度会高很多。远程对web服务器进行压力测试,往往效果不理想(因为网络延时过大或带宽不足)

 

注:

参数解析:

-n:代表请求数,在测试会话中所执行的请求个数。默认时,仅执行一个请求

-c:代表并发数,一次产生的请求个数。默认是一次一个

-t:测试所进行的最大秒数。其内部隐含值是-n 50000。它可以使对服务器的测试限制在一个固定的总时间以内。默认时,没有时间限制

-p:包含了需要POST的数据的文件

-T:POST数据所使用的Content-type头信息。

-v:设置显示信息的详细程度 - 4或更大值会显示头信息, 3或更大值可以显示响应代码(404, 200等), 2或更大值可以显示警告和其他信息。 -V 显示版本号并退出。

-i:执行HEAD请求,而不是GET。

-C:cookie-name=value 对请求附加一个Cookie:行。 其典型形式是name=value的一个参数对。此参数可以重复。

-P:proxy-auth-username:password 对一个中转代理提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。无论服务器是否需要(即, 是否发送了401认证需求代码),此字符串都会被发送。

 

返回结果解析:

Server Software:       ##apache版本 
Server Hostname:         ##请求的机子 
Server Port:         ##请求端口
Document Length:       ##
HTTP响应数据的正文长度

Concurrency Level:      ##并发数 
Time taken for tests:      ##所有这些请求处理完成所花费的时间 
Complete requests:      ##完成请求数 
Failed requests:       ##失败请求数  
Total transferred:      ##总共传输字节数,包含http的头信息等 
HTML transferred:        ##html字节数,实际的页面传递字节数 
Requests per second:      ##每秒多少请求,这个是非常重要的参数数值,服务器的吞吐量 
Time per request:      ##服务器收到请求,响应页面要花费的时间 
Time per request:       ##服务器平均处理时间,也就是服务器吞吐量的倒数 
Transfer rate:        ##平均每秒网络上的流量,可以帮助排除是否存在网络流量过大导致响应时间延长的问题

 

测试:

[root@lyq1 bin]# ./ab -c1000 -n1000 http://www.lyq.com:8080/1.jpg 

This is ApacheBench, Version 2.3 <$Revision: 1796539 $>

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Licensed to The Apache Software Foundation, http://www.apache.org/

 

Benchmarking www.lyq.com (be patient)

Completed 100 requests

Completed 200 requests

Completed 300 requests

Completed 400 requests

Completed 500 requests

Completed 600 requests

Completed 700 requests

Completed 800 requests

Completed 900 requests

Completed 1000 requests

Finished 1000 requests

 

Server Software:        Apache    ##apache版本(这里版本已被隐藏了)

Server Hostname:        www.lyq.com    ##服务器主机名

Server Port:            8080           ##服务器端口

 

Document Path:          /1.jpg         ##测试的页面文档

Document Length:        9006 bytes     ##测试文档大小

 

Concurrency Level:      1000             ##并发数

Time taken for tests:   6.950 seconds   ##整个测试持续的时间

Complete requests:      1000             ##完成的请求数量

Failed requests:        0               ##失败的请求数量

Total transferred:      9241000 bytes      ##整个场景中的网络传输量

HTML transferred:       9006000 bytes   ##整个场景中的HTML内容传输量

Requests per second:    143.89 [#/sec] (mean)   ##大家最关心的指标之一,相当于LR中的每秒事务数,后面括号中的mean表示这是一个平均值

Time per request:       6949.866 [ms] (mean)     ##大家最关心的指标之二,相当于LR中的平均事务响应时间,后面括号中的mean表示这是一个平均值

Time per request:     6.950 [ms] (mean, across all concurrent requests)  ##每个请求实际运行时间的平均值

Transfer rate:          1298.50 [Kbytes/sec] received  ##平均每秒网络上的流量,可以帮助排除是否存在网络流量过大导致响应时间延长的问题

Connection Times (ms)

              min  mean[+/-sd] median   max

Connect:        0   21  20.1      3      44

Processing:     6  805 2070.7     16    6905

Waiting:        6  804 2070.8     15    6905

Total:          7  826 2078.7     22    6946

##网络上消耗的时间的分解,各项数据的具体算法还不是很清楚

Percentage of the requests served within a certain time (ms)

  50%     22

  66%     59

  75%    248

  80%    260

  90%   4011

  95%   6884

  98%   6916

  99%   6939

 100%   6946 (longest request)

##整个场景中所有请求的响应情况。在场景中每个请求都有一个响应时间,其中50%的用户响应时间小于22 毫秒,60% 的用户响应时间小于59 毫秒,最大的响应时间小于6946 毫秒

  由于对于并发请求,cpu实际上并不是同时处理的,而是按照每个请求获得的时间片逐个轮转处理的,所以基本上第一个Time per request时间约等于第二个Time per request时间乘以并发请求数