2010-07-13 9 views
18

Actualización: he implementado ahora esto correctamente. Para obtener más información, consulte mi blog post al respecto.AppFabric: No se pudo contactar con el servicio de caché

Estoy tratando de usar AppFabric con NHibernate como mi segundo proveedor de caché de nivel, pero me aparece el siguiente error: ErrorCode: Inicialización: no se pudo contactar con el servicio de caché. Póngase en contacto con el administrador y consulte la documentación de ayuda del producto por posibles motivos.

Supongo que el problema es con mi configuración en 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> 

He descargado el código fuente NHibernate.Caches para tratar de descubrir dónde está el problema y la excepción se está lanzando en el constructor VelocityClient cuando se llama al método 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) {} 
    } 

Si añado un reloj para la variable cacheCluster, puedo encontrar un _servers variable privada que cuenta con uno System.Data.Caching.EndpointID que tiene el prope MyURI rty establecido en net.tcp: // localhost: 22234/AppFabricCachingServive, que supongo que proviene de la configuración en web.config.

Si no conoce la causa exacta del problema, pero tienen algunas ideas sobre cómo hacer para solucionar este problema, eso sería muy apreciado también.

Información adicional


me sale el siguiente resultado de la orden, 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 

Así que creo que los valores que tengo configurado en web.config están bien.


googlear este problema e investigar cómo configurar AppFabric, en primer lugar, que han llegado a través de dos formas ligeramente diferentes de cómo configurar la memoria caché en web.config. La forma en que he descrito anteriormente y la forma Hanselman tiene en su AppFabric blog post

De hecho, empecé con él, como esto, sin embargo, tengo el siguiente error que es como llegué a tener que configurar la forma en que tengo ahora:

ErrorCode: etiqueta "dcacheClient" no especificada en el archivo de configuración de la aplicación. Especifique una etiqueta válida en el archivo de configuración.


traza completa de la excepción de que se tira en VelocityClient:

System.Data.Caching.CacheException ocurrió mensaje = "Código de error: \" etiqueta dcacheClient \" no especificado en el archivo de configuración de la aplicación Especifique una etiqueta válida en el archivo de configuración ". Fuente = "CacheBaseLibrary" ErrorCode = "ERRCMC0004" StackTrace: en System.Data.Caching.ClientConfigFile.ThrowException (String errorCode, PARAM String) en System.Data.Caching.ClientConfigReader.GetDeployementMode() en Sistema. Data.Caching.ClientConfigurationManager.InitializeDepMode (cfr ClientConfigReader) en System.Data.Caching.ClientConfigurationManager.Initialize (camino String) en System.Data.Caching.ClientConfigurationManager..ctor() en System.Data.Caching.CacheFactory.InitCacheFactory() en Sistema .Data.Caching.CacheFactory.GetCache (String cacheName) en NHibernate.Caches.Velocity.VelocityClient..ctor (String regionName, IDictionary`2 properties) en C: \ Source \ Projects \ NHibernate.contrib \ trunk \ src \ NHibernate .Caches \ velocidad \ NHibernate.Caches.Velocity \ VelocityClient.cs: línea 67 InnerException:


EDITAR: Añadido salida de get-cachehost a lo solicitado por @PhilPursglove

salida de get-cachehost:

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

SOLUCIÓN: @PhilPursglove era perfecto. El proveedor de velocidad de NHibernate estaba usando dll antiguos, por lo que actualizarlos y hacer algunos cambios en el código resolvió mis problemas. Pensé que incluiría mi solución completa aquí.

  1. descargado la fuente NHibernate.contrib desde el repositorio SVN en https://nhcontrib.svn.sourceforge.net/svnroot/nhcontrib/trunk
  2. abierto la solución NHibernate.Caches.Everything y se elimina las referencias a la velocidad de edad DLL del proyecto NHibernate.Caches.Velocity.
  3. Referencias adicionales a los dll de App Fabric que se instalaron cuando instalé App Fabric. Este no es el caso normal de agregar una referencia a un ensamblaje en el GAC, sino this article describes how to do it.
  4. Agregar las nuevas referencias significaba que la clase VelocityClient ya no se compilaba. Con un poco de ayuda de this, se me ocurrió la versión de VelocityClient.cs a continuación.
  5. Agregué una referencia a la nueva versión de NHibernate.Caches.Velocity en mi proyecto, hice los cambios a continuación en mi configuración y todo funcionó.

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

No realicé ningún otro cambio en la configuración de mi App Fabric ni nada.

+0

¿Está funcionando su caché? ¿Cuál es el resultado de 'get-cachehost'? – PhilPursglove

+0

@PhilPursglove, sí, la caché se está ejecutando y he agregado el resultado de get-cachehost a la pregunta original. Gracias por tomarse el tiempo para comentar – s1mm0t

+0

¡Me alegra que lo hayas solucionado! Debe enviar esos cambios de NHibernate al baúl para que nadie más tenga este problema. – PhilPursglove

Respuesta

6

creo que hay dos posibles culpables aquí:

  1. En su web.config del elemento hosts, estás lista localhost - Me gustaría probar el canje de eso por el nombre real del servidor tn-staylor-02

  2. Ese seguimiento de la pila excepción se refiere a CacheBaseLibrary - No sé mucho (es decir: nada !) sobre NHibernate, pero me atrevería a adivinar que ese caché podría no estar construido con la versión de lanzamiento de AppFabric - CacheBaseLibrary era un ensamblaje que aparecía en los CTP y las versiones beta pero no creía que se utilizara en la versión RTM. Tenga en cuenta que en el elemento de sección para dcacheclient, se refiere al ensamblaje Microsoft.ApplicationServer.Caching.Core.

+0

He intentado usar tn-staylor-02 sin ningún tipo de suerte, pero parece que es posible que tenga algo con la biblioteca de la base de memoria caché. Intentaré intercambiar en las últimas asambleas y probablemente también necesite actualizar el código. Les contaré cómo me llevo. – s1mm0t

Cuestiones relacionadas