跟踪每个请求的访客信息

时间:2011-04-25 12:41:30

标签: asp.net analytics visitor-statistic

使用Asp.net webforms我想像Google Analytics一样跟踪访问者信息。当然,我可以将Google Analytic用于此目的,但我想知道如何使用Asp.net 3.5和SQL Server 2008实现相同的目标。

我想存储访问者的IP,国家/地区,URL推荐人,每个页面请求的解析除了回发。我期待每天访问50k +。

主要关注的是我希望以不应阻止当前请求的方式进行。

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

我在下面找到了替代方案:
1. PageAsynchTask
2. BeginExecuteNonQuery
3. Jquery Post方法和Web服务(但我对此没有信心,并且想知道我应该怎么做)

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

有人能告诉我哪一个更好吗?如果您有任何其他想法或更好的方法,请告诉我。非常感谢您的帮助。

4 个答案:

答案 0 :(得分: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-> Country数据库来完成这项工作。我之前使用过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从HttpModule中读取屏幕尺寸,然后将其记录在日志文件中。

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

这是否能为您提供问题的完整解决方案?

答案 1 :(得分:0)

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

  1. 请求仍会阻塞,直到任务完成(或超时中止)。
  2. 您必须在每个页面上注册您的任务。
  3. 第二种方法看起来不方便,可能会导致错误。 (当您的页面渲染速度超过查询处理速度时,您必须注意这种情况。我不确定当您的页面对象被销毁并且GC进入finalize()狂欢时查询未完成会发生什么。 ..但没什么好处,我假设。你可以通过在渲染后等待IAsyncResult.IsCompleted来避免它,但这很不方便。)

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

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

答案 2 :(得分: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)

希望你明白这一点

所有最好的

答案 3 :(得分:0)

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

没有什么比这更快,因为自IIS 1.0以来它已针对性能进行了优化

您可以在这些日志中添加自己的信息(HttpRequest.AppendToLog),它们具有标准格式,如果您想使用自定义内容,则有一个API(但如果您愿意,仍然可以使用文本解析器) ),有很多免费工具,例如Microsoft Log Parser,可以在SQL数据库(以及其他)中传输数据。