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

AppFabric CreateRoutingClient Error

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

在上面的例子中,cachefactory是它们各自类型的private static版本,位于一个名为Cache的静态类中。

希望能有所帮助

我们在工厂创建时使用了锁,从来没有出现过这个问题。我们也在我们的集群中使用AppFab 1.1。我建议你这样做:

lock (cacheLock)
{
    if(cacheFactory == null)
    {
        DataCacheFactoryConfiguration config = new DataCacheFactoryConfiguration(...); 
        cacheFactory = new DataCacheFactory(config);
    }
    return cacheFactory;
}