【问题标题】:track visitor info on every request跟踪每个请求的访客信息
【发布时间】:2011-05-07 21:39:37
【问题描述】:

使用 Asp.net 网络表单,我想像 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方法和Webservice(但我对此没有信心,想知道我该怎么做)

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

谁能告诉我哪种方法更好?如果您有任何其他想法或比列出的更好的方法,也请告诉我。您的帮助将不胜感激。

【问题讨论】:

    标签: asp.net analytics visitor-statistic


    【解决方案1】:

    服务器端任何后台线程的问题是每个请求都将占用两个线程。一种用于服务 ASP.NET 请求,另一种用于记录您要记录的内容。因此,由于 ASP.NET 线程耗尽,您最终会遇到可伸缩性问题。在数据库中记录每个请求是一个很大的禁忌。

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

    您可以使用 HttpModule 拦截每个 GET、POST,然后在 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 异步回发的解决方案。

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

    【讨论】:

    • 我一直在使用 Entlib(DAAB + 异常处理 + 日志记录),对于国家/地区的 ip,我将使用 this。我对您所说的关于在数据库中存储信息的方案表示怀疑,那么如果我想在他的仪表板中向管理员显示不同的访问者详细信息,还有什么选择?我认为在日志文件中保存详细信息是不可能的。感谢您所说的我将与 HTTP 模块一起使用的分辨率 sn-p,因为我将获得有关每个请求的所需信息,并且模块也可以在其他项目中使用。非常感谢您的帮助
    • 您应该将原始日志存储在日志文件中。然后您可以创建一些 Windows 服务或控制台应用程序来处理原始日志,然后进行 IP -> 国家/地区映射,然后将摘要信息存储在数据库中。我建议不要将每次访问都存储在数据库中。最好将一些每日摘要或国家/地区摘要存储在数据库中,并从管理仪表板中显示。
    【解决方案2】:

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

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

    第二种方法看起来不方便,可能会导致错误。 (您必须注意页面呈现速度快于查询处理速度的情况。我不确定当您的页面对象被销毁并且 GC 继续 finalize() 狂欢时,如果您的查询未完成会发生什么......但我认为没什么好处。您可以通过在渲染后等待 IAsyncResult.IsCompleted 来避免它,但这很不方便。)

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

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

    【讨论】:

    • 感谢您抽出宝贵时间回答我的问题。
    • 感谢您抽出宝贵时间回答我的问题。我知道第一种方法的第二点,但第一点可能是你所说的问题。第二种方法我从未使用过,但会检查一下。我已经放弃了使用第三种方法的想法。正如你所说,我可以在 BeginRequest 中做到这一点,但我猜会话在该事件中不可用,所以如果我想追踪用户特定信息,它对我没有帮助。我想我必须使用 Application_PreRequestHandlerExecute 因为会话将在其中可用。我已经浏览了this 的文章。
    • 我仍然愿意接受其他想法和更好的方法。
    【解决方案3】:

    嗨, 您可以触发异步请求而无需等待响应。 这里我有一些实现的代码..

    为此,您需要创建一个 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)

    希望你明白这一点

    一切顺利

    【讨论】:

      【解决方案4】:

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

      没有比这更快的了,因为它从 IIS 1.0 开始就针对性能进行了优化

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

      【讨论】:

      • 感谢西蒙的回复。 IIS 日志文件包含的信息过多,我不关心是否访问了特定图像的次数,并且当您将数据分散在没有文件中时会变得很困难。我们当然可以使用您提到的实用程序或网络上可用的其他实用程序来解析日志文件。很难看到单个会话中的活动以及是否有访客返回。 Response.AppendToLog 在 URI 中附加详细信息,如果我们预期其他参数,则会有长度限制。我正在考虑这是最后的选择。再次感谢您的宝贵意见。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-21
      • 2022-01-23
      • 2019-07-15
      • 1970-01-01
      • 2023-01-13
      • 1970-01-01
      相关资源
      最近更新 更多