代码之家  ›  专栏  ›  技术社区  ›  James

跨负载平衡服务器(ASP.NET)的选择性缓存清除

  •  8
  • James  · 技术社区  · 17 年前

    我们有一个在两个负载平衡服务器上运行的网站。我们使用ASP.NET缓存通过缓存高使用率数据来帮助提高性能。但是,偶尔这些数据会发生变化。这样做时,我们需要清除两个负载平衡服务器上的相关缓存项。对于如何实现这一点,是否有人有一些易于实施的建议?

    我知道有软件可以帮你管理这个(微软的Velocity就是其中之一)。我也知道有其他的选择,有独立的状态服务器等。然而,对于我们想要的,他们似乎都是多余的。我们现在只需要一个简单的机制来清除跨服务器的特定缓存项。

    谢谢你的建议。

    2 回复  |  直到 17 年前
        1
  •  1
  •   wweicker    17 年前

    我们使用一种简单的Web服务方法。我们的缓存清除机制检查Web配置设置,以查看是否存在其他服务器,并异步调用这些服务器上的Web服务。

    我们使用特定的命名转换来存储数据,以便于清楚地了解我们想要什么。因此,我们为要删除的项传递前缀或后缀,因为有时它可能是特定于用户(例如,用户ID附加到项的名称)或特定于应用程序(例如,项的前缀是应用程序名称)。

    下面是将在任意一个节点上调用的ClearItem例程的VB示例:

    Public Shared Sub ClearItem(ByVal strPrefix As String, ByVal strPostfix As String)
    
        If WebConfig.Caching_Enabled() Then
    
            ' Exit if no criteria specified '
            If IsNothing(strPrefix) AndAlso IsNothing(strPostfix) Then
                Exit Sub
            End If
    
            ' At the very least we need a Postfix '
            If Not IsNothing(strPostfix) AndAlso Not strPostfix.Length.Equals(0) Then
                _ClearItem(strPrefix, strPostfix)
            End If
    
            If WebConfig.Caching_WebFarmEnabled() Then
                ' Now clear the cache across the rest of the server farm '
                _ClearItem_WebFarm(strPrefix, strPostfix)
            End If
    
        End If
    
    End Sub
    
    Private Shared Sub _ClearItem_WebFarm(ByVal strPrefix As String, ByVal strPostfix As String)
    
        If WebConfig.Caching_WebFarmEnabled() Then
    
            ' Use a web service on each server in the farm to clear the '
            ' requested item from the Cache '
    
            ' Determine which servers need to remove cache items '
            Dim arrServers As String()
            arrServers = Split(WebConfig.Caching_WebFarmServers(), "|")
    
            Dim strServer As String ' Holds which server we are currently contacting ' 
    
            ' Loop through all the servers and call their web services '
            For Each strServer In arrServers
    
                Dim WS As New WebServiceAsyncCall
                WS.StartCallBack(strServer, strPrefix, strPostfix)
    
            Next
    
        End If
    
    End Sub
    
    Private Shared Sub _ClearItem(ByVal strPrefix As String, ByVal strPostfix As String)
    
        If WebConfig.Caching_Enabled() Then
    
            ' Determine how we are comparing keys '
            Dim blnPrefix, blnPostfix As Boolean
    
            If strPrefix.Length.Equals(0) Then
                blnPrefix = False
            Else
                blnPrefix = True
            End If
    
            If strPostfix.Length.Equals(0) Then
                blnPostfix = False
            Else
                blnPostfix = True
            End If
    
            ' Reference the Cache collection '
            Dim objCache As System.Web.Caching.Cache = HttpContext.Current.Cache
    
            ' Exit if the cache is empty '
            If objCache.Count.Equals(0) Then
                Exit Sub
            End If
    
            ' Clear out the cache for all items matching the input(s) (on this local server) '
            Dim objCacheEnum As IEnumerator = objCache.GetEnumerator()
            Dim objCacheItem As Object
            Dim objCurrentKey As System.Collections.DictionaryEntry
            Dim strCurrentKey As String
    
            ' Enumerate through the cache '
            While objCacheEnum.MoveNext()
    
                objCurrentKey = CType(objCacheEnum.Current, DictionaryEntry)
                strCurrentKey = objCurrentKey.Key.ToString()
    
                ' How are we comparing the key? '
                If blnPrefix AndAlso Not (blnPostfix) Then ' Only by PREFIX '
    
                    If strCurrentKey.StartsWith(strPrefix) Then
                        ' Remove it from the cache '
                        objCacheItem = objCache.Remove(strCurrentKey) ' Returns a reference to the item '
                        objCacheItem = Nothing ' Need to explicitly nuke this because the objCache.Remove() above doesn t destroy '
                    End If
    
                ElseIf Not (blnPrefix) AndAlso blnPostfix Then ' Only by POSTFIX '
    
                    If strCurrentKey.EndsWith(strPostfix) Then
                        ' Remove it from the cache '
                        objCacheItem = objCache.Remove(strCurrentKey) ' Returns a reference to the item '
                        objCacheItem = Nothing ' Need to explicitly nuke this because the objCache.Remove() above doesn t destroy '
                    End If
    
                ElseIf blnPrefix AndAlso blnPostfix Then ' By both PREFIX and POSTFIX'
    
                    If strCurrentKey.StartsWith(strPrefix) AndAlso strCurrentKey.EndsWith(strPostfix) Then
                        ' Remove it from the cache '
                        objCacheItem = objCache.Remove(strCurrentKey) ' Returns a reference to the item '
                        objCacheItem = Nothing ' Need to explicitly nuke this because the objCache.Remove() above doesn t destroy '
                    End If
    
                Else
                    ' Not comparing prefix OR postfix? Why bother continuing then! '
                    Exit Sub
                End If
    
            End While
    
        End If
    
    End Sub
    

    您可以看到上面的代码通过使用此助手类调用其他服务器:

    Private Class WebServiceAsyncCall
    
        Public Sub StartCallBack(ByVal strService As String, ByVal strPrefix As String, ByVal strPostfix As String)
    
            ActiveWebServiceCounter += 1
    
            Dim clearCacheProxy As New CacheClearService.CacheClear ' This is the web service which of course will exist on the other node as well '
            clearCacheProxy.Url = strService
    
            AddHandler clearCacheProxy.ClearItemCompleted, AddressOf DoneCallBack
    
            clearCacheProxy.ClearItemAsync(strPrefix, strPostfix)
    
        End Sub
    
        Public Sub DoneCallBack(ByVal sender As Object, ByVal e As CacheClearService.ClearItemCompletedEventArgs)
    
            ActiveWebServiceCounter -= 1
    
            If e.Result.Length > 0 Then ' Something failed '
                ' Log the error '
            End If
    
        End Sub
    
    End Class
    

    然后,远程服务器上的Web服务调用与\u clearItem调用的代码相同的代码。

        2
  •  5
  •   JoshBerke    17 年前

    为什么不在两个服务器都能看到的对象上定义一个缓存依赖性呢?你可以使用 SQL 或 File 缓存依赖性。

    Link to Caching Msdn Page