加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

利用HttpModule做流量记录 画蛇添足最后一笔

发布时间:2020-12-17 02:48:37 所属栏目:安全 来源:网络整理
导读:《利用HttpModule做流量记录》和《利用HttpModule做流量记录 补充》除了得到大家的建议外也饱受非议。在这里要谢谢 kiler 、zoti、武眉博活靶子.NET、大石头、古巴、yoshow、ekinwt 、Jeffrey Zhao、slightboy的建议,感谢一下Colin Han、北极熊,我来了

《利用HttpModule做流量记录》和《利用HttpModule做流量记录 补充》除了得到大家的建议外也饱受非议。在这里要谢谢 kiler 、zoti、武眉博<活靶子.NET>、大石头、古巴、yoshow、ekinwt
、Jeffrey Zhao、slightboy的建议,感谢一下Colin Han、北极熊,我来了!、nasa、雪溯馨风的支持。

利用HttpModule做流量记录的方案已经提出来了,而且也已经决定项目采用这个方案,所以,就算是N多的不好,也还是需要完善一下。下面,我就画蛇添足吧!

方案的瓶颈:
1、加载入了Web请求,给处理增加负担。
2、每次请求页面都会产生巨大的记录数据。保存记录数据时整体性能的损耗。
3、由于流量记录HttpModule异常引发网站请求异常存在危险性。

方案的优势:
1、最大程度保护记录准确性。用户信息基于Session中获取。
2、无需往实际页面中增加任何代码。也无需让所有页面继承任何一个基类。保持网站业务逻辑代码和统计代码分离。
3、可以记录WebService请求(必须开启服务方法Session才能获取保存在Session中的信息)。

我采用降低瓶颈的解决方案
1、数据记录。
最终采用记录入Sql2005数据库,利用异步处理完成并启用连接池。
CS代码——————————————————————————————————————————————————
?/// <summary>
??????? /// 记录流量信息
??????? /// </summary>
??????? /// <param name="flowEntity">流量记录实体</param>
??????? public void Record(FlowEntity flowEntity)
??????? {
??????????? //判断连接是否为打开状态
??????????? if (_conn.State != ConnectionState.Open)
??????????????? _conn.Open();

???? string strCommand = "记录语句";
??????????? SqlCommand dbcommand = new SqlCommand(strCommand,_conn);
??????????? dbcommand.CommandType = CommandType.Text;
???????????
??????????? dbcommand.Parameters.Add(添加记录需要的参数);
??????????

??????????? try
??????????? {
??????????????? dbcommand.BeginExecuteNonQuery(new AsyncCallback(dbcommandCallBack),dbcommand);

??????????? }
??????????? catch
??????????? {
??????????? }

??????? }

??????? public void dbcommandCallBack(IAsyncResult result)
??????? {
??????????? try
??????????? {
??????????????? SqlCommand dbcommand = (SqlCommand)result.AsyncState;
??????????????? dbcommand.EndExecuteNonQuery(result);
??????????? }
??????????? catch
??????????? {

??????????? }
??????? }
web.config 连接字符串——————————————————————————————————————————
<add name="FoutorWebSiteFlowStatisticsDatabaseConnectionString"
?? connectionString="Data Source=YourServer;Initial Catalog=FoutorWebSiteFlowStatisticsDatabase;Integrated Security=True;Asynchronous

Processing=true;Pooling=true;MultipleActiveResultSets=true;"
?? providerName="System.Data.SqlClient" />
注意必须用:Asynchronous Processing=true;MultipleActiveResultSets=true;声明

关于ADO.net异步处理和Http异步处理可以参考下面的文章
通过 ASP.NET 异步编程实现可扩展的应用程序 http://msdn.microsoft.com/msdnmag/issues/07/03/WickedCode/Default.aspx?loc=zh#void
执行异步操作 http://msdn2.microsoft.com/zh-cn/library/zw97wx20(VS.80).aspx
ADO.NET 2.0中的异步命令执行 http://blog.csdn.net/Aaron_Xie/archive/2007/07/20/1700510.aspx
ADO.NET的新功能:MARS(Multiple Active Result Set) 及 异步执行命令 http://www.cnblogs.com/doll-net/archive/2007/07/23/828043.html

2、关于请求Session的问题。
我曾补充到“
如果选用从Session中传入用户信息或者其他需要记录的信息,请在记录前加判断(2007年8月29日20:34:43增加)
?if (ctx.Handler is Page || ctx.Handler is WebService)
根据需要选用Page还是WebService。
调试过程中发现,如果是其他的类型可能不创建Session,这时从Session读取数据发生错误,造成整个请求中断引起请求失效。这样其他的Module可能不能执行造成页面上一些需要生成的东西无

法生成,例如Asp.net Ajax从WebService生成的脚本类型注册等,引发错误!
尽量捕捉错误,因为这些错误可能不会直接爆出,引发请求中断,让人有的时候摸不着头脑!

但是发现好似用Asp.net Ajax做的WebService放弃捕获,具体原因时间原因没有深究。

这里可以写成这样,更好些

??????????? HttpApplication Application = (HttpApplication)source;
??????????? HttpContext ctx = Application.Context;

??????????? if (!IsFlowType(ctx.Request.Url.AbsoluteUri))
??????????????? return;???????????

??????????? if (ctx.Session!=null)

3、引发异常中断请求。
没有什么好多的了。全部Catch住吧,就不要再抛错误了。最好再Catch里面记录一下错误把。

考虑过的其他解决方案
1、让请求异步处理
通过 ASP.NET 异步编程实现可扩展的应用程序里面的示例代码
using System;
using System.Web;
using System.IO;
using System.Threading;
using System.Text;

public class AsyncRequestLogModule : IHttpModule
{
??? private FileStream _file;
??? private static long _position = 0;
??? private static object _lock = new object();
???
??? public void Init (HttpApplication application)
?{
??application.AddOnPreRequestHandlerExecuteAsync (
???new BeginEventHandler (BeginPreRequestHandlerExecute),
???new EndEventHandler (EndPreRequestHandlerExecute)
??);
?}

?IAsyncResult BeginPreRequestHandlerExecute (Object source,EventArgs e,
??AsyncCallback cb,Object state)
?{
??????? HttpApplication application = (HttpApplication)source;
??????? DateTime time = DateTime.Now;

??????? string line = String.Format("{0,10:d}??? {1,11:T}??? {2,32}?? {3}/r/n",
??????????? time,time,
??????????? application.User.Identity.IsAuthenticated ?
??????????? application.User.Identity.Name :
??????????? application.Request.UserHostAddress,
??????????? application.Request.Url);

??????? byte[] output = Encoding.ASCII.GetBytes(line);

??????? lock (_lock)
??????? {
??????????? _file = new FileStream(HttpContext.Current.Server.MapPath("~/App_Data/RequestLog.txt"),
??????????????? FileMode.OpenOrCreate,FileAccess.Write,FileShare.Write,1024,true);
??????????? _file.Seek(_position,SeekOrigin.Begin);
??????????? _position += output.Length;
??????????? return _file.BeginWrite(output,output.Length,cb,state);
??????? }
??? }

?void EndPreRequestHandlerExecute (IAsyncResult ar)
?{
??????? _file.EndWrite(ar);
??????? _file.Close();
??? }

?public void Dispose () {}
}

2、利用IIS日志,和form验证配合(大石头的建议)“如果是我,我会直接使用IIS日志,然后用LogParser,.net调用那个COM,就可以实现很多统计功能”

?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读