版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tomnic_ylwang/article/details/47343161
先认识几个nignx内置变量:
$request_uri:则是请求的整个字符串,包含了后面的query_string的;
$remote_addr:则是发送下载请求的主机ip;
$body_bytes_sent
:传送页面的字节数
认识几个nignx指令:
post_action
:当主请求完成后,进行的请求。
internal:指令指定某个location只能被“内部的”请求调用,外部的调用请求会返回”Not
found” (404)
“内部的”是指下列类型:
“内部的”是指下列类型:
proxy_pass:转发请求
ngnix配置:
location /predownload/{
rewrite ^/predownload/(.*)$ /download/$1 redirect; post_action @before; } location /download/ { alias /data/storage/android/; default_type application/octet-stream; autoindex_exact_size off; autoindex_localtime on; post_action @after; } location @before{ proxy_pass http://www.henaizhangli.cn/download/predownload?fileName=$request_uri&clientIp=$remote_addr; internal; } location @after{ proxy_pass http://http://www.henaizhangli.cn/download/downloaded?fileName=$request_uri&clientIp=$remote_addr&bytes=$body_bytes_sent; internal;
} |
单线程下载:
1、向ngnix发送请求http://www.staticdownload.cn/predownload/imooc.apk?adId=1426
2、定向到“location /predownload/“,根据配置现转发到 ”location /download/
“与客户端建立下载链接,开始下载
3、执行post_action,转发到”location @before“,发送请求到后台,统计下载点击量
4、下载完成后,发送请求到server附带上请求的参数,以及下载的字节数到后台进行下载完成量的校验
多线程下载:
多线程下载的情况下,单线程下载完成的统计方案不适用。
1、向ngnix发送请求http://www.staticdownload.cn/predownload/imooc.apk?adId=1426
2、定向到“location /predownload/“,根据配置现转发到 ”location /download/ “与客户端建立下载链接,浏览器进行多线程下载,重新发送多个请求,HTTP头增加了一个Range字段,下载开始
3、执行post_action,转发到”location @before“,发送请求到后台,统计下载点击量
4、下载完成后,发送请求到server附带上请求的参数,server取请求中的Range参数,进行分析
浏览器多线程下载的,实际上是把文件分成多个部分进行分段下载,分段后Http头里有一个Range字段
如下:
若下载一个12826743个字节的文件,随机可能会出现;
Range: bytes=0-
Range: bytes==4301545-8551161
Range: bytes==4301545-8551161
Range: bytes==8551162-12826742
后台server获取
String range=request.getHeader("Range");
最后通过比较bytes与文件实际大小进行比较,达到统计下载完成量的目的;
本方法也有缺陷,若是Range: bytes==8551162-12826742这个线程先下载完成,下载完成量会增加,但是若其余线程下载还未完成,那么此时用户若是取消了下载,那么就会造成统计结果不准确。