AppFabric CreateRoutingClient Error
本文关键字:Error CreateRoutingClient AppFabric | 更新日期: 2023-09-27 17:49:21
AppFabric有一个问题,导致以下错误发生:
Exception type: ArgumentException
Exception message: An item with the same key has already been added.
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at Microsoft.ApplicationServer.Caching.DataCacheFactory.CreateRoutingClient(String cacheName, NamedCacheConfiguration config)
at Microsoft.ApplicationServer.Caching.DataCacheFactory.CreateNewCacheClient(DataCacheDeploymentMode mode, String cacheName, NamedCacheConfiguration config, IClientChannel channel)
at Microsoft.ApplicationServer.Caching.DataCacheFactory.GetCache(String cacheName)
at Microsoft.ApplicationServer.Caching.DataCacheFactory.GetDefaultCache()
... our code where we are attempting to retrieve a cache item from the default cache by its key
这个错误在我们的测试环境中很少发生(我们还没有找到一个根据需要重现这个问题的场景),但似乎总是在每次部署之后发生在我们的生产环境中。我们的部署是自动化的,并且我们已经验证了部署到各种环境的步骤是相同的。
给定环境的服务器设置如下:
- Server1 -主机我们的。net网站,是我们的AppFabric 1.1服务器
- Server2 -主机我们的。net网站
这些服务器是负载均衡的。两个应用程序都启用了AppFabric本地缓存。我们的测试服务器和生产服务器设置相同。我们知道在专用服务器上安装AppFabric会更好,但不认为这会导致/解决这个问题。
我们被这个问题难住了,因为我们在网上没有找到任何其他地方提到它,因为堆栈跟踪似乎表明这是AppFabric本身的问题。异常提到插入一些东西,但是当这种情况发生时,我们所做的只是试图从DataCacheFactory获取默认缓存,以便我们可以从中检索项。那么,这个错误意味着什么,我们该如何解决它呢?
下面是我用来创建DataCacheFactory
和从缓存中提取数据的代码:
private static readonly Lazy<DataCacheFactory> _DATA_CACHE_FACTORY = new Lazy<DataCacheFactory>(() => new DataCacheFactory());
private static readonly Lazy<DataCache> _CACHE = new Lazy<DataCache>(() => _DATA_CACHE_FACTORY.Value.GetDefaultCache());
public object Get(string key)
{
return _CACHE.Value.Get(key);
}
我100%确定重复密钥错误是由于对DataCacheFactory
的私有_myCache
属性的错误访问而产生的。该属性是一个哈希表。对Hashtable.Add("mykey","myvalue");
的重复调用将产生与您所看到的相同的期望。
我运行了多个测试,背靠背调用GetCache("default")
和GetDefaultCache()
不会产生错误。App Fabric试图填补这一空白的方式确实有些奇怪。这是我的代码,从来没有产生过这个错误。我想贴出来作为参考,以防你能看到一些明显不同于你的代码所做的事情
if (cache == null)
{
if(factory == null)
factory = new DataCacheFactory();
if(string.IsNullOrWhiteSpace(cacheName))
cacheName = ConfigurationManager.AppSettings["APP_FABRIC_CACHE_NAME"];
cache = factory.GetCache(cacheName);
return cache;
}
在上面的例子中,cache
和factory
是它们各自类型的private static
版本,位于一个名为Cache
的静态类中。
希望能有所帮助
我们在工厂创建时使用了锁,从来没有出现过这个问题。我们也在我们的集群中使用AppFab 1.1。我建议你这样做:
lock (cacheLock)
{
if(cacheFactory == null)
{
DataCacheFactoryConfiguration config = new DataCacheFactoryConfiguration(...);
cacheFactory = new DataCacheFactory(config);
}
return cacheFactory;
}