利用HttpHandler和Cache统计点击量
因为访问量大,做页面浏览量的时候不能直接操作库;用文件来记录的话,虽然减缓了数据库的压力但是对服务器I/O却是一个考验;而缓存正是.Net的一大优势,所以想出HttpHandler结合Cache来减缓I/O操作,这样I/O跟数据库的压力都解决了!
首先创建统计类库
1.创建CounterHelper统计类
2.创建HttpHandler
生成dll后创建一个Website,然后把dll引用进来!
接着在web.config里面添加配置:
<httpHandlers>
<add verb="*" path="count.aspx" type="MYSpace.Counter.CounterHandler,MYSpace.Counter" />
</httpHandlers>
最后在web页面调用就ok了。页面代码如下:
首先创建统计类库
1.创建CounterHelper统计类
1using System;
2using System.Web;
3using System.Web.Caching;
4using System.Collections.Specialized;
5using System.Data;
6using System.Data.SqlClient;
7using System.Configuration;
8using System.Text;
9using System.IO;
10
11namespace MYSpace.Counter
12{
13 /// <summary>
14 /// Counter 的摘要说明。
15 /// </summary>
16 public class CounterHelper
17 {
18 private int _Hits = 0; //累计的点击数
19 private string _FileName = "";
20 private string FilePth = string.Empty;
21 private string ErrorLogFilePth = string.Empty;
22 private int[] HitsArr = {-1,0,0}; //HitsArr[0]表示总的点击数HitsArr标识昨天的点击数HitsArr表示今天的点击数
23 CacheItemRemovedCallback onRemove = null;//CacheItemRemovedCallback对象
24 private string CacheName = "UpdateHitsForExpired";//缓存名称
25 private object LockForAddHits = new object();//LockForAddHits锁
26 private object LockForItemRemovedFromCacheHits = new object();//ItemRemovedFromCacheHits锁
27
28 /// <summary>
29 /// 构造函数
30 /// </summary>
31 public CounterHelper(string filename)
32 {
33 _FileName = filename;
34 CacheName = filename;
35 HttpContext ctx = HttpContext.Current;
36 FilePth = ctx.Server.MapPath("~/" + _FileName + ".txt");
37 ErrorLogFilePth = ctx.Server.MapPath("~/" + _FileName + ".txt");
38 LoadHits();
39 }
40
41 /// <summary>
42 /// 将累计点击数保存到全局变量,当它达到一定量时保存到文本文件,并清空
43 /// </summary>
44 public void AddHits()
45 {
46 lock(LockForAddHits)
47 {
48 if( Hits != 0 )
49 {
50 Add();
51 if(Hits > 200 )
52 {
53 //--移除
54 HttpRuntime.Cache.Remove(CacheName);
55 }
56 }
57 else
58 {
59 onRemove = new CacheItemRemovedCallback(ItemRemovedFromCache);
60 HttpRuntime.Cache.Insert(
61 CacheName,
62 "This Object For Expired",
63 null,
64 DateTime.Now.AddSeconds(5) ,
65 TimeSpan.Zero,
66 System.Web.Caching.CacheItemPriority.Normal,
67 onRemove
68 );
69 Add();
70 }
71 }
72 }
73
74 /// <summary>
75 /// 保存到文本文件
76 /// </summary>
77 /// <param name="AllId"></param>
78 private void SaveHitsToFile(int hits)
79 {
80 string hitsinfo = string.Empty;
81
82 DateTime LastWriteTime = File.GetLastWriteTime(FilePth);
83 if((DateTime.Today - LastWriteTime).TotalDays >0 )
84 {
85 //--表示今天第一次写数据
86 HitsArr[1] = HitsArr[2];//--将当前累计的点击数赋给昨天的点击数
87 HitsArr[2] = hits;//--设置今天的点击数
88 using(StreamWriter streamWriter = new StreamWriter(FilePth,false) )
89 {
90 streamWriter.Write(string.Format("{0},{1},{2}",HitsArr[0] + hits,HitsArr[1] ,hits));
91 streamWriter.Flush();
92 }
93 }
94 else
95 {
96 using(StreamWriter streamWriter = new StreamWriter(FilePth,false) )
97 {
98 streamWriter.Write(string.Format("{0},{1},{2}",HitsArr[0] + hits,HitsArr[1],HitsArr[2] + hits));
99 streamWriter.Flush();
100 }
101 }
102 }
103
104 /// <summary>
105 /// 当缓存被移除或过期是触发的回调事件
106 /// </summary>
107 /// <param name="key"></param>
108 /// <param name="value"></param>
109 /// <param name="reason"></param>
110 private void ItemRemovedFromCache(string key, object value,CacheItemRemovedReason reason)
111 {
112 try
113 {
114 清空并写到文本文件
132 }
133 catch(Exception ex)
134 {
135 using(StreamWriter streamWriter = new StreamWriter(ErrorLogFilePth,false) )
136 {
137 streamWriter.Write(string.Format("时间:{0}\r\n描述信息:{1}\r\n",DateTime.Now,ex.Message));
138 streamWriter.Flush();
139 }
140 }
141 }
142
143 /// <summary>
144 /// 获取所有的点击数
145 /// </summary>
146 public int AllHits
147 {
148 get
149 {
150 return HitsArr[0] + Hits;
151 }
152 }
153
154 /// <summary>
155 /// 获取昨天点击数
156 /// </summary>
157 public int YesterdayHits
158 {
159 get
160 {
161 return HitsArr[1];
162 }
163 }
164
165 /// <summary>
166 /// 获取今天点击数
167 /// </summary>
168 public int TodayHits
169 {
170 get
171 {
172 return HitsArr[2] + Hits;
173 }
174 }
175
176 /// <summary>
177 /// 加载点击数
178 /// </summary>
179 private void LoadHits()
180 {
181 if (HttpRuntime.Cache[CacheName] == null)
182 {
183 HttpContext ctx = HttpContext.Current;
184 if (!File.Exists(FilePth))
185 {
186 //--第一次使用
187 using (StreamWriter streamWriter = new StreamWriter(FilePth))
188 {
189 streamWriter.Write(string.Format("{0},{1},{2}", 0, 0, 0));
190 streamWriter.Flush();
191 }
192 HitsArr[0] = 0;
193 HitsArr[1] = 0;
194 HitsArr[2] = 0;
195 }
196 else
197 {
198 string hitsinfo = string.Empty;
199 using (StreamReader objStreamReader = new StreamReader(FilePth))
200 {
201 hitsinfo = objStreamReader.ReadLine();
202 }
203 if (hitsinfo != "")
204 {
205 string[] arr = hitsinfo.Split(',');
206 HitsArr[0] = Convert.ToInt32(arr[0]);//全部
207 HitsArr[1] = Convert.ToInt32(arr[1]);//昨天
208 HitsArr[2] = Convert.ToInt32(arr[2]);//今天
209 }
210 else
211 {
212 HitsArr[0] = 0;
213 HitsArr[1] = 0;
214 HitsArr[2] = 0;
215 }
216 }
217 HttpRuntime.Cache["b" + CacheName] = HitsArr;
218 }
219 else
220 {
221 HitsArr = (int[])HttpRuntime.Cache["b" + CacheName];
222 //HitsArr[0] += 1;
223 //HitsArr[2] += 1;
224
225 }
226 }
227
228
229 /// <summary>
230 /// 获取累计的点击数
231 /// </summary>
232 private int Hits
233 {
234 get
235 {
236 return _Hits;
237 }
238 set
239 {
240 _Hits = value;
241 }
242 }
243
244 /// <summary>
245 /// 累加
246 /// </summary>
247 /// <param name="id"></param>
248 private void Add()
249 {
250 if(HitsArr[2]<14000)
251 {
252 //_Hits = _Hits + new Random(DateTime.Now.Second).Next(60,80);
253 _Hits = _Hits + 1;
254 }
255 else
256 {
257 _Hits = _Hits + 1;//_Hits = _Hits + new Random(DateTime.Now.Second).Next(2,8); 传回指定范围的随机数
258 }
259 }
260 /// <summary>
261 /// 文件名
262 /// </summary>
263
264 /// <summary>
265 /// 获取文件名
266 /// </summary>
267 public string FileName
268 {
269 get { return _FileName; }
270 set { _FileName = value; }
271 }
272 }
273}
274
2using System.Web;
3using System.Web.Caching;
4using System.Collections.Specialized;
5using System.Data;
6using System.Data.SqlClient;
7using System.Configuration;
8using System.Text;
9using System.IO;
10
11namespace MYSpace.Counter
12{
13 /// <summary>
14 /// Counter 的摘要说明。
15 /// </summary>
16 public class CounterHelper
17 {
18 private int _Hits = 0; //累计的点击数
19 private string _FileName = "";
20 private string FilePth = string.Empty;
21 private string ErrorLogFilePth = string.Empty;
22 private int[] HitsArr = {-1,0,0}; //HitsArr[0]表示总的点击数HitsArr标识昨天的点击数HitsArr表示今天的点击数
23 CacheItemRemovedCallback onRemove = null;//CacheItemRemovedCallback对象
24 private string CacheName = "UpdateHitsForExpired";//缓存名称
25 private object LockForAddHits = new object();//LockForAddHits锁
26 private object LockForItemRemovedFromCacheHits = new object();//ItemRemovedFromCacheHits锁
27
28 /// <summary>
29 /// 构造函数
30 /// </summary>
31 public CounterHelper(string filename)
32 {
33 _FileName = filename;
34 CacheName = filename;
35 HttpContext ctx = HttpContext.Current;
36 FilePth = ctx.Server.MapPath("~/" + _FileName + ".txt");
37 ErrorLogFilePth = ctx.Server.MapPath("~/" + _FileName + ".txt");
38 LoadHits();
39 }
40
41 /// <summary>
42 /// 将累计点击数保存到全局变量,当它达到一定量时保存到文本文件,并清空
43 /// </summary>
44 public void AddHits()
45 {
46 lock(LockForAddHits)
47 {
48 if( Hits != 0 )
49 {
50 Add();
51 if(Hits > 200 )
52 {
53 //--移除
54 HttpRuntime.Cache.Remove(CacheName);
55 }
56 }
57 else
58 {
59 onRemove = new CacheItemRemovedCallback(ItemRemovedFromCache);
60 HttpRuntime.Cache.Insert(
61 CacheName,
62 "This Object For Expired",
63 null,
64 DateTime.Now.AddSeconds(5) ,
65 TimeSpan.Zero,
66 System.Web.Caching.CacheItemPriority.Normal,
67 onRemove
68 );
69 Add();
70 }
71 }
72 }
73
74 /// <summary>
75 /// 保存到文本文件
76 /// </summary>
77 /// <param name="AllId"></param>
78 private void SaveHitsToFile(int hits)
79 {
80 string hitsinfo = string.Empty;
81
82 DateTime LastWriteTime = File.GetLastWriteTime(FilePth);
83 if((DateTime.Today - LastWriteTime).TotalDays >0 )
84 {
85 //--表示今天第一次写数据
86 HitsArr[1] = HitsArr[2];//--将当前累计的点击数赋给昨天的点击数
87 HitsArr[2] = hits;//--设置今天的点击数
88 using(StreamWriter streamWriter = new StreamWriter(FilePth,false) )
89 {
90 streamWriter.Write(string.Format("{0},{1},{2}",HitsArr[0] + hits,HitsArr[1] ,hits));
91 streamWriter.Flush();
92 }
93 }
94 else
95 {
96 using(StreamWriter streamWriter = new StreamWriter(FilePth,false) )
97 {
98 streamWriter.Write(string.Format("{0},{1},{2}",HitsArr[0] + hits,HitsArr[1],HitsArr[2] + hits));
99 streamWriter.Flush();
100 }
101 }
102 }
103
104 /// <summary>
105 /// 当缓存被移除或过期是触发的回调事件
106 /// </summary>
107 /// <param name="key"></param>
108 /// <param name="value"></param>
109 /// <param name="reason"></param>
110 private void ItemRemovedFromCache(string key, object value,CacheItemRemovedReason reason)
111 {
112 try
113 {
114 清空并写到文本文件
132 }
133 catch(Exception ex)
134 {
135 using(StreamWriter streamWriter = new StreamWriter(ErrorLogFilePth,false) )
136 {
137 streamWriter.Write(string.Format("时间:{0}\r\n描述信息:{1}\r\n",DateTime.Now,ex.Message));
138 streamWriter.Flush();
139 }
140 }
141 }
142
143 /// <summary>
144 /// 获取所有的点击数
145 /// </summary>
146 public int AllHits
147 {
148 get
149 {
150 return HitsArr[0] + Hits;
151 }
152 }
153
154 /// <summary>
155 /// 获取昨天点击数
156 /// </summary>
157 public int YesterdayHits
158 {
159 get
160 {
161 return HitsArr[1];
162 }
163 }
164
165 /// <summary>
166 /// 获取今天点击数
167 /// </summary>
168 public int TodayHits
169 {
170 get
171 {
172 return HitsArr[2] + Hits;
173 }
174 }
175
176 /// <summary>
177 /// 加载点击数
178 /// </summary>
179 private void LoadHits()
180 {
181 if (HttpRuntime.Cache[CacheName] == null)
182 {
183 HttpContext ctx = HttpContext.Current;
184 if (!File.Exists(FilePth))
185 {
186 //--第一次使用
187 using (StreamWriter streamWriter = new StreamWriter(FilePth))
188 {
189 streamWriter.Write(string.Format("{0},{1},{2}", 0, 0, 0));
190 streamWriter.Flush();
191 }
192 HitsArr[0] = 0;
193 HitsArr[1] = 0;
194 HitsArr[2] = 0;
195 }
196 else
197 {
198 string hitsinfo = string.Empty;
199 using (StreamReader objStreamReader = new StreamReader(FilePth))
200 {
201 hitsinfo = objStreamReader.ReadLine();
202 }
203 if (hitsinfo != "")
204 {
205 string[] arr = hitsinfo.Split(',');
206 HitsArr[0] = Convert.ToInt32(arr[0]);//全部
207 HitsArr[1] = Convert.ToInt32(arr[1]);//昨天
208 HitsArr[2] = Convert.ToInt32(arr[2]);//今天
209 }
210 else
211 {
212 HitsArr[0] = 0;
213 HitsArr[1] = 0;
214 HitsArr[2] = 0;
215 }
216 }
217 HttpRuntime.Cache["b" + CacheName] = HitsArr;
218 }
219 else
220 {
221 HitsArr = (int[])HttpRuntime.Cache["b" + CacheName];
222 //HitsArr[0] += 1;
223 //HitsArr[2] += 1;
224
225 }
226 }
227
228
229 /// <summary>
230 /// 获取累计的点击数
231 /// </summary>
232 private int Hits
233 {
234 get
235 {
236 return _Hits;
237 }
238 set
239 {
240 _Hits = value;
241 }
242 }
243
244 /// <summary>
245 /// 累加
246 /// </summary>
247 /// <param name="id"></param>
248 private void Add()
249 {
250 if(HitsArr[2]<14000)
251 {
252 //_Hits = _Hits + new Random(DateTime.Now.Second).Next(60,80);
253 _Hits = _Hits + 1;
254 }
255 else
256 {
257 _Hits = _Hits + 1;//_Hits = _Hits + new Random(DateTime.Now.Second).Next(2,8); 传回指定范围的随机数
258 }
259 }
260 /// <summary>
261 /// 文件名
262 /// </summary>
263
264 /// <summary>
265 /// 获取文件名
266 /// </summary>
267 public string FileName
268 {
269 get { return _FileName; }
270 set { _FileName = value; }
271 }
272 }
273}
274
2.创建HttpHandler
1using System;
2using System.Web;
3using System.Text.RegularExpressions;
4
5namespace MYSpace.Counter
6{
7 /// <summary>
8 /// HitsHandler 的摘要说明。
9 /// </summary>
10 public class CounterHandler: IHttpHandler
11 {
12 public void ProcessRequest(HttpContext ctx)
13 {
14 CounterHelper objCounterHelper = new CounterHelper(ctx.Request.QueryString["id"].ToString());
15 objCounterHelper.AddHits();
16 ctx.Response.Write(string.Format("document.write('页面访问量:{0} 昨日:{1} 今日:{2} id :{3}')",objCounterHelper.AllHits,objCounterHelper.YesterdayHits,objCounterHelper.TodayHits,ctx.Request.Url.AbsoluteUri));
17 }
18
19 public bool IsReusable
20 {
21 get { return false; }
22 }
23 }
24}
25
2using System.Web;
3using System.Text.RegularExpressions;
4
5namespace MYSpace.Counter
6{
7 /// <summary>
8 /// HitsHandler 的摘要说明。
9 /// </summary>
10 public class CounterHandler: IHttpHandler
11 {
12 public void ProcessRequest(HttpContext ctx)
13 {
14 CounterHelper objCounterHelper = new CounterHelper(ctx.Request.QueryString["id"].ToString());
15 objCounterHelper.AddHits();
16 ctx.Response.Write(string.Format("document.write('页面访问量:{0} 昨日:{1} 今日:{2} id :{3}')",objCounterHelper.AllHits,objCounterHelper.YesterdayHits,objCounterHelper.TodayHits,ctx.Request.Url.AbsoluteUri));
17 }
18
19 public bool IsReusable
20 {
21 get { return false; }
22 }
23 }
24}
25
生成dll后创建一个Website,然后把dll引用进来!
接着在web.config里面添加配置:
<httpHandlers>
<add verb="*" path="count.aspx" type="MYSpace.Counter.CounterHandler,MYSpace.Counter" />
</httpHandlers>
最后在web页面调用就ok了。页面代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>无标题页</title>
<SCRIPT LANGUAGE="JavaScript" src='count.aspx?id=o4'></SCRIPT>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
</html>
很简单吧,这里只介绍到写入文件,如果想写入库里面,直接读取文件里的数值就搞定!