为完成网站访问计数器可是伤透脑筋,今天完成了第一个版本,记录信息如下:
1、记录每天的访问用户数
2、记录每天的点击次数

就为实现这两个简单功能,也让我着实头痛,暂时没有太多考虑性能,只是实现。
简单说明一下:
由于为了精确实现计数器,那么要么简单使用Application.Lock锁定线程,要么自己写多线程的程序,他们都会造成系统性能的严重影响,因此,在锁定线程期间做的事情越少越好,因此不能频繁的往数据库写用户访问的计数统计信息,我使用了间隔一段时间写一次的方法,可以减少往数据库记录数据的次数,下面的代码在Application_EndRequest中检查用户上次记录数据的时间到现在是否超过了设定的时间间隔,如果是,那么再次记录,这样就极大的减少了写数据库的次数,对性能的影响和数据库服务器的影响也小一些。
如果服务器停止,那么最后一次时间间隔内的用户访问可能不会被记录,因此在Application_End事件中进行记录。

往数据库中传递的参数为:当前日期(yyyy-MM-dd格式),计数类别:用户数/页面点击数,计数。在存储过程中首先以日期参数为主键更新数据,如果更新失败(当天还没有记录过),那么插入新数据。数据库中该表有三个字段:TodayDate(Date),TodayVisitCNT(number),TodayClickCNT(number)。TodayDate为主键。

Option Explicit On
Option Strict On

Imports System
Imports System.Web
Imports System.Web.SessionState
Imports System.Runtime.Remoting

Imports System.IO
Imports Microsoft.VisualBasic

Namespace MyWeb
    Public Class Global
        Inherits System.Web.HttpApplication

        ' 保存访问计数
        Private Shared _visitCount As New Hashtable
        ' 记录最后一次更新计数信息的时间
        Private Shared _lastUpdate As DateTime

#Region " 组件设计器生成的代码 "

        Public Sub New()
            MyBase.New()

            '该调用是组件设计器所必需的。
            InitializeComponent()

            '在 InitializeComponent() 调用之后添加任何初始化

        End Sub

        '组件设计器所必需的
        Private components As System.ComponentModel.IContainer

        '注意:以下过程是组件设计器所必需的
        '可以使用组件设计器修改此过程。
        '不要使用代码编辑器修改它。
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            components = New System.ComponentModel.Container
        End Sub

#End Region

#Region "系统事件"


        Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
           ' 系统启动时间定为最后一次更新时间
            _lastUpdate = DateTime.Now
        End Sub

        Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
            ' 当前日期访问用户数加1
            Application.Lock()
            Dim Key As String = Now.ToString("yyyy-MM-dd") & "_USERCOUNT"
            _visitCount(Key) = CInt(_visitCount(Key)) + 1
            Application.UnLock()
      End Sub


        Sub Application_EndRequest(ByVal sender As Object, ByVal e As EventArgs)
            ' 用户日期页面请求次数增加1,到一定访问量以后记录到数据库
            Application.Lock()

            Dim Key As String = Now.ToString("yyyy-MM-dd") & "_PAGECOUNT"
            Dim count As Integer

            count = CInt(_visitCount(Key))
            count += 1
            _visitCount(Key) = count

            ' 如果上次记录时间超过了指定的时间间隔,那么再次记录计数器
            If DateTime.Now.Subtract(_lastUpdate).TotalSeconds > 60 Then
                ' 1、往数据库记录所有访问信息
                Dim item As String
                Dim mDate As Date
                Dim mType As String
                Dim mCount As Integer

                For Each item In _visitCount.Keys
                    mCount = CInt(_visitCount(item))
                    mDate = CDate(Split(item, "_")(0))
                    mType = CStr(Split(item, "_")(1))
                  ' 往数据库写数据
                    With New BusinessFacade.PagesSystem
                        .VisitCountLog(mDate, mType, mCount)
                    End With
                Next

                ' 2、将计数器归零
                _visitCount.Clear()
                ' 将记录时间更新
                _lastUpdate = DateTime.Now
            End If

            Application.UnLock()

        End Sub

        Sub Application_End(ByVal sender As Object, ByVal e As EventArgs)
            ' 在应用程序结束时激发

            ' 1、往数据库记录所有访问信息
            Dim item As String
            Dim mDate As Date
            Dim mType As String
            Dim mCount As Integer

            For Each item In _visitCount.Keys
                mCount = CInt(_visitCount(item))
                mDate = CDate(Split(item, "_")(0))
                mType = CStr(Split(item, "_")(1))
                With New BusinessFacade.PagesSystem
                    .VisitCountLog(mDate, mType, mCount)
                End With
            Next
            ' 2、将计数器归零
            _visitCount.Clear()

        End Sub

#End Region

    End Class
End Namespace

posted on 2004-06-10 15:48  zhumk  阅读(4359)  评论(0编辑  收藏  举报