nhibernate - AppFabric:无法联系缓存服务

标签 nhibernate appfabric

更新:我现在已经正确实现了。有关更多信息,请参见我的blog post

我正在尝试将AppFabric与NHibernate一起用作我的第二级缓存提供程序,但是出现以下错误:ErrorCode:Initialization:无法联系缓存服务。请与管理员联系并参阅产品帮助文档以了解可能的原因。

我认为问题出在我在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源代码,以尝试发现问题出在哪里,并且在调用GetCache方法时在VelocityClient构造函数中引发了异常:

  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中的缓存。我上面描述的方式以及Hanselman在他的AppFabric blog post中拥有的方式

我实际上是从这样开始的,但是,出现了以下错误,这就是我如何对其进行配置的方式:

未在应用程序配置文件中指定错误代码:“ dcacheClient”标记。在配置文件中指定有效标签。



在VelocityClient中引发的异常的完整堆栈跟踪:

发生System.Data.Caching.CacheException
在应用程序配置文件中未指定Message =“ ErrorCode:\” dcacheClient \“标签。在配置文件中指定有效标签。
Source =“ CacheBaseLibrary”
ErrorCode =“ ERRCMC0004”
堆栈跟踪:
在System.Data.Caching.ClientConfigFile.ThrowException(String errorCode,String param)
在System.Data.Caching.ClientConfigReader.GetDeployementMode()
在System.Data.Caching.ClientConfigurationManager.InitializeDepMode(ClientConfigReader cfr)
在System.Data.Caching.ClientConfigurationManager.Initialize(字符串路径)
在System.Data.Caching.ClientConfigurationManager..ctor()
在System.Data.Caching.CacheFactory.InitCacheFactory()
在System.Data.Caching.CacheFactory.GetCache(String cacheName)
在NHibernate.Caches.Velocity.VelocityClient..ctor(字符串regionName,IDictionary`2属性)在C:\ Source \ Projects \ NHibernate.contrib \ trunk \ src \ NHibernate.Caches \ Velocity \ NHibernate.Caches.Velocity \ VelocityClient中。 cs:第67行
InnerException:



编辑:按照@PhilPursglove的要求,添加了get-cachehost的输出

get-cachehost的输出:

HostName : CachePort      Service Name            Service Status Version Info
--------------------      ------------            -------------- ------------
tn-staylor-02:22233       AppFabricCachingService UP             1 [1,1][1,1]




解决方案:@PhilPursglove在现场。 NHibernate速度提供程序正在使用旧的dll,因此升级它们并进行一些代码更改解决了我的问题。我以为我会在这里包括完整的解决方案。


https://nhcontrib.svn.sourceforge.net/svnroot/nhcontrib/trunk的SVN存储库下载了NHibernate.contrib源。
打开NHibernate.Caches.Everything解决方案,并从NHibernate.Caches.Velocity项目中删除对旧的dll的引用。
添加了对在我安装App Fabric时安装的App Fabric dll的引用。这不是在GAC中添加对程序集的引用的正常情况,而是this article describes how to do it
添加新引用意味着不再编译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配置进行任何进一步的更改。

最佳答案

我认为这里有两个可能的罪魁祸首:


hosts元素下的web.config中,您列出了localhost-我尝试将其替换为实际的服务器名称tn-staylor-02
该异常堆栈跟踪指向CacheBaseLibrary-我对NHibernate知之甚少(但无所不知!),但我可能会猜测,可能不是使用AppFabric的发行版构建的缓存-CacheBaseLibrary是一个程序集出现在CTP和Beta中,但我不认为它用于RTM版本。请注意,在dcacheclient的section元素中,它引用Microsoft.ApplicationServer.Caching.Core程序集。

关于nhibernate - AppFabric:无法联系缓存服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3233792/

相关文章:

c# - 使用Linq-to-Nhibernate从50多个表中获取数据

c# - 使用 C# 的 AppFabric 缓存示例

azure - Azure Development Fabric 有哪些限制?

AppFabric - 将数据放入本地缓存

asp.net - 哪个版本的 ASP.NET 支持使用 Windows AppFabric 缓存进行 session 管理

azure - 应用程序结构缓存监视器

c# - 如何使用 linq 使用 hibernate queryover 连接两列

c# - LINQ group by 多个计数

.net - 带有 nhibernate 的 mysql 连接太多

NHibernate CompositeUserType : How to specify Sql Types?