上篇日志中写到的访问MogileFS文件的方法不太好,原因是把要访问的图片写到response中,这样做法比较笨,而且通过测试发现,写过来的图片显示的时候有问题,经常是上半部分正常,而下半部分变得乱掉了。在以前的应用中有过类似的写法,在多次刷新页面的时候会出现response的out被重置的情况,导致图片显示不出来。

所以还是直接访问文件在MogileFS的物理存储位置比较靠谱。和雷明同学研究了一下YuPoo图片地址和架构,大致确定的自己的图片地址写法:

http://localhost/lvto/pics/[username]/[picid]/[pictype]

其中:username代表了图片上传的用户名或标识

picid:图片的唯一标识

pictype:图片的类型,可能是缩略图(thumb),方图(square)等等。

具体来说,在页面上引用一个图片时,地址会是这样:

http://localhost/lvto/pics/xyn0563/1234abcd/thumb/

而且通过MogileFS对它进行直接访问的地址是:

http://localhost:7500/dev1/0/000/000/0000000014.fid

现在的工作就是要如何将引用地址指向实际的物理地址。

1.编写一个Action,picture/picutreRedirector.do,其作用是通过username,picid,pictype等参数,到数据库中查询,得到文件在MogileFS中的存储位置(path),然后调用

response.sendRedirect(path)

跳转到该位置。

如访问http://localhost:8080/lvto/picture/pictureRedirector.do?username=xyn0563&picid=1234abcd&pictype=thumb,得到的存储位置是:

dev1/0/000/000/0000000014.fid,然后跳转这个地址。

2.配置Nginx,使对于图片的请求全都转发到刚才写的Action。

nginx.conf 中:

  1. #访问图片的代理
  2.     location /lvto/pics {       
  3.         rewrite ^/lvto/pics/(.*)/(.*)/(.*)/    /lvto/picture/pictureRedirector.do?username=$1&picid=$2&pictype=$3 break;
  4.             proxy_pass http://127.0.0.1:81;
  5.     }

其中的81端口起的是 Lighttpd,它的作用是将*.jsp,*.do都交由tomcat处理。

这样一来通过

http://localhost/lvto/pics/xyn0563/1234abcd/thumb/

访问的地址都经跳转到了

http://localhost/dev1/0/000/000/0000000014.fid

我的Nginx用的是80端口。

3.配置另外一个 Lighttpd,当然其他的web服务,比如Apache也可以,把它的documentroot直接指向Mogstored的存储位置。如,在我的Lighttpd中是这样的:

  1. server.document-root = "/usr/local/mogdata"
  2. #其他配置......
  3. server.port  = 83

根据以上位置,通过以下地址一样可以访问MogileFS中的文件:

  1. http://127.0.0.1:83/dev1/0/000/000/0000000014.fid

4.最后一步,即把第2步最后得到的地址再转向第3步的地址。这时又要用到Nginx。配置如下:

  1. location /dev1 {                
  2.         include    /usr/local/nginx/conf/proxy.conf;         
  3.             proxy_pass http://127.0.0.1:83;
  4.     }

这样就实现了最终的目标,通过类似http://localhost/lvto/pics/xyn0563/1234abcd/thumb/的地址访问到具体的图片。

感觉比之前的方法好了许多,在与服务器交互过后不需要向response里写入图片数据,而只是得到图片的存储地址进行跳转即可。但是还是有些问题的:

1.图片的物理地址需要与数据库交互。每访问一个图片交互一次。在访问量大的情况会导致数据库压力增加。解决办法是使用memcached作数据库查询结果的缓存。这个回头再研究。

2.这个问题在别人的文章里也提到过。就是如果在MogileFS上多加一个device,比如多了个dev2,那么在nginx中就要针对dev2增加一条配置信息。

最后还有一个始终弄不明白的问题。对于以上的方法,图片在MogileFS中的存储位置在保存时就返回过来,保存到了数据库。如,保存到了dev1,数据库里记录的就是dev1,今后所有的访问都是到dev1里面去找。但是后来加上的dev2和dev1之间做了备份,意思是其实通过dev2这台mogstored也可以访问到这个图片。

由于是通过物理地址直接访问,这样的话在dev1负载很大的情况下就没办法通过dev2进行负载平衡了。那MogileFS所说的负载平衡是啥个意思啊,难道说只是在文件存储的时候有作用?还是说我了解的不够,其实是有办法做到的?

想来想去应该还是在那个Action里面,我设想的是应该可以通过某种方法,调用 MogileFS 的Api动态地决定访问dev1还是dev2。看Yupoo的架构图,感觉它的YPWS就是做这个东东的。

继续学习中。。。