问题描述
我们有一个在两台负载平衡服务器上运行的网站.我们使用 ASP.Net 缓存通过缓存高使用率数据来帮助提高性能.但是,偶尔数据会发生变化.当它发生时,我们需要清除负载平衡服务器上的相关缓存项.有没有人对如何做到这一点有一些易于实施的建议?
We have a website that runs on two load balanced servers. We use the ASP.Net caching to help improve performance by caching high usage data. BUT, occasionally that data changes. When it does, we need to clear the relevant cache items on BOTH the load balanced servers. Does anyone have some easy to implement suggestions for how this can be done?
我知道有软件可以为你管理这个(微软 Velocity 就是其中之一).我也知道拥有单独的状态服务器等还有其他选择.但是,对于我们想要的,它们似乎都有些矫枉过正.我们现在只需要一个简单的机制来清除跨服务器的特定缓存项.
I know that there is software out there to manage this for you (Microsoft Velocity for one). I also know that there are other options for having separate state servers etc. However, for what we want they all seem like overkill. Just a simple mechanism for clearing out specific cache items across servers is all we need for now.
感谢您的任何建议.
推荐答案
我们使用简单的 Web 服务方法.我们的缓存清除机制会检查 Web 配置设置以查看是否存在任何其他服务器,并异步调用这些服务器上的 Web 服务.
We use a simple web service approach. Our cache clear mechanism checks a web config setting to see if any other servers exist and calls the web service on those server(s) asynchronously.
我们使用特定的命名约定存储数据,以便轻松清除我们想要的内容.因此,我们为要删除的项目传入前缀或后缀,因为有时它可能是特定于用户的(例如,将用户 ID 附加到项目名称)或特定于应用程序(例如,项目的前缀是应用程序)姓名).
We store data with specific naming convetions to make it easy to clear what we want. So we pass in either a prefix or postfix for the item to be removed as sometimes it might be user specific (ex. the userid is appended to the name of the item) or application specific (ex. the prefix of the item is the application name).
以下是在任一节点上调用的 ClearItem 例程的 VB 示例:
Here is a VB example of the ClearItem routine that would be called on either one of your nodes:
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
你可以看到上面的代码通过使用这个辅助类调用了其他服务器:
You can see that the code above calls other server(s) by using this helper class:
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 调用的代码相同的代码.
The web service on the remote server then calls the same code that the _ClearItem called.
这篇关于跨负载平衡服务器 (ASP.Net) 的选择性缓存清除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!