2010-07-13 18 views
18

Aggiornamento: Ora l'ho implementato correttamente. Per maggiori informazioni vedi il mio blog post a riguardo.AppFabric: impossibile contattare il servizio cache

Sto cercando di utilizzare AppFabric con NHibernate come provider di cache di secondo livello, ma ricevo il seguente errore: ErrorCode: Inizializzazione: impossibile contattare il servizio cache. Contattare l'amministratore e fare riferimento alla documentazione della guida del prodotto per possibili motivi.

Presumo che il problema è con la mia configurazione nel 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> 

Ho scaricato il codice sorgente di NHibernate.Caches per cercare di scoprire dove sta il problema e l'eccezione viene gettata nel costruttore VelocityClient quando il metodo GetCache si chiama:

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

Se posso aggiungere un orologio alla variabile cacheCluster, posso trovare un _servers variabile privata che ha una System.Data.Caching.EndpointID che ha la prope MyURI rty set to net.tcp: // localhost: 22234/AppFabricCachingServive che presumo provenga dalla configurazione in web.config.

Se non si conosce la causa esatta del problema ma si hanno alcune idee su come risolvere questo problema, sarebbe molto apprezzato.

Altre Informazioni


io ottenere i seguenti risultati del comando, 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 

Quindi penso che il valore c'ho configurato in web.config sono OK.


Googling questo problema e investigando come impostare AppFabric, in primo luogo, mi sono imbattuto in due modi leggermente diversi su come configurare la cache in web.config. Il modo in cui ho descritto sopra e il modo in cui Hanselman ha nel suo AppFabric blog post

realtà ho iniziato con in questo modo però, ho ricevuto il seguente errore che è come mi è venuto di averlo configurato come devo subito:

ErrorCode: tag "dcacheClient" non specificato nel file di configurazione dell'applicazione. Specifica un tag valido nel file di configurazione.


traccia dello stack completo l'eccezione che viene gettato in VelocityClient:

System.Data.Caching.CacheException verificato Messaggio = "ErrorCode: \" tag dcacheClient \" non specificato nel file di configurazione dell'applicazione Specificare un tag valido nel file di configurazione. " Source = "CacheBaseLibrary" ErrorCode = "ERRCMC0004" StackTrace: a System.Data.Caching.ClientConfigFile.ThrowException (String errorCode, String param) a System.Data.Caching.ClientConfigReader.GetDeployementMode() al sistema. Data.Caching.ClientConfigurationManager.InitializeDepMode (ClientConfigReader CFR) a System.Data.Caching.ClientConfigurationManager.Initialize (string path) a System.Data.Caching.ClientConfigurationManager..ctor() a System.Data.Caching.CacheFactory.InitCacheFactory() presso System .Data.Caching.CacheFactory.GetCache (String cacheName) in NHibernate.Caches.Velocity.VelocityClient..ctor (String regionName, IDictionary`2 proprietà) in C: \ Source \ Projects \ NHibernate.contrib \ trunk \ src \ NHibernate .Caches \ Velocity \ NHibernate.Caches.Velocity \ VelocityClient.cs: linea 67 InnerException:


EDIT: Rese da get-cachehost come richiesto dal @PhilPursglove

uscita da get-cachehost:

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

SOLUZIONE: @PhilPursglove era perfetto. Il provider di velocità di NHibernate stava usando vecchi dll per aggiornarli e fare alcune modifiche al codice ha risolto i miei problemi. Ho pensato di includere la mia soluzione completa qui.

  1. scaricato i sorgenti NHibernate.contrib dal repository SVN a https://nhcontrib.svn.sourceforge.net/svnroot/nhcontrib/trunk
  2. aperto la soluzione NHibernate.Caches.Everything e rimossi i riferimenti ai vecchi velocità dll dal progetto NHibernate.Caches.Velocity.
  3. Aggiunti riferimenti alle dll di App Fabric che sono state installate durante l'installazione di App Fabric. Questo non è il caso normale di aggiungere un riferimento a un assembly nel GAC, ma this article describes how to do it.
  4. L'aggiunta dei nuovi riferimenti ha significato che la classe VelocityClient non è più compilata. Con un po 'di aiuto da this ho trovato la versione di VelocityClient.cs qui sotto.
  5. Ho aggiunto un riferimento alla nuova versione di NHibernate.Caches.Velocity al mio progetto, apportato le modifiche di seguito alla mia configurazione e tutto ha funzionato.

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> 
... 

Non ho apportato ulteriori modifiche alla mia configurazione di App Fabric o altro.

+0

La cache è in esecuzione? Qual è l'output di 'get-cachehost'? – PhilPursglove

+0

@PhilPursglove, sì la cache è in esecuzione e ho aggiunto l'output di get-cachehost alla domanda originale. Grazie per aver il tempo di commentare – s1mm0t

+0

Contento che l'abbia risolto! È necessario inviare le modifiche di NHibernate al trunk in modo che nessun altro possa ottenere questo problema. – PhilPursglove

risposta

6

Penso che ci siano due possibili colpevoli qui:

  1. del Web.config sotto l'elemento hosts hai messa localhost - mi piacerebbe provare scambiando che per il nome effettivo del server tn-staylor-02

  2. Questo stack eccezione si riferisce alla CacheBaseLibrary - non so molto (leggi: niente !) su NHibernate ma rischierei di indovinare che quella cache potrebbe non essere costruita con la versione di AppFabric - CacheBaseLibrary era un assembly che appariva nei CTP e nelle beta ma non pensavo che fosse usato nella versione RTM. Si noti che nell'elemento section per dcacheclient, fa riferimento all'assembly Microsoft.ApplicationServer.Caching.Core.

+0

Ho provato a usare tn-staylor-02 senza fortuna, ma sembra che si possa fare qualcosa con la libreria di base della cache. Cercherò di fare lo swapping negli ultimi assembly e probabilmente avrò bisogno di aggiornare il codice - ti farò sapere come andrò avanti. – s1mm0t

Problemi correlati