środa, 25 maja 2011

Webfarm web servers configuration - Part 3 of 3 - cache synchronization

Because my application is using the HttpContext.Current.Cache object to store items used commonly in my application I needed to make sure that when the cache item was updated on one of Web servers, the aprropriate cache item on second server would also get updated. To accomplish that I decided to create a action in controller responsible for removing item from cache. Then whenever an item from the cache is removed this action would be called on second server to remove cached data. First step is to store in web.config the list of web servers that should be notified when the cache item is removed. So I added following key in web.config file on Server A (10.0.1.1).

and on Server B (10.0.1.2):

This is my Cache Synchronizer class
/// 
    /// Manages cache synchronization on webservers that the application is set up on
    /// Requires following application key to be present in web.config file: WebFarmServersAddresses
    /// 
    public static class CacheSynchronizer
    {
        public static void SynchronizeCache(string cacheKey)
        {
            // Remove cache items on another servers
            var servers = ConfigUtils.GetAppSetting("WebFarmServersAddresses").Split(';');
            foreach (var serverAddress in servers)
            {
                // Call action on second server responsible for removing item from cache
                using (WebClient asyncWebClient = new WebClient())
                {
                    asyncWebClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(asyncWebClient_DownloadDataCompleted);
                    Uri urlToRequest = new Uri(string.Format("http://{0}/System/RemoveCacheItem?key={1}", serverAddress, cacheKey));
                    //System.Diagnostics.Debug.WriteLine("Syncrhnizing cache on - " + urlToRequest.ToString());                    
                    asyncWebClient.DownloadDataAsync(urlToRequest);
                }
            }
            
        }

        static void asyncWebClient_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Elmah.ErrorSignal.FromCurrentContext().Raise(e.Error);
            }
        }
    }
Cache Synchronizer is called whenever an item is removed from cache:
cache.Remove(hash + cacheKey);
            #if !DEBUG
            // If the application is compiled in release mode we need to run Cache Synchronize in order to synchronize cache on another webservers
            if (updateAnotherServers)
            {
                CacheSynchronizer.SynchronizeCache(hash + cacheKey);
            }
            #endif
The last thing we need to do is to implement action in controller which is going to be called by cache synchronizer:
    public class SystemController : Controller
    {
        public void RemoveCacheItem(string key)
        {
            HttpContext.Cache.Remove(key);
        }
    }
That's it. The cache is going to be syncrhonized on another web servers in your web farm. This is the end of 3 part tutorial of setting asp.net mvc web application in web farm environment. Hope you enjoyed it.

Brak komentarzy: