IT技术博客大学习 共学习 共进步

当使用 Nginx 做 Hash 时对动态文件和静态文件的处理

扶凯 2010-08-02 22:59:10 浏览 4,123 次

nginx 做 url 的 hash 时,做动态和静态的 hash 时需要多多注意。因为动态和静态的文件表现出来的不一样。

静态文件 Nginx 的 Hash 处理
静态的文件的源网站的,特点文件静态,大小基本是几种类型的大小,每个节点存的文件,大多不一样,基本img1,img2,img3.这三个节点存的不一样的文件。
如下:

http://mp4.php-oa.com/index/8277e0910d750195b448797616e091ad.mp4?key=92eb5ffee6ae2fec3ad71c777531578f
http://flv.php-oa.com/home/4a8a08f09d37b73795649038408b5f33.flv?key=92eb5ffee6ae2fec3ad71c777531578f
http://f4v.php-oa.com/user/0cc175b9c0f1b6a831c399e269772661.f4v?key=92eb5ffee6ae2fec3ad71c777531578f

静态文件,这样设计不只为了能处理更多请求,还为了存储的可扩展。
所以针对这二种文件,在 Url 中做 Url 的 hash 时, nginx 要分别处理,因为为了防盗链之类的原因,还有存储的原因。不能给 key 计算到整个 nginx 的 hash 的算法中。当给整个 Url 加入到 Hash 的算法中时,因为 key 是变化的内容。下次 key 变化后,你 Nginx 重向的服务器就发生了变化,这样当然是不可取的。
所以在静态文件中,建议 Nginx 的 Hash 的算法修改为 

hash $uri; # uri 为 Nginx 的内部变量,表示没有 ? 的 url.

这样,防盗链之类的算法怎么改变,都不会影响到 Nginx 的重定向.

动态文件 Nginx 的 Hash 处理

但动态的,所有服务器,大多是所有服务器可以处理所有动态的内容,基本没有主从之分,这主要是为了可以处理更加多的请求。
http://web2.php-oa.com/index.php?search=12
http://web1.php-oa.com/index.php?search=12
所以这种的时候,nginx 建议设置成

hash $request_uri; # request_uri 为 Nginx 的内部变量,表示有 ? 的 url.

当这样设置时,同样的请求,可以被平均分到多台后端的服务器。更加方便动态文件的处理。

其它情况 Nginx 的 Hash 处理

在静态文件时,还有一种变化的防盗链的算法。如下。

http://mp4.php-oa.com/92eb5ffee6ae2fec3ad71c777531578f/index/8277e0910d750195b448797616e091ad.mp4
http://flv.php-oa.com/92eb5ffee6ae2fec3ad71c777531578f/home/4a8a08f09d37b73795649038408b5f33.flv
http://f4v.php-oa.com/92eb5ffee6ae2fec3ad71c777531578f/user/0cc175b9c0f1b6a831c399e269772661.f4v

在这种情况下,发现防盗链的算法的 key 内容是直接放到 Url 中的第一个部分的。这样处理起来就有点麻烦,因为 request_uri 和 uri 都是不能正常生成好用的 Hash 结果来用的。
这只能使用变态点的方法.如下

server
{
    listen 80;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    if ($uri ~* "\/([^\/]+)$" ){
        set $filename $1;
    }
    location /
    {
        proxy_pass http://default;
    }
}
 
upstream default
{
    hash $filename;
    server 121.xx.xxx.1;# node1
    server 121.xx.xxx.2;# node2
    server 121.xx.xxx.3;# node3
}

这个时候 ,我使用标准的 Perl 的正则,来取得最后一个 / 后的文件名。如上面的 0cc175b9c0f1b6a831c399e269772661.f4v。 然后我对这个文件名来做 hash .
这样,无论中间的防盗链的 key 怎么修改,我都能正常使用。
在 nginx 中的 set 的功能相当好用,可以定制自己要的变量内容。给这个自定的 $filename 变量,交给 Hash 算法来计算。

建议继续学习

  1. 配置Nginx+uwsgi更方便地部署python应用 (阅读 106,824)
  2. 搜狐闪电邮箱的 Nginx/Postfix 使用模式 (阅读 33,762)
  3. 解析nginx负载均衡 (阅读 16,422)
  4. HashMap解决hash冲突的方法 (阅读 12,463)
  5. 关于memcache分布式一致性hash (阅读 11,661)
  6. Nginx模块开发入门 (阅读 11,041)
  7. 检查nginx配置,重载配置以及重启的方法 (阅读 10,683)
  8. Cacti 添加 Nginx 监控 (阅读 10,362)
  9. Nginx+FastCgi+Php 的工作机制 (阅读 10,084)
  10. 奇怪的 Nginx 的 upstream timed out 引起响应 502 (阅读 9,823)