使用Mongodb存储上传物理文件并进行SQUID加速(基于aspx页面)

长平狐 发布于 2012/11/06 18:42
阅读 100
收藏 0

       之前在阅读MongoDB GFS文档时,学习了它如何存储物理文件(包括大文件)的方式。为了加深印象,专门写了一个上传文件存储到Mongodb的示例。当然后因为是存储到文档数据库中,所以就不能用普通方式来访问这些物理文件了,这里又专门写了一个aspx页面专门读取这些文件(比如图片或MP3等),所以下载示例之后会看到两个页面,一个是uploadfile.aspx(上传),一个是getfile.aspx(从mongodb中把文件以流的方式读出来)。当然考虑到访问速度,这里还引入了SQUID来进行文件加速(当前SQUID默认只缓存静态文件,所以这里要对ASPX页面的输出进行一下设置,这些都会在本文中进行介绍)

       首先介绍一下开发环境,我使用的是VS2008+SP1 ,mongodb客户端软件用的是samus-mongodb(最新版本即可)
   
       添加对下面名空间的引用
    

using  MongoDB;
using  MongoDB.GridFS;

 

    
    下面是上传文件的主要代码:uploadfile.aspx.cs    
     

     HttpPostedFile myFile  =  FileUpload.PostedFile;
     
int  nFileLen  =  myFile.ContentLength;
     
     
byte [] myData  =   new  Byte[nFileLen];
     myFile.InputStream.Read(myData, 
0 , nFileLen);
     
     GridFile fs 
=   new  GridFile(DB, filesystem);

     Random random 
=   new  Random( unchecked (( int )DateTime.Now.Ticks));
     
string  newfilename  =   string .Format( " {0}{1}{2} " , random.Next( 1000 99999 ), random.Next( 1000 99999 ), System.IO.Path.GetExtension(myFile.FileName));
     GridFileStream gfs 
=  fs.Create(newfilename);
     gfs.Write(myData, 
0 , nFileLen);
     gfs.Close();

 

    
      这里只是给上传文件起个随机名称,这样如果一切正常,就可以在数据库中找到该文件了,如下图:
    
          
    
      下面看一下如何访问上传的物理文件getfile.aspx.cs(通过传递filename参数,mongodb中相应字段结构,如上图):
    
     

      protected   void  Page_Load( object  sender, EventArgs e)
     {
         
if  ( ! string .IsNullOrEmpty(Request.QueryString[ " filename " ]))
         {
             
string  filename  =  Request.QueryString[ " filename " ];
             Init();
             String filesystem 
=   " gfstream " ;

             GridFile fs 
=   new  GridFile(DB, filesystem);
             GridFileStream gfs 
=  fs.OpenRead(filename);

             Byte[] buffer 
=   new  Byte[gfs.Length];

             HttpContext.Current.Response.AddHeader(
" Expires " , DateTime.Now.AddDays( 20 ).ToString( " r " ));
             HttpContext.Current.Response.AddHeader(
" Cache-Control " " public " );
      
             
//  需要读的数据长度
              long  dataToRead  =  gfs.Length;
             
int  length;
             
while  (dataToRead  >   0 )
             {
                 
//  检查客户端是否还处于连接状态
                  if  (HttpContext.Current.Response.IsClientConnected)
                 {
                     length 
=  gfs.Read(buffer,  0 10000 );
                     HttpContext.Current.Response.OutputStream.Write(buffer, 
0 , length);
                     HttpContext.Current.Response.Flush();
                     buffer 
=   new  Byte[ 10000 ];
                     dataToRead 
=  dataToRead  -  length;
                 }
                 
else
                 {
                     
//  如果不再连接则跳出死循环
                     dataToRead  =   - 1 ;
                 }
             }
             gfs.Dispose();
             HttpContext.Current.Response.End();
         }
     }

 

    
       下面就是以列表的方式从mongodb中检索文件列表的最终的运行效果:
    
       
    
       尽管MONGODB的并发性能很不错,但每次都去mongodb取的话也是有性能损耗的,特别是对于不经常变化的物理文件,所以这里
 使用了SQUID来进行文件缓存。当前SQUID默认只支持静态文件,对于本示例中的ASPX页面输出的流信息来缓存还要进行一下设置。    
    
      首先,如果在squid.conf文件中有如下行,需要用#进行注释(它会禁止缓存所有带?的链接地址):

 

 hierarchy_stoplist cgi-bin ? \.php \.html
 acl QUERY urlpath_regex cgi-bin \? \.php \.html   
 cache deny QUERY

  

        这样,再修改一下相应的.aspx,并在Header中添加如下信息,即:    
    

HttpContext.Current.Response.AddHeader( " Expires " , DateTime.Now.AddDays( 20 ).ToString( " r " ));
HttpContext.Current.Response.AddHeader(
" Cache-Control " " public " );

 

      

        这样SQUID就会忠实在根据该头信息来CACHED相应文件了。
   
        当然也可以用如下方式来让指定那些文件aspx文件才会被SQUID CACHED:   

    acl CACHABLE_PAGES urlpath_regex \getfile.aspx
    #允许cache上面的aspx页面
    no_cache allow CACHABLE_PAGES

 

    
        而下面一个acl匹配所有的动态页面并禁止缓存所有aspx页面
    

    #acl NONE_CACHABLE_PAGES urlpath_regex \? \.aspx   
    #禁止cache其它的aspx页面
    #no_cache deny NONE_CACHABLE_PAGES

 

    
    下面几行设置页面cache的时长,第一行cache一天,第二行cache两分钟
    

    refresh_pattern ^http://10.0.4.114:1100/mongodbsample/getfile.aspx 1440 0% 1440 ignore-reload
    refresh_pattern ^http://10.0.4.114:1100/mongodbsample/getfile.aspx 2 0% 2 ignore-reload

 

    
      如要SQUID配置正确的话,只要访问SQUID所请求代理的站点(本文中为http://10.0.4.85:8989/mongodbspame/uploadfile.aspx),
这里它就会到http://10.0.4.114:1100/mongodbspame/uploadfile.aspx去获取页面信息,同时对该页面中的链接getfile.aspx文件均会
进行缓存,如下图:


         

     

     好了,今天的内容就先到这里了,示例源码及SQUID配置文件下载链接:/Files/daizhj/mongodbsample.rar
    
     原文链接:http://www.cnblogs.com/daizhj/archive/2010/08/19/1803454.html
     BLOG: http://daizhj.cnblogs.com/
     作者:daizhj,代震军

   
   
   
   


原文链接:http://www.cnblogs.com/daizhj/archive/2010/08/19/1803454.html
加载中
返回顶部
顶部