Ошибка AppRabric CreateRoutingClient
У нас есть проблема с 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);
}
Ответы
Ответ 1
Я на 100% уверен, что дублируемая ошибка ключа генерируется плохим доступом к частному _myCache
свойству DataCacheFactory
. Это свойство Hashtable. Повторные вызовы Hashtable.Add("mykey","myvalue");
будут генерировать то же самое, что и ваш вид.
Я запускал несколько тестов, а вызов GetCache("default")
и GetDefaultCache()
назад не приводит к ошибке. Это определенно что-то странное в том, как приложение 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
.
Надеюсь, что это поможет
Ответ 2
Мы используем блокировку вокруг нашего factory создания и никогда не сталкивались с этой проблемой. Мы также используем AppFab 1.1 для нашего кластера. Я бы порекомендовал вам сделать что-то вроде этого:
lock (cacheLock)
{
if(cacheFactory == null)
{
DataCacheFactoryConfiguration config = new DataCacheFactoryConfiguration(...);
cacheFactory = new DataCacheFactory(config);
}
return cacheFactory;
}