负载均衡服务器上的缓存类

时间:2013-07-25 22:25:01

标签: c# asp.net asp.net-mvc caching deployment

我有一个在我的网络应用程序的服务层业务对象中进行缓存的类。当代码在负载平衡的服务器上运行时,当客户端点击一台计算机并更新其详细信息,然后关闭浏览器,重新打开它并碰巧在负载平衡解决方案上的其他一台机器上访问网站时,最新的变化不可见。

此基本类由我的其他业务对象(如People)继承。有没有办法可以在负载均衡的环境中刷新其他服务器上的缓存对象,这样客户端总能看到最新的?

   public abstract class CacheStore<T> where T:IComparable, new()
    {
        private class CacheItem
        {
            public T Item
            {
                get;
                set;
            }

            public DateTime Expires
            {
                get;
                set;
            }
        }

        private List<CacheItem> theCache = new List<CacheItem>();

        public abstract TimeSpan Lifetime
        {
            get;
        }

        public int CountAll
        {
            get
            {
                return theCache.Count();
            }
        }

        public int CountExpired
        {
            get
            {
                return theCache.Count(i => i.Expires < DateTime.Now);
            }
        }

        public void Add(T item)
        {
            CacheItem i = (from c in theCache where (c.Item.CompareTo(item) == 0) select c).FirstOrDefault();
            if (i != null)
            {
                if (i.Expires < DateTime.Now)
                {
                    theCache.Remove(i);
                    i = null;
                }
            }

            if (i == null)
            {
                theCache.Add(new CacheItem()
                {
                    Expires = DateTime.Now + Lifetime,
                    Item = item
                });
            }
        }

        public IEnumerable<T> Filter(Func<T, bool> predicate)
        {
            return (from c in theCache where c.Expires > DateTime.Now select c.Item).Where(predicate);
        }

        public void MarkAsExpired(Func<T, bool> predicate)
        {
            var markAsExpired = from c in theCache 
                                where this.Filter(predicate).Contains(c.Item) 
                                    select c;
            foreach (CacheItem ci in markAsExpired)
            {
                ci.Expires = DateTime.Now.Subtract(TimeSpan.FromSeconds(1));
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

当您在本地应用程序域中创建缓存到直接服务器的缓存时,可以预料到这一点。在那里创建的任何对象仅与该app域相关。

要解决此问题,您需要将缓存解决方案集中到公共服务器或使用Couchbase / Memcached之类的东西,以便所有服务器可以共享相同的缓存。

答案 1 :(得分:1)

劳埃德的答案基本上涵盖了它。

在.NET应用程序中滚动自己的缓存有点不寻常。通常,您将使用框架中内置的缓存 - 请参阅ASP.NET Caching以获取概述,并the System.Web.Caching namespace。如果您这样做,您可以使用SqlCacheDependency使数据库更改的缓存数据无效。

对于负载均衡的环境,Lloyd建议使用集中式缓存可能会更好。如果您想继续使用Microsoft解决方案,AppFabric将成为您的首选。