Обновление: теперь я правильно реализовал это. Дополнительную информацию см. В моем сообщении в блоге об этом.
Я пытаюсь использовать AppFabric с NHibernate в качестве поставщика кеша второго уровня, но получаю следующую ошибку: Код ошибки: Инициализация: не удалось связаться со службой кеширования. Обратитесь к администратору и обратитесь к справочной документации по продукту, чтобы узнать о возможных причинах.
Я предполагаю, что проблема в моей конфигурации в web.config:
<section name="dcacheClient"
type="Microsoft.ApplicationServer.Caching.DataCacheClientSection, Microsoft.ApplicationServer.Caching.Core"
allowLocation="true"
allowDefinition="Everywhere"/>
...
<dcacheClient deployment="routing" localCache="False">
<localCache isEnabled="false" sync="TimeoutBased" ttlValue="300" />
<hosts>
<host name="localhost" cachePort="22233" cacheHostName="AppFabricCachingService" />
</hosts>
</dcacheClient>
Я загрузил исходный код NHibernate.Caches, чтобы попытаться выяснить, в чем проблема, и что исключение выдается в конструкторе VelocityClient при вызове метода GetCache:
public VelocityClient(string regionName, IDictionary<string, string> properties)
{
region = regionName.GetHashCode().ToString(); //because the region name length is limited
var cacheCluster = new CacheFactory();
cache = cacheCluster.GetCache(CacheName);
try
{
cache.CreateRegion(region, true);
}
catch (CacheException) {}
}
Если я добавлю часы к переменной cacheCluster, я могу найти частную переменную _servers, которая имеет один System.Data.Caching.EndpointID, для которого свойство MyURI установлено на net.tcp: // localhost: 22234 / AppFabricCachingServive, который, как я полагаю, пришел из конфигурации в web.config.
Если вы не знаете точную причину проблемы, но у вас есть идеи, как решить эту проблему, это также будет очень полезно.
Дополнительная информация
Я получаю следующие результаты от команды Get-CacheHostConfig -HostName tn-staylor-02 -CachePort 22233
:
HostName : tn-staylor-02
ClusterPort : 22234
CachePort : 22233
ArbitrationPort : 22235
ReplicationPort : 22236
Size : 3001 MB
ServiceName : AppFabricCachingService
HighWatermark : 90%
LowWatermark : 70%
IsLeadHost : True
Поэтому я думаю, что значения, которые я настроил в web.config, в порядке.
Погуглив эту проблему и исследуя, как настроить AppFabric в первую очередь, я обнаружил два немного разных способа настройки кеша в web.config. То, что я описал выше, и то, как Гензельман изложил это в своем сообщении в блоге AppFabric
На самом деле я начал с этого, но у меня возникла следующая ошибка, из-за которой я пришел к настройке, как у меня сейчас:
ErrorCode: тег dcacheClient не указан в файле конфигурации приложения. Укажите действительный тег в файле конфигурации.
Полная трассировка стека исключения, которое возникает в VelocityClient:
System.Data.Caching.CacheException Произошло сообщение = "ErrorCode: \" dcacheClient \ "тег не указан в файле конфигурации приложения. Укажите допустимый тег в файле конфигурации." Source = "CacheBaseLibrary" ErrorCode = "ERRCMC0004" StackTrace: в System.Data.Caching.ClientConfigFile.ThrowException (String errorCode, String param) в System.Data.Caching.ClientConfigReader.GetDeployementMode () в System.Data.CachingMiguration.Client. InitializeDepMode (ClientConfigReader cfr) в System.Data.Caching.ClientConfigurationManager.Initialize (String path) в System.Data.Caching.ClientConfigurationManager..ctor () в System.Data.Caching.CacheFactory.InitCacheFactory () в System.Data.Caching .CacheFactory.GetCache (String cacheName) в NHibernate.Caches.Velocity.VelocityClient..ctor (String regionName, свойства IDictionary`2) в C: \ Source \ Projects \ NHibernate.contrib \ trunk \ src \ NHibernate.Caches \ Velocity \ NHibernate.Caches.Velocity \ VelocityClient.cs: строка 67 InnerException:
РЕДАКТИРОВАТЬ: добавлен вывод из get-cachehost
по запросу @PhilPursglove
Вывод из get-cachehost
:
HostName : CachePort Service Name Service Status Version Info
-------------------- ------------ -------------- ------------
tn-staylor-02:22233 AppFabricCachingService UP 1 [1,1][1,1]
РЕШЕНИЕ: @PhilPursglove оказался на высоте. Провайдер скорости NHibernate использовал старые библиотеки DLL, поэтому их обновление и внесение нескольких изменений в код решили мои проблемы. Я думал, что включу сюда свое полное решение.
- Загрузил исходный код NHibernate.contrib из репозитория SVN по адресу https://nhcontrib.svn.sourceforge.net/svnroot/nhcontrib/trunk
- Открыл решение NHibernate.Caches.Everything и удалил ссылки на старые DLL-библиотеки скорости из проекта NHibernate.Caches.Velocity.
- Добавлены ссылки на библиотеки DLL App Fabric, которые были установлены при установке App Fabric. Это не обычный случай добавления ссылки на сборку в GAC, но в этой статье описывается, как это сделать.
- Добавление новых ссылок означало, что класс VelocityClient больше не компилировался. С небольшой помощью this я придумал версию VelocityClient.cs, указанную ниже.
- Я добавил ссылку на новую версию NHibernate.Caches.Velocity в свой проект, внес следующие изменения в свою конфигурацию, и все заработало.
VelocityClient.cs
using System;
using System.Collections.Generic;
using Microsoft.ApplicationServer.Caching;
using log4net;
using NHibernate.Cache;
using CacheException = Microsoft.ApplicationServer.Caching.DataCacheException;
using CacheFactory = Microsoft.ApplicationServer.Caching.DataCacheFactory;
namespace NHibernate.Caches.Velocity
{
public class VelocityClient : ICache
{
private const string CacheName = "nhibernate";
private static readonly ILog log;
private readonly DataCache cache;
private readonly string region;
private Dictionary<string, DataCacheLockHandle> locks = new Dictionary<string, DataCacheLockHandle>();
static VelocityClient()
{
log = LogManager.GetLogger(typeof (VelocityClient));
}
public VelocityClient() : this("nhibernate", null) {}
public VelocityClient(string regionName) : this(regionName, null) {}
public VelocityClient(string regionName, IDictionary<string, string> properties)
{
region = regionName.GetHashCode().ToString(); //because the region name length is limited
var cacheCluster = new CacheFactory();
cache = cacheCluster.GetCache(CacheName);
try
{
cache.CreateRegion(region);
}
catch (CacheException) {}
}
#region ICache Members
public object Get(object key)
{
if (key == null)
{
return null;
}
if (log.IsDebugEnabled)
{
log.DebugFormat("fetching object {0} from the cache", key);
}
DataCacheItemVersion version = null;
return cache.Get(key.ToString(), out version, region);
}
public void Put(object key, object value)
{
if (key == null)
{
throw new ArgumentNullException("key", "null key not allowed");
}
if (value == null)
{
throw new ArgumentNullException("value", "null value not allowed");
}
if (log.IsDebugEnabled)
{
log.DebugFormat("setting value for item {0}", key);
}
cache.Put(key.ToString(), value, region);
}
public void Remove(object key)
{
if (key == null)
{
throw new ArgumentNullException("key");
}
if (log.IsDebugEnabled)
{
log.DebugFormat("removing item {0}", key);
}
if (Get(key.ToString()) != null)
{
cache.Remove(region, key.ToString());
}
}
public void Clear()
{
cache.ClearRegion(region);
}
public void Destroy()
{
Clear();
}
public void Lock(object key)
{
DataCacheLockHandle lockHandle = null;
if (Get(key.ToString()) != null)
{
try
{
cache.GetAndLock(key.ToString(), TimeSpan.FromMilliseconds(Timeout), out lockHandle, region);
locks.Add(key.ToString(), lockHandle);
}
catch (CacheException) {}
}
}
public void Unlock(object key)
{
DataCacheLockHandle lockHandle = null;
if (Get(key.ToString()) != null)
{
try
{
if (locks.ContainsKey(key.ToString()))
{
cache.Unlock(key.ToString(), locks[key.ToString()], region);
locks.Remove(key.ToString());
}
}
catch (CacheException) {}
}
}
public long NextTimestamp()
{
return Timestamper.Next();
}
public int Timeout
{
get { return Timestamper.OneMs * 60000; } // 60 seconds
}
public string RegionName
{
get { return region; }
}
#endregion
}
}
NHibernate.config:
...
<property name="cache.provider_class">NHibernate.Caches.Velocity.VelocityProvider, NHibernate.Caches.Velocity</property>
<property name="cache.use_second_level_cache">true</property>
<property name="cache.use_query_cache">true</property>
...
web.config
...
<section name="dataCacheClient"
type="Microsoft.ApplicationServer.Caching.DataCacheClientSection, Microsoft.ApplicationServer.Caching.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
allowLocation="true"
allowDefinition="Everywhere"/>
...
<dataCacheClient>
<!-- cache host(s) -->
<hosts>
<host
name="localhost"
cachePort="22233"/>
</hosts>
</dataCacheClient>
...
Я больше не вносил никаких изменений в конфигурацию App Fabric или что-то еще.
get-cachehost
? - person PhilPursglove   schedule 13.07.2010