通过Nginx服务器获取大文件MD5值的配置方法
http协议新增了content-md5 http头,但是nginx并不支持这个功能,而且官方也明确表示不会增加这项功能,为什么呢?因为每次请求都需要读取整个文件来计算md5值,以性能著称的nginx绝对不愿意干出违背软件宗旨的事情。但是有些应用中,需要验证文件的正确性,有些人通过下载当前文件,然后计算md5值来比对当前文件是否正确。不仅仅浪费带宽资源也浪费了大把的时间。有需求就有解决方案,网友开发了file-md5模块。
1. 下载模块file-md5
# cd /usr/local/src # wget https://github.com/cfsego/file-md5/archive/master.zip -o file-md5-master.zip # unzip file-md5-master.zip
2. 安装模块file-md5
# wget http://nginx.org/download/nginx-1.4.2.tar.gz # tar -xzf nginx-1.4.2.tar.gz # cd nginx-1.4.2 # ./configure --prefix=/usr/local/nginx-1.4.2 --add-module=../file-md5-master # make # make isntall
如果你已经安装了nginx,仅需要增加file-md5模块即可。
3. 配置file-md5
3.1 md5追加到http响应头中
server { listen 80; server_name test.ttlsa.com; root /data/site/test.ttlsa.com; # for add content-md5 to http header location ~ /download { add_header content-md5 $file_md5; } }
所有请求download的请求,都会在响应http头部增加content-md5,值为这个文件的md5,看如下测试:
# curl -i test.ttlsa.com/download/1.exe http/1.1 200 ok server: nginx date: wed, 26 feb 2014 03:00:05 gmt content-type: application/octet-stream content-length: 1535488 last-modified: mon, 24 feb 2014 10:08:10 gmt connection: keep-alive etag: "530b1a0a-176e00" content-md5: 6adda4a06dbad3ac9b53a08f4ff9c4f8 accept-ranges: bytes
大家可以看到content-md5: 6adda4a06dbad3ac9b53a08f4ff9c4f8,这个就是1.exe文件的md5值.
3.2 直接响应md5值到内容中
server { listen 80; server_name test.ttlsa.com; root /data/site/test.ttlsa.com; # for add content-md5 to http header location ~ /download { if ( $arg_md5 ~* "true" ){ echo $file_md5; } } }
这边直接使用echo输出md5值(echo模块需要额外安装),只需在下载的文件后面加上参数&md5=true即可得到md5值,使用过程中,参数可以随心定义。下面来测试一下。
# curl test.ttlsa.com/download/1.exe?md5=true 6adda4a06dbad3ac9b53a08f4ff9c4f8
直接得到md5值,与第一种方法得到同样的md5。
4. 最后
使用nginx模块也是一种方法,这种方法有个不足支持,每个请求都需要从新计算一次md5值。想减小他的压力,可以在nginx加缓存,或者借用memcache以及使用perl或者lua等模块,希望大家继续支持运维生存时间。
项目地址:https://github.com/cfsego/file-md5
项目文档:https://github.com/cfsego/file-md5/blob/master/readme
ps:nginx大文件下载优化
默认情况下proxy_max_temp_file_size值为1024mb,也就是说后端服务器的文件不大于1g都可以缓存到nginx代理硬盘中,如果超过1g,那么文件不缓存,而是直接中转发送给客户端.如果proxy_max_temp_file_size设置为0,表示不使用临时缓存。
在大文件的环境下,如果想启用临时缓存,那么可以修改配置,值改成你想要的。
修改nginx配置
location / { ... proxy_max_temp_file_size 2048m; ... }
重启nginx
# /usr/local/nginx-1.7.0/sbin/nginx -s reload