简体   繁体   English

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

[英]Caching Class on Load Balanced Server

I have a class which does caching in the service layer business objects of my web app. 我有一个类在我的Web应用程序的服务层业务对象中进行缓存。 When the code runs on a load-balanced server, when a client hits one machine and updates their details, but then close the browser, reopen it and happen to hit the website on one of the other machines on the load-balanced solution, their latest changes are not visible. 当代码在负载平衡的服务器上运行时,当客户端点击一台计算机并更新其详细信息,然后关闭浏览器,重新打开它并碰巧在负载平衡解决方案上的其他一台机器上访问网站时,最新的更改不可见。

This basic class is inherited by my other business objects like the People. 这个基本类由我的其他业务对象继承。 Is there a way I can refresh this cached object on the other servers on the load-balanced environment, so the client always sees the latest? 有没有办法可以在负载均衡的环境中刷新其他服务器上的缓存对象,这样客户端总能看到最新的?

   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));
            }
        }
    }
}

This is to be expected as you're creating the cache within the local app domain that's scoped to the immediate server. 当您在本地应用程序域中创建缓存到直接服务器时,可以预期这一点。 Any objects created there are only relevant to that app domain. 在那里创建的任何对象仅与该app域相关。

To get around this you need to centralize the caching solution to a common server or using something like Couchbase/Memcached so that all servers can share the same cache. 要解决此问题,您需要将缓存解决方案集中到公共服务器或使用Couchbase / Memcached之类的东西,以便所有服务器可以共享相同的缓存。

Lloyd's answer basically covers it. 劳埃德的答案基本上涵盖了它。

It's a little unusual to roll your own cache in a .NET application. 在.NET应用程序中滚动自己的缓存有点不寻常。 Generally you would use the caching built into the framework - see ASP.NET Caching for an overview, and the System.Web.Caching namespace . 通常,您将使用框架中内置的缓存 - 请参阅ASP.NET缓存以获取概述,以及System.Web.Caching命名空间 If you were doing that, you could for instance invalidate cached data on database changes using SqlCacheDependency . 如果您这样做,您可以使用SqlCacheDependency使数据库更改的缓存数据无效。

For load-balanced environments, though, you would probably be better with a centralized cache as Lloyd recommended. 但是,对于负载均衡的环境,Lloyd建议使用集中式缓存可能会更好。 If you want to stay with a Microsoft solution, AppFabric would be your go-to option. 如果您想继续使用Microsoft解决方案, AppFabric将是您的首选。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM