2009-04-21 31 views
8

我們有一個運行在兩個負載平衡服務器上的網站。我們使用ASP.Net緩存通過緩存高使用率數據來幫助提高性能。但偶爾數據會發生變化。當它發生時,我們需要清除負載平衡服務器上的相關緩存項目。有沒有人有一些容易實施的建議,如何做到這一點?跨負載平衡服務器的選擇性高速緩存清除(ASP.Net)

我知道那裏有軟件爲你管理這個軟件(Microsoft Velocity for one)。我也知道還有其他的選擇可以分開狀態服務器等。但是,對於我們想要的,他們似乎都是過度殺傷性的。現在只需要一個簡單的機制來清除跨服務器的特定緩存項目。

感謝您的任何建議。

+0

我很高興我的解決方案能爲你工作。如果遇到任何問題,請告訴我! – wweicker 2009-04-21 22:56:12

回答

1

我們用一個簡單的Web服務的方法。我們的緩存清除機制檢查web配置設置,以查看是否存在其他服務器,並異步地在這些服務器上調用Web服務。

我們存儲具有特定命名召集的數據,以便輕鬆地清除我們想要的內容。因此,我們傳遞要刪除的項目的前綴或後綴,因爲它有時可能是用戶特定的(例如,用戶標識附加到項目的名稱)或特定於應用程序(例如項目的前綴是應用程序名稱)。

這裏是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 

你可以看到,上面的代碼中使用這個輔助類調用其他的服務器(S):

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服務然後調用與_ClearItem調用的代碼相同的代碼。