zoukankan      html  css  js  c++  java
  • 使用Mongodb存储上传物理文件并进行SQUID加速(基于aspx页面)

           之前在阅读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(100099999), random.Next(100099999), 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, 010000);
                         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,代震军

       
       
       
       

  • 相关阅读:
    PHP中的数据库一、MySQL优化策略综述
    LINUX下的PHP
    JS实现别踩白块小游戏
    网页实时聊天之js和jQuery实现ajax长轮询
    PHP用mb_string函数库处理与windows相关中文字符
    PHP正则中的捕获组与非捕获组
    PHP递归创建多级目录(一道面试题的解题过程)
    PHP模拟发送POST请求之五curl基本使用和多线程优化
    PHP模拟发送POST请求之四、加强file_get_contents()发送POST请求
    PHP模拟发送POST请求之三、用Telnet和fsockopen()模拟发送POST信息
  • 原文地址:https://www.cnblogs.com/daizhj/p/1803454.html
Copyright © 2011-2022 走看看