之前写过“Nginx+Lighttpd+Tomcat,访问MogileFS中的文件”,嗯,问题是能解决,但比较复杂,而且高手说效率极底,不可取。当时的方法很笨,在数据库中把文件的物理地址直接就存起来了,而且只存一个,这样导致一个文件一辈子只能从一个地址去取,太不合理。后来也想过将所有的地址都存起来,每次访问随机拿一个,但这只会导致问题更复杂。

后来仔细地看了MogileFS的java API,发现人家提供了直接通过key来取path的方法,心想这样就简单了,我得到一组path ,随机取一个返回。只要写一个专门的程序用来处理图片请求就可以了。于是按照这个方法开始实践。

然后无意间找到了有一个叫Nginx mogilefs module (v 1.0.2)的好东东,它是nginx的MogileFS客户端(MogileFS client for nginx web server)。有了它,只需在nginx中配置MogileFS 的tracker和domain以及其他属性,在需要访问MogileFS中的文件时,它将根据传递过来的参数作为key,访问MogileFS并返回tracker返回给它的第一个文件地址(有人说它总返回第一个存储的地址,但我觉得返回的应该是做了负载均衡计算后的结果,有待验证)。这使得我之前对于访问MogileFS中文件的解决方案得到了极大的简化,不需要访问数据库(当然Nginx mogilefs module在取得文件地址时肯定会有一次数据交互),不需要另起专门的程序或服务来处理文件请求,简单,好用。

下载地址:http://github.com/vkholodkov/nginx-mogilefs-module/tree/master

感谢Sunshow同学帮我翻墙下载,不过MS上面这个地址不要翻。

从头梳理一遍:

图片URL的形式

  1. http://127.0.0.1/lvto/phpto/$pickey/$pictype

如:

  1. http://127.0.0.1/lvto/photo/ff80818122ca754d0122ca7648180002/small

URL的形式完全自己定,只要能通过URL标识体现出文件的key就可以了。我以前用了picid,userid,pickey三个参数,到后台去定位key的方法实在是太笨了,所以这次决定简化。

在此之前通过JMagick为图片生成了各种尺寸,存储到MogileFS,将图片相关的信息存储到数据库中。在MogileFS中以$pickey$pictype作为图片的key(注意中间没有 / )。如:ff80818122ca754d0122ca7648180002small是一个图片的key。

首先通过lighttpd的rewrite模块,把$pickey/$pictype重写成$pickey$pictype的形式

  1. url.rewrite-once = (
  2.     "^/lvto/photo/(.*)/(.*)" => "/lvto/photo/$1$2"
  3. )

然后通过lighttpd的proxy模块将对于图片的访问全部proxy到nginx处理,nginx的port是88。

  1. $HTTP["url"] =~ "^/lvto/photo/" {
  2.     proxy.server = ("" =>
  3.         (
  4.             ("host" => "127.0.0.1" , "port" => 88)
  5.         )
  6.     )
  7. }

在nginx中关于Nginx mogilefs module的具体配置:

  1. location /lvto/photo/ {
  2.             mogilefs_tracker 127.0.0.1:6001;
  3.         mogilefs_domain testdomain;
  4.         mogilefs_methods get;
  5.             mogilefs_pass {
  6.                 proxy_pass $mogilefs_path;
  7.                 proxy_hide_header Content-Type;
  8.                 proxy_buffering off;
  9.             }
  10.         }

搞定~