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

📅 2026/7/5 2:16:00
使用Mongodb存储上传物理文件并进行SQUID加速(基于aspx页面)
之前在阅读MongoDB GFS文档时学习了它如何存储物理文件包括大文件的方式。为了加深印象专门写了一个上传文件存储到Mongodb的示例。当然后因为是存储到文档数据库中所以就不能用普通方式来访问这些物理文件了这里又专门写了一个aspx页面专门读取这些文件比如图片或MP3等所以下载示例之后会看到两个页面一个是uploadfile.aspx(上传)一个是getfile.aspx从mongodb中把文件以流的方式读出来。当然考虑到访问速度这里还引入了SQUID来进行文件加速当前SQUID默认只缓存静态文件所以这里要对ASPX页面的输出进行一下设置这些都会在本文中进行介绍首先介绍一下开发环境我使用的是VS2008SP1 ,mongodb客户端软件用的是samus-mongodb最新版本即可添加对下面名空间的引用using MongoDB;using MongoDB.GridFS;下面是上传文件的主要代码uploadfile.aspx.csHttpPostedFile 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 \.htmlacl QUERY urlpath_regex cgi-bin \? \.php \.htmlcache 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 CACHEDacl 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-reloadrefresh_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文件均会进行缓存如下图