2010-07-13 100 views
18

更新:我現在已經正確實施了。欲瞭解更多信息,請參閱我的blog postAppFabric:無法聯繫緩存服務

我想與NHibernate一起使用AppFabric作爲我的二級緩存提供程序,但出現以下錯誤:ErrorCode:Initialization:Could not contact the cache service。聯繫管理員並參考產品幫助文檔查找可能的原因。

我相信這個問題是我在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,其具有具有MyURI prope一個System.Data.Caching.EndpointID私有變量rty設置爲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

我真正開始使用它像這樣不過,我有以下錯誤是怎麼來有它配置我怎麼也得現在:

ErrorCode:應用程序配置文件中未指定「dcacheClient」標記。在配置文件中指定有效的標籤。即獲取VelocityClient拋出的異常的


完整堆棧跟蹤:

System.Data.Caching.CacheException發生 消息=「錯誤代碼:\」應用程序配置文件中指定dcacheClient \」標籤。在配置文件中指定有效的標籤。「 源= 「CacheBaseLibrary」 錯誤碼= 「ERRCMC0004」 堆棧跟蹤: 在System.Data.Caching.ClientConfigFile.ThrowException(字符串的errorCode,字符串PARAM) 在System.Data.Caching.ClientConfigReader.GetDeployementMode() 在系統。 Data.Caching.ClientConfigurationManager。InitializeDepMode(ClientConfigReader CFR) 在System.Data.Caching.ClientConfigurationManager.Initialize(字符串路徑) 在System.Data.Caching.ClientConfigurationManager..ctor() 在System.Data.Caching.CacheFactory.InitCacheFactory() 在系統.Data.Caching.CacheFactory.GetCache(String cacheName) at NHibernate.Caches.Velocity.VelocityClient..ctor(String regionName,IDictionary`2 properties)in C:\ Source \ Projects \ NHibernate.contrib \ trunk \ src \ NHibernate .Caches \速度\ NHibernate.Caches.Velocity \ VelocityClient.cs:線67 的InnerException:


EDIT:從get-cachehost相加的輸出作爲由@PhilPursglove

請求

輸出從get-cachehost

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

SOLUTION:@PhilPursglove是點上。 NHibernate速度提供者正在使用舊的dll,所以升級它們,並使一些代碼更改解決了我的問題。我想我會在這裏包括我的完整解決方案。

  1. 下載從SVN倉庫的NHibernate.contrib源在https://nhcontrib.svn.sourceforge.net/svnroot/nhcontrib/trunk
  2. 開闢了NHibernate.Caches.Everything溶液中取出舊的速度dll的從NHibernate.Caches.Velocity項目的引用。
  3. 新增了對我在安裝App Fabric時安裝的App Fabric dll的參考。這不是在GAC中添加對組件的引用的正常情況,而是this article describes how to do it
  4. 添加新引用意味着VelocityClient類不再編譯。從this獲得一點點幫助,我想到了下面的VelocityClient.cs版本。
  5. 我添加了一個對新版本的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> 
... 

我沒有對我的應用程序結構配置或任何其他進行任何更改。

+0

您的緩存是否正在運行? get-cachehost的輸出是什麼? – PhilPursglove 2010-07-13 08:57:31

+0

@PhilPursglove,是的緩存正在運行,我已經從get-cachehost的輸出添加到原來的問題。感謝您抽出時間發表評論 – s1mm0t 2010-07-13 13:29:05

+0

很高興您解決它!您應該將這些NHibernate變更提交回幹線,這樣沒有人會發現這個問題。 – PhilPursglove 2010-07-15 07:45:35

回答

6

我覺得這裏有兩種可能的罪魁禍首:

  1. 在您的網頁。在hosts元素的配置,您列出localhost - 我想嘗試換是出於對實際的服務器名稱tn-staylor-02

  2. 這異常堆棧跟蹤是指CacheBaseLibrary - 我不知道一個很大的(閱讀:什麼!)關於NHibernate,但我會冒險猜測,該緩存可能不會與AppFabric的發佈版本一起構建--CacheBaseLibrary是一個出現在CTP和Beta版中的程序集,但我認爲它並未用於RTM版本。請注意,在dcacheclient的部分元素中,它指的是Microsoft.ApplicationServer.Caching.Core部件。

+0

我已經嘗試過使用tn-staylor-02,但沒有任何運氣,但它確實顯示出您可能正在使用緩存基礎庫。我將嘗試交換最新的程序集,並且可能還需要更新代碼 - 我會讓你知道我如何繼續。 – s1mm0t 2010-07-13 15:46:38