开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 2508|回复: 2
打印 上一主题 下一主题
收起左侧

[其它数据库例题] 详解MongoDB实现存储物理文件和SQUID加速

[复制链接]

结帖率:61% (35/57)
跳转到指定楼层
楼主
发表于 2013-2-2 19:26:10 | 只看该作者 回帖奖励 |正序浏览 |阅读模式   海南省海口市
前在阅读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

结帖率:37% (7/19)
板凳
发表于 2013-2-10 16:53:55 | 只看该作者   北京市北京市
这个只能板凳了
回复 支持 反对

使用道具 举报

结帖率:0% (0/1)
沙发
发表于 2013-2-2 19:59:28 | 只看该作者   北京市北京市
好强大呀。。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:[email protected]
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表