反向代理or后端nginx 生产用于缓存视频需要解决的问题
2017-03-23 13:54
169 查看
nginx proxy_cache 生产上需要解决的问题 http://blog.csdn.net/dengjiexian123/article/details/53386586 提出疑问:
到此,就完成了最基本的proxy_cache配置和访问过程介绍,但是最基本的配置,往往无法满足我们的业务需求,我们往往会提出以下几点疑问和需求:
需要主动清理缓存文件
写入路径为一块磁盘,如果磁盘打满该怎么解决?
如何让源站支持断点续传,以及断点续传的缓存策略
如果请求端 range 请求(分片下载)一个大资源,同样的uri,如何区别请求?
还需要告诉请求端,资源的过期时间
日志统计,如何配置命中与不命中字段,如何做统计?
问题一:主动清理缓存
采用:nginx proxy_cache_purge 模块 ,该模块与proxy_cache成对出现,功能正好相反。
设计方法:在nginx中,另启一个server,当需要清理响应资源的缓存时,在本机访问这个server。
例如:
访问 127.0.0.1:8083/tmp-test/TL39ef7ea6d8e8d48e87a30c43b8f75e30.txt 即可清理该资源的缓存文件。
1、将多块磁盘做磁盘阵列? 缺点是:减小了实际的存储空间。
2、巧妙得运用proxy_cache_path的目录结构,由于levels=1:2,这导致缓存文件的目录结构为两层,每层目录名,都是由hash函数生成
当缓存代理转发http请求到后端服务器时,http header会改变,header中的部分参数,会被取消掉。其中range参数被取消,导致,后端nginx服务器没有收到range参数,最终导致这个分片下载不成功。所以需要对代理转发的header进行配置。
location /tmp-test/ {
proxy_cache tmp-test;
proxy_cache_valid 200 206 304 301 302 10d;
proxy_cache_key $uri;
proxy_set_header Range $http_range;
proxy_pass http://127.0.0.1:8081/media_store.php/tmp-test/; }
红色部分的含义:将http请求中的range值($http_range)放到代理转发的http请求头中作为参数range的值。
由于nginx配置为:proxy_cache_key $uri,用uri作为key
所以当请求为普通请求和range请求时,都是同样的uri作为key。proxy_cache将有可能导致错误返回
解决方法如下:
修改proxy_cache_key ,配置proxy_cache_key $http_range$uri;
这样就能解决:key唯一性。可以避免不管是正常请求还是不同的range请求,第一次获取的内容和之后获取的缓存内容都不会出现异常
为了防止请求端将分片资源当做完整资源缓存起来,我们需要对正常请求,返回过期时间;对range请求, 不返回过期时间。
解决该问题,通过对nginx配置即可解决:
location /media_store.php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index media_store.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include fastcgi_params;
if ( $http_range = ''){
expires 2592000s;
}
}
在proxy_pass代理之后的location中加入对$http_range的判断,expires 表示过期时间。 2592000s指缓存过期时间。
利用nginx $upstream_cache_status变量:该变量代表缓存命中的状态,
如果命中,为HIT;如果未命中,为MISS
在返回nginx server配置中添加:
add_header Nginx-Cache "$upstream_cache_status";
在nginxlog中添加:
log_format combinedio …$upstream_cache_status;
http返回head截图:
nginx log日志截图:
到此,就完成了最基本的proxy_cache配置和访问过程介绍,但是最基本的配置,往往无法满足我们的业务需求,我们往往会提出以下几点疑问和需求:
需要主动清理缓存文件
写入路径为一块磁盘,如果磁盘打满该怎么解决?
如何让源站支持断点续传,以及断点续传的缓存策略
如果请求端 range 请求(分片下载)一个大资源,同样的uri,如何区别请求?
还需要告诉请求端,资源的过期时间
日志统计,如何配置命中与不命中字段,如何做统计?
问题一:主动清理缓存
采用:nginx proxy_cache_purge 模块 ,该模块与proxy_cache成对出现,功能正好相反。
设计方法:在nginx中,另启一个server,当需要清理响应资源的缓存时,在本机访问这个server。
例如:
访问 127.0.0.1:8083/tmp-test/TL39ef7ea6d8e8d48e87a30c43b8f75e30.txt 即可清理该资源的缓存文件。
问题二:缓存文件强磁盘打满该怎么办?
由于写入路径为一个单一目录,只能写入一块磁盘。一块磁盘很快就会被打满,解决该问题有如下两种方法:1、将多块磁盘做磁盘阵列? 缺点是:减小了实际的存储空间。
2、巧妙得运用proxy_cache_path的目录结构,由于levels=1:2,这导致缓存文件的目录结构为两层,每层目录名,都是由hash函数生成
问题三:支持range(断点续传)
当缓存代理转发http请求到后端服务器时,http header会改变,header中的部分参数,会被取消掉。其中range参数被取消,导致,后端nginx服务器没有收到range参数,最终导致这个分片下载不成功。所以需要对代理转发的header进行配置。
location /tmp-test/ {
proxy_cache tmp-test;
proxy_cache_valid 200 206 304 301 302 10d;
proxy_cache_key $uri;
proxy_set_header Range $http_range;
proxy_pass http://127.0.0.1:8081/media_store.php/tmp-test/; }
红色部分的含义:将http请求中的range值($http_range)放到代理转发的http请求头中作为参数range的值。
问题四,当支持range加载后,proxy_cache_key,则需要重新配置
如果请求端 Range请求(分片下载)一个大资源,同样的uri,proxy cache如何识别资源对应的key。由于nginx配置为:proxy_cache_key $uri,用uri作为key
所以当请求为普通请求和range请求时,都是同样的uri作为key。proxy_cache将有可能导致错误返回
解决方法如下:
修改proxy_cache_key ,配置proxy_cache_key $http_range$uri;
这样就能解决:key唯一性。可以避免不管是正常请求还是不同的range请求,第一次获取的内容和之后获取的缓存内容都不会出现异常
问题五:如何配置-返回过期时间
需要通过返回过期时间来指定请求端,哪些资源需要缓存,哪些资源不缓存,参数 | 正常请求 | range请求 |
返回过期时间 | 返回 | 不返回 |
解决该问题,通过对nginx配置即可解决:
location /media_store.php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index media_store.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include fastcgi_params;
if ( $http_range = ''){
expires 2592000s;
}
}
在proxy_pass代理之后的location中加入对$http_range的判断,expires 表示过期时间。 2592000s指缓存过期时间。
问题七:缓存命中情况如何在http头中体现,以及在nginx日志中查看
解决方法:利用nginx $upstream_cache_status变量:该变量代表缓存命中的状态,
如果命中,为HIT;如果未命中,为MISS
在返回nginx server配置中添加:
add_header Nginx-Cache "$upstream_cache_status";
在nginxlog中添加:
log_format combinedio …$upstream_cache_status;
http返回head截图:
nginx log日志截图:
总结:
整个一套完备的缓存策略就介绍到此,这套方案中不仅实现了基本的缓存配置,还解决了实际场景应用中会遇到的,磁盘扩展,缓存清理,断点续传,缓存过期时间,缓存命中提示等问题,只要将这套方案灵活运用,不管是再复杂的场景,基本都能满足需求。以上都是我在工作中爬过的坑,不断完善总结出的结果,希望对读者能有帮助。相关文章推荐
- 编写category时的便利宏(用于解决category方法从静态库中加载需要特别设置的问题)
- 【转载】----web网站css,js更新后客户浏览器缓存问题,需要刷新才能正常展示的解决办法
- 自己写的一个用于解决DateTimePicker的值无法为Null的控件.不过有问题.需要请各位帮忙看一下问题出在哪.
- 【转载】web网站css,js更新后客户浏览器缓存问题,需要刷新才能正常展示的解决办法
- web网站css,js更新后客户浏览器缓存问题,需要刷新才能正常展示的解决办法
- win7系统修复本地连接提示“windows无法完成修复问题,需要清除DNS缓存”的解决方法
- tp中save代码正确,无法执行问题,删除缓存试试.---根本的解决办法还需要思考
- web网站css,js更新后客户浏览器缓存问题,需要刷新才能正常展示的解决办法
- VS2012 webservice的创建并在iis上发布,发布完后解决“测试窗体只能用于来自本地计算机的请求.”问题视频教程
- web网站css,js更新后客户浏览器缓存问题,需要刷新才能正常展示的解决办法
- web网站css,js更新后客户浏览器缓存问题,需要刷新才能正常展示的解决办法
- Kodi - 设置视频缓存(解决局域网视频播放卡顿问题)
- 编写category时的便利宏(用于解决category方法从静态库中加载需要特别设置的问题)
- 如何解决在不同浏览器版本下播放视频的问题。
- 关于web页面缓存问题解决方法,如图片缓存,异步提交数据页面不更新
- 解决生产环境上日志报事务回滚的问题
- 解决ajax页面缓存的问题
- SVN利用post-commit hooks自动同步代码到生产环境,解决大数量文件更新同步问题
- 在编程的世界中,如何高效地学习理论知识,应用理论知识来解决实际生产中的问题
- jQuery.getJSON的缓存问题的解决办法