静态网站优化技巧总结
preface
公司的app下载服务器是一个静态网站,可是服务器配置不高,跑得阿里云虚拟机。在有限的硬件资源下,充分挖掘Nginx的高性能,成了一个工作重点。
缓存配置方法
在网站中,公共的js脚本经常被多个页面调用,我们通过配置nginx的缓存机制,可以让浏览器在访问不同页面时,不需要多次连接到服务器上获取这样一些重复调用的资源,从而减少浏览器的等待时间,提升用户访问体验。
在Nginx中,我们用下面的配置去配置Nginx的缓存机制。
location ~ \.(gif|jpg|jpeg|png|bmp|ico|css|js)$ { #后缀结尾是gif|jpg|jpeg|png|bmp|ico|css|js都进行压缩
root /var/www/html;
expires max;
}
expires 指令控制HTTP应答中的Expires和Cache-Control的头部信息。
语法如下:
expires [time|epoch|max|off]
其中:
- time: 可以使用正数或者负数。Expires头部信息的值将通过当前系统时间加上设定的time值来设定。time值还控制Cache-Control的值。负数表示no-cache;正数和零表示max-age=time。
- epoch: 指定Expires的值为1 January,1970,00:00:01 CMT
- max: 指定Expires的值为31 December2037 23:59:59 GMT,Cache-control的值为10年。
- -1 : 指定Expires的值为当前服务器时间-1s,即永远过期。
- off: 不修改Expires和cache-Control的值,此为默认值。
Notice
Expires使用了特定的时间,并且要求服务器和客户端是严格同步。而Cache-Control是用max-age指令指定组件被缓存多久。对于不支持http1.1的浏览器,需要expire来控制,所以最好能指定两个响应头。但是HTTP规范max-age指令重写expire头。
压缩配置方法
通过配置网站服务器进行输出压缩,可以减少HTTP响应传输的数据量,从而提供网站页面加载速度。在Nginx中,配置压缩的方法如下:
gzip on; # 开启gzip压缩,CPU的消耗大大提高
gzip_types text/html text/css text/xml application/javascript text/plain; # 针对哪些类型的文件进行压缩。
防盗链的配置方法
盗链就是指本网站的图片被资源链接使用到了其他非授权的网站页面上。对于盗链的网站来说,被消耗了大量带宽和服务器资源,但没有产生任何价值。通过配置网站服务器对接收到的请求中的Referer进行检查。可以有效避免景钛资源被第三方网站盗链。
HTTP Referer是HTTP请求头部信息的一部分,当浏览器向网站服务器发送请求的时候,都会带上Referer,告诉服务器我是从哪个页面过来的,因此服务器可以得知这个client从来过来的,根据来源进行处理。
在Nginx中,对图片资源进行防盗链的方法如下:
location ~ \.(jpg|jpeg|png)$ {
valid_referers none blocked *.ljf.com; # Referer不是*.ljf.com的都阻塞掉
if ($invalid_referer) { #如果来源域名不是*.ljf.com,那么$invalid_referer等于1,在if语句中返回一个403给用户
return 403;
# rewrite ^/ http://img.ljf.com/403.jpg # 或者返回一个403的图片也行。
}
}
图片剪裁的方法
在图片越来越泛滥的时代,作为一门运维人员,我们可以对用户上传的图片进行裁剪,可以减少存储的使用量和用户访问图片的等待时间。提供用户访问体验。
在linux系统中,使用的剪裁工具是ImageMagick(http://www.imagemagick.org)。ImageMagick包含了一组处理图片的命令工具。人们可能对GUI的图片处理工具并不陌生,例如GIMP和Photoshop等。但是GUI的工具在很多情况下并方便使用。比如需要在网站服务器上调用图片的时候或者需要批量处理的时候。在这些情况下ImangeMagick就很实用了。
我们使用yum来安装这个工具
[root@localhost ~]# yum -y install ImageMagick
使用下面的命令验证
[root@localhost ~]# convert -version
Version: ImageMagick 6.7.2-7 2016-06-16 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features: OpenMP
例如用户上传一张4608*3456像素的图片的为例,把它裁剪为原像50%和30%的尺寸图片:
[root@localhost ~]# identify IMG20160827130106.jpg
IMG20160827130106.jpg JPEG 4608x3456 4608x3456+0+0 8-bit DirectClass 8.261MB 0.000u 0:00.000 #原来8M的图片,1600W像素的图片
[root@localhost ~]# convert IMG20160827130106.jpg -resize 50% 111.jpg
[root@localhost ~]# convert IMG20160827130106.jpg -resize 30% 112.jpg
[root@localhost ~]# identify 111.jpg
111.jpg JPEG 2304x1728 2304x1728+0+0 8-bit DirectClass 2.257MB 0.000u 0:00.000 # 压缩到现在2M的图片,尺寸缩小到原来的一半。
[root@localhost ~]# identify 112.jpg
112.jpg JPEG 1382x1037 1382x1037+0+0 8-bit DirectClass 869KB 0.000u 0:00.000
减少Cookie的携带
在浏览器首次访问动态网站的时候,服务端通过发送Set-Cookie指令,能够让浏览器在后续访问指定域名的页面时,携带该带Cookie信息,以能够在服务器继续别该用户端的状态。例如是否登录,个性化设置。如果在访问静态网站,浏览器依然携带了这些Cookie,那么必然造成没有价值的数据流量(因为此时服务器端并没有对该Cookie的内容做任何的分析和利用)。在高并发的时候,这些消耗将被严重放大。
我们举个例子,一张图片的访问量有300百万的PV每天,假设一个Cookie的大小为556字节,每次访问这个图片都是带着Cookie的话,那么一天带来的带宽损耗得多大。
解决这个问题的方法是在配置静态文件时,使用和主站完全不同的域名。如提供动态内容的域名是www.ljf.com,那么提供静态图片,css等静态域名就可以为img.ljf.com,css.ljf.com,静态域名专注于提供静态服务的,这样就把两者的流量互相拆分出来了。
实现静态文件的安全下载
在一些应用场景下,需要对提供的下载文件进行验证,防止非授权的用户访问到这些资源,例如在验证真实用户登陆后才能够下载软件、在付费才可以下载的音视频等。
- 使用ngx_http_secure_link_module模块。
- 使用Nginx中的X-Accel-Redirect控制头部。
1. 使用ngx_http_secure_link_module模块的配置方法
我们假设配置这条URL http://liaojiafa.com/download/test.rar的有效时间只有5min,那么在Nginx配置文件中,对应的配置段是:
location /download/ {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "ljf.com$secure_link_expires$uri"; # ljf.com这个是密码
if () {
return 403;
}
if ($secure_link == "0"){
return 410;
}
}
Nginx的配置文件要和PHP生产网页的代码相结合,我们举个PHP代码的例子,这样结合Nginx的配置文件就能够更加纤细说明整个过程。php代码如下:
<?php
$host='liaojiafa.com;
$password="ljf.com" # 这个密码和我们在Nginx配置的一模一样
$expires=time()+300;
$uri="/download/test.rar";
print "http://".$host.$uri."?"."md5=".str_replace('=','',strtr(base64_encode(md5("$password$expires$uri",TRUE)),'+/', '-_'))."$expires=".$expires; #md5由密码,过期时间,URI等3部分组成,注意顺序和Nginx配置文件中完全一致。
?>
2. 使用Nginx中的X-Accel-Rediert控制头部
使用ngx_http_secure_link_module模块,可以满足大部分安全下载的需求。如果希望实现更精细化的控制(例如,验证用户的登陆状态),那么可使用X-Accel-Rediert控制头部。它的工作原理如下:Nginx把收到的下载请求发送到后端程序后,例如php或者java程序等,这些验证程序根据用户发过来的Cookie信息或者其他信息进行校验,如果成功,那么Nginx返回X-Accel-Rediert头部,通知Nginx向客户端输出静态文件;否则可以直接拒绝用户的非法请求。
假设URL是:http://liaojiafa.com/download.php?file=test.rar
那么刚才说了,校验动作是由验证程序来做的,所以我们这里看看PHP网页的伪代码:
<?php
function check() {
# 完成Cookie验证等
return 0;
}
$path = $_GET["file"];
header("Cache-Control: no-cache");
if(!check()){
header("X-Accel-Redirect: /download/" . $path);
}else {
header("X-Accel-Redirect: /download/error.txt");
}
?>
在Nginx配置文件的配置是:
location /download/ {
internal; # 该目录不允许客户端直接访问,仅仅可以由后端程序通过发送X-Accel-Redirect头部通知Nginx返回给用户。
}
使用CDN加速用户访问。
为了使用不同区域和运营商的用户都能够快速访问静态资源,使用CDN是一个很好的选择,使用CDN加速的时候,对静态站点的部署和用户的访问都是透明的。