Dot-Net

跨負載平衡伺服器的選擇性記憶體清除 (ASP.Net)

  • April 21, 2009

我們有一個在兩台負載平衡伺服器上執行的網站。我們使用 ASP.Net 記憶體通過記憶體高使用率數據來幫助提高性能。但是,有時數據會發生變化。當它發生時,我們需要清除負載平衡伺服器上的相關記憶體項。有沒有人有一些易於實施的建議來說明如何做到這一點?

我知道有軟體可以為您管理這個(Microsoft Velocity 為其中之一)。我也知道還有其他選項可以擁有單獨的狀態伺服器等。但是,對於我們想要的,它們似乎都過大了。我們現在只需要一個簡單的機制來清除跨伺服器的特定記憶體項。

感謝您的任何建議。

我們使用簡單的 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 服務呼叫 _ClearItem 呼叫的相同程式碼。

為什麼不在兩個伺服器都可以看到的對像上定義記憶體依賴關係?您可以使用SQL文件記憶體依賴關係。

連結到記憶體 Msdn 頁面

引用自:https://stackoverflow.com/questions/774695