ASP.NET使用IHttpModule实现网站静态缓存
来源:互联网 发布:js 禁止a标签跳转 编辑:程序博客网 时间:2024/05/22 02:13
需求:
一网站已开发完成,考虑SEO优化,用户体验,开发周期(节约成本)等等,网站使用伪静态技术。
初期运行可以,后期问题就出现了,由于网站访问量增大,出现CPU100%情况,严重影响用户访问,由于不是真静态,所以程序比较耗内存,CPU。
分析:
考虑网站真静态,可是如果要改原来的代码,会是一个很费力的问题,效率不高。
如何不改动原代码,实现网站静态化?
IHttpModule IHttpHandler 都可以实现。
实现:
网上查询很多资料,开始使用IHttpHandler 来实现
public class MyHandler : IHttpHandler { public bool IsReusable { get { return true; } } public void ProcessRequest(HttpContext context) { //处理代码 } }
//配置web.config 在httphandler节增加配置 <httpHandlers> <add verb="*" path="*" type="MyHandler"/> </httpHandlers>
可是发现handler 拦截用户请求后,无法在继续响应,只能使用response.writer来手动响应内容,如果将原页面手动输入,会出现版面混乱的问题,没有找到解决方案。
Google。发现IHttpModule 可以实现我想要的效果
using System;using System.Web;using System.Text.RegularExpressions;using System.IO;using System.Configuration;using System.Collections.Generic;namespace Product{ public class ProductModule : IHttpModule { public void Init(HttpApplication application) { application.BeginRequest += (new EventHandler(this.Application_BeginRequest));//请求开始 application.EndRequest += (new EventHandler(this.Application_EndRequest));//请求结束 } private void Application_BeginRequest(Object source, EventArgs e) { HttpApplication Application = (HttpApplication)source; CheckUrl(Application); } private void Application_EndRequest(Object source, EventArgs e) { //HttpApplication Application = (HttpApplication)source; //Application.Response.Write("test"); } private void CheckUrl(HttpApplication application) { if (application.Request.RequestType.ToUpper() == "POST" || application.Request.UserAgent.ToLower() == "product") { return; } string[] resUrlTemp = new string[5];//待缓存的请求模板 resUrlTemp[0] = "/model/modelsearch.aspx\\?clid=([\\d]+)&coid=([\\d]+)&bid=([\\d]+)&price=(.*)&model=(.*)&p=([\\d]+)&t=([0-2]{1,1})"; resUrlTemp[1] = "/pic/imgsearch.aspx\\?clid=([\\d]+)&cbid=([\\d]+)&model=(.*)&p=([\\d]+)"; resUrlTemp[2] = "/praise/PraiseSearch.aspx\\?clid=([\\d]+)&coid=([\\d]+)&model=(.*)&p=([\\d]+)"; resUrlTemp[3] = "/price/sellerpricesearch.aspx\\?clid=([\\d]+)&coid=([\\d]+)&brand=([\\d]+)&price=(.*)&model=(.*)&p=([\\d]+)&t=([0-2]{1,1})"; resUrlTemp[4] = "/dealer/sellersearch.aspx\\?pve=([\\d]+)&city=([\\d]+)&type=([\\d]+)&seller=(.*)&bid=([\\d]+)&model=(.*)&pagesize=([\\d]+)&p=([\\d]+)"; string reqUrl = application.Context.Request.Url.PathAndQuery.ToLower();//请求动态路径 bool success = false; for (int i = 0; i < resUrlTemp.Length;i++ ) { if (!success) { Regex reg = new Regex(resUrlTemp[i]);//匹配当前请求是否需要缓存 MatchCollection mc = reg.Matches(reqUrl); if (mc.Count > 0) { //静态页命名使用当前请求路径MD5加密命名 string PyReUrl = ConfigurationManager.ConnectionStrings["WebPhysicsUrl"].ConnectionString + "/Cache/" + i + "/" + System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(reqUrl, "MD5") + ".html"; FileInfo fi = new FileInfo(PyReUrl);//判断是否缓存 if (!fi.Exists) { //缓存页面 string WebUrl = ConfigurationManager.ConnectionStrings["WebUrl"].ConnectionString; System.Net.HttpWebRequest Request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(WebUrl + reqUrl);//Post请求当前页 Request.Method = "GET"; Request.Accept = "*/*"; Request.UserAgent = "Product"; Request.AllowAutoRedirect = true; Request.MaximumAutomaticRedirections = 2; System.Net.HttpWebResponse Response = null; try { Response = (System.Net.HttpWebResponse)Request.GetResponse();//获得响应 } catch(Exception ex) { application.Response.Write("Response Error"+ex.Message); } if (Response != null) { System.IO.Stream strm = Response.GetResponseStream(); System.IO.StreamReader sr = new System.IO.StreamReader(strm, System.Text.Encoding.GetEncoding("gb2312")); StreamWriter Sw = null; try { if (!Directory.Exists(Directory.GetParent(PyReUrl).FullName)) Directory.CreateDirectory(Directory.GetParent(PyReUrl).FullName); FileStream Fs = new FileStream(PyReUrl, FileMode.Create, FileAccess.Write, FileShare.Read); Sw = new StreamWriter(Fs, System.Text.Encoding.Default, 512); Sw.Write(sr.ReadToEnd());//写入 success = true; } catch(Exception ex) { Sw.Close(); application.Response.Write("Writer Error"+ex.Message); } sr.Close(); Sw.Close(); Response.Close(); } } else { //application.Response.Redirect(PyReUrl);//链接到静态页面 浏览器请求路径不变,不会影响收录 application.Server.Transfer("/Cache/" + i + "/" + System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(reqUrl, "MD5") + ".html"); } } } } } public void Dispose() { } }}
//webcongif配置文件<httpModules><add name="ProductModules" type="Product.ProductModule"/></httpModules>
实现思路:
当用户发出请求后,IIS接到请求,伪静态解析得到动态请求路径,IHttpModule拦截到动态请求路径,正则匹配,查看当前请求路径是否静态缓存
1.不需要缓存。不处理,继续响应用户请求。
2.需要缓存。判断缓存是否存在
(1.存在,将缓存响应给用户。
(2.不存在,缓存当前请求。继续响应用户请求。
总体来说,第一次访问页面的人响应时间比较长,当缓存文件保存后,后续用户访问直接访问缓存内容,大大降低了服务器的压力,响应速度也更快。
当网站内容需要更新时,只需要删除缓存文件即可。
注意,并不是所有页面都可以缓存,因为你的页面可能有些需要页面回传,如果生成静态页,回传就失效了。
由于鄙人开发此网站前考虑都以后可能会使用静态,所有请求都是使用ajax实现,级联等效果也是ajax实现,并无页面回发,所以改起来很方便。
只需添加一个IHttpModule文件,改一下配置文件即可。
有对此感兴趣,有不懂的可以问我,乐意为大家解决问题。
生产缓存文件如下:
- ASP.NET使用IHttpModule实现网站静态缓存
- ASP.NET通过IHttpModule实现伪静态
- ASP.NET中用IHttpModule接口实现伪静态
- ASP.NET中用IHttpModule接口实现伪静态
- asp.net IHttpModule实现权限控制
- 在ASP.NET上使用IHttpModule进行整体控制
- asp.net HttpModule与IHttpModule
- ASP.NET MVC用IHttpModule修改response的html实现压缩或者转繁体,IHttpModule用后台代码注册
- asp.net网站url伪静态重写技术的实现
- asp.net网站url伪静态重写技术的实现
- ASP.net演练:使用输出缓存增强网站性能
- ASP.NET MVC 3 网站优化总结(四)使用缓存
- asp.net网站静态化
- asp.net 缓存使用
- ASP.NET页面如何建立静态缓存
- ASP.NET Core缓存静态资源
- Asp.net使用异步缓存方法实现页面及时更新
- asp.net网站安全之————iHttpModule判断当前页面session是否为空(1)
- 不能从const char *转换为LPCWSTR 经常碰到
- 读书笔记:少有人走的路
- S3C2440驱动篇—Linux平台设备驱动
- WebSite和WebApplicationd的区别
- rails 3总出现 axconfig port1 not active
- ASP.NET使用IHttpModule实现网站静态缓存
- SVN小记
- CSS IE6/7/8, Firefox, Safari, Chrome, Opera Hack使用简要归纳
- Socket编程keepalive
- 软件项目经理必备素质
- Activity练习 一 关于Activity A的启动Activity B的过程
- windows socket api
- Neodynamic Barcode Professional for .NET Windows Forms
- 第八章:【UCHome二次开发】模板页面说明