2011-04-25 33 views
1

使用Asp.net webforms我想跟踪Google Analytics一样的访问者信息。当然,我可以使用谷歌分析为这个目的,但我想知道我怎么能与Asp.net 3.5和SQL Server 2008实现相同的事情。跟踪每个请求的访问者信息

我想存储IP,国家,URL推荐的访问者,解决每个页面请求,除了回发。我期望每天访问5万次以上。

主要问题是我想以不应阻止当前请求的方式执行此操作。

即一般情况下,当我们将数据保存到数据库时,当前请求停止在特定的SP调用状态,并在完成SP或tsql语句执行时向前移动。我想遵循“插入和忘记”的方法。当我将参数传递给特定事件或函数时,它应该在后台插入。

我发现下面的替代品这样的:
1. PageAsynchTask
2. BeginExecuteNonQuery
3. jQuery的Post方法和WebService(但我不相信这一点,并想知道应该如何去做)

我希望我已经正确地提到了我的问题。

有人可以告诉我哪一个更好吗?此外,让我知道你是否有任何其他想法或更好的方法比列出的。您的帮助将非常感激。

回答

1

服务器端任何后台线程的问题是每个请求都占用两个线程。一个用于提供ASP.NET请求,另一个用于记录要记录的内容。所以,最终由于ASP.NET线程耗尽而导致可伸缩性问题。并且在数据库中记录每一个请求是一件很大的事情。

最好的办法就是使用一些高性能日志库来写入日志文件。日志记录库针对多线程日志进行了高度优化。他们不会在每个呼叫中​​产生I/O呼叫。日志存储在内存缓冲区中并定期刷新。您应该使用EntLib或Log4net进行日志记录。

您可以使用拦截每个GET,POST,然后在HttpModule内部的HttpModule,您可以检查Request.Url是否为aspx。然后你可以读取Request.Headers [“__ ASYNCPOST”]并查看它是否为“true”,这意味着它是一个UpdatePanel异步更新。如果所有这些条件都满足,你只需登录请求到该存储

您可以从客户端获取IP日志文件:

HttpContext.Current.Request.UserHostAddress; 
or 
HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; 

要获取本机的IP地址,而不是代理请使用以下代码

HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; 

但是无法获取该国家/地区。您必须将IP记录在日志文件中,然后使用某些控制台应用程序或作业来处理日志文件,这些应用程序或作业将解析IP的国家/地区。你需要获得一些IP->国家数据库来完成这项工作。我以前用过http://www.maxmind.com/app/geoip_country

对于屏幕尺寸,你将不得不依靠一些JavaScript。在每个页面上使用javascript,在客户端查找屏幕大小并存储在cookie中。

var screenW = 640, screenH = 480; 
if (parseInt(navigator.appVersion)>3) { 
screenW = screen.width; 
screenH = screen.height; 
} 
else if (navigator.appName == "Netscape" 
    && parseInt(navigator.appVersion)==3 
    && navigator.javaEnabled() 
    ) 
{ 
var jToolkit = java.awt.Toolkit.getDefaultToolkit(); 
var jScreenSize = jToolkit.getScreenSize(); 
screenW = jScreenSize.width; 
screenH = jScreenSize.height; 
} 

一旦你将它存储在cookie(我还没有证明代码),您可以通过使用Request.Cookies时读取来自HTTP模块屏幕尺寸,然后在日志文件中记录它。

因此,这为您提供了登录IP,屏幕大小,从IP查找国家以及从日志记录过滤UpdatePanel异步回发的解决方案。

这是否为您提供了完整的解决方案?

+0

我一直在使用Entlib(DAAB +异常处理+日志记录)为它和IP到国家,我将使用[this](http://www.ipinfodb.com)。我怀疑你说的关于将信息存储在数据库中的情况,所以如果我想在他的仪表板中向管理员显示不同的访问者详细信息,会有什么样的选择?我认为在日志文件中保存细节是不可能的。感谢您的解决方案片段,我将与HTTP模块一起使用,因为我将获得有关每个请求的必需信息,并且模块也可以用于其他项目。非常感谢您的帮助 – 2011-05-08 16:56:43

+0

您应该将原始日志存储在日志文件中。然后,您可以创建一些处理原始日志的Windows服务或控制台应用程序,然后执行IP - >国家/地区映射,然后将摘要信息存储在数据库中。我建议不要将每次访问都存储在数据库中。最好在数据库中存储一些每日摘要或国家明智的摘要,并从管理仪表板显示。 – oazabir 2011-05-10 19:54:02

+0

如果这有帮助,请投我的答案。 – oazabir 2011-05-10 19:54:31

0

第一种方法看起来不错。 (但我推荐它。)但它有两个缺点:

  1. 请求将仍然阻塞,直到任务完成(或超时中止)。
  2. 您必须在每个页面上注册您的任务。

第二种方法看起来不方便,可能会导致错误。 (当你的页面渲染速度超过你的查询处理速度时,你必须注意一些情况,我不确定当你的页面对象被销毁并且GC进行finalize()时,你的查询没有完成会发生什么......但是没有什么好的,我假设你可以通过在渲染后等待IAsyncResult.IsCompleted来避免它,但这很不方便。)

第三种方法显然是错误的。在处理您要记录的请求时,您应该在服务器端上启动日志记录。但是您仍然可以从服务器端调用Web服务。 (或赢得服务)。

就我个人而言,我想在BeginRequest中实现日志记录以避免代码重复,但是您需要IsPostback ...仍然可能有解决方法。

+0

我很感激你的时间来回答我的问题。 – 2011-04-26 18:55:58

+0

我很感谢您花时间回答我的问题。 我意识到第一种方法的第二点,但第一点可能是你说的问题。 第二种方法我从来没有用过,但会检查出来。 我放弃了使用第三种方法的想法。 正如你所说,我可以在BeginRequest中做到这一点,但我猜想在该事件中会话不可用,所以如果我想追踪用户特定的信息,它不会帮助我。我认为我必须使用Application_PreRequestHandlerExecute,因为会话将可用于此。我已阅读[this](http://tinyurl.com/l9xs4)文章。 – 2011-04-26 19:10:55

+0

我仍然对其他想法和更好的方法开放。 – 2011-04-26 19:13:14

0

嗨, 你可以触发一个异步请求,不要等待响应。 这里我有一些实施的代码..

因为你需要创建一个Web服务来做你的数据库操作,或者你可以用它来处理整个事件。

从服务器端,你必须异步调用Web服务这样的

声明一个私有的委托

private delegate void ReEntryDelegate(long CaseID, string MessageText); 

现在的方法将包含Web服务调用这样

WebServiceTest.Notification service = new WebServiceTest.Notification(); 
IAsyncResult handle; 
ReEntryDelegate objAscReEntry = new ReEntryDelegate(service.ReEntryNotifications); 
handle = objAscReEntry.BeginInvoke(CaseID, MessageText, null, null); 
break; 

而且变量值将通过此处的方法传递(CaseID,MessageText)

希望这是你清楚

一切顺利

0

谈到服务器端,如果你正在运行在IIS上,你并不需要绝对的实时信息,我建议你使用IIS日志。

没有什么比这个速度更快,因为它的性能,因为IIS进行了优化1.0

您可以将这些日志(HttpRequest.AppendToLog)自己的信息,他们有一个标准的格式,有一个API,如果你想用它来做自定义的事情(但是如果你愿意,你仍然可以使用文本解析器),并且有很多免费工具,例如Microsoft Log Parser可以在SQL数据库中传输数据等等。

+0

谢谢西蒙回应。 IIS日志文件包含的信息比所需要的要多得多,我不担心特定图像是否被访问了多少次,而当您将数据分散到多个文件中时,它变得很困难。我们现在可以使用您提到的实用程序或其他网络上的其他工具解析日志文件。在单个会话中看到活动以及是否有任何访问者返回都很困难。 Response.AppendToLog在URI中附加了详细信息,如果我们预计其他参数会有长度限制。我正在考虑这是最后的选择。再次感谢您的宝贵意见。 – 2011-05-08 12:43:56