Cập nhật: Tôi hiện đã triển khai đúng cách này. Để biết thêm thông tin, hãy xem blog post về thông tin đó.AppFabric: Không thể liên hệ với dịch vụ bộ nhớ cache
Tôi đang cố gắng sử dụng AppFabric với NHibernate làm nhà cung cấp bộ nhớ cache cấp thứ hai nhưng tôi nhận được lỗi sau: ErrorCode: Khởi tạo: Không thể liên hệ với dịch vụ bộ nhớ cache. Liên hệ với quản trị viên và tham khảo tài liệu trợ giúp sản phẩm vì các lý do có thể xảy ra.
Tôi đoán rằng vấn đề là với cấu hình của tôi trong 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>
Tôi đã tải về mã nguồn NHibernate.Caches để thử và khám phá nơi mà vấn đề nằm và ngoại lệ được ném trong constructor VelocityClient khi các phương pháp GetCache được gọi là:
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) {}
}
Nếu tôi thêm một chiếc đồng hồ để biến cacheCluster, tôi có thể tìm thấy một _servers biến tư nhân trong đó có một System.Data.Caching.EndpointID trong đó có các prope MyURI rty thiết lập để net.tcp: // localhost: 22234/AppFabricCachingServive mà tôi đoán đã đến từ cấu hình trong web.config.
Nếu bạn không biết nguyên nhân chính xác của sự cố nhưng có một số ý tưởng về cách khắc phục sự cố này, điều đó cũng sẽ được đánh giá cao.
Thông tin bổ sung
tôi nhận được kết quả như sau từ lệnh, 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
Vì vậy, tôi nghĩ rằng các giá trị tôi đã bị cấu hình trong web.config là OK.
Googling vấn đề này và điều tra cách thiết lập AppFabric ngay từ đầu, tôi đã xem xét hai cách khác nhau về cách cấu hình bộ đệm trong web.config. Con đường tôi đã mô tả ở trên và cách Hanselman có nó trong mình AppFabric blog post
Tôi thực sự bắt đầu với nó như thế này tuy nhiên, tôi đã được lỗi sau đó là làm thế nào tôi đã có nó được cấu hình làm thế nào tôi có nó bây giờ:
ErrorCode: "dcacheClient" không được chỉ định trong tệp cấu hình ứng dụng. Chỉ định thẻ hợp lệ trong tệp cấu hình.
stack trace đầy đủ của ngoại lệ đó được ném vào VelocityClient:
System.Data.Caching.CacheException xảy ra nhắn = "ERRORCODE: \" dcacheClient \ tag" không quy định trong tập tin cấu hình ứng dụng Chỉ định thẻ hợp lệ trong tệp cấu hình. " Source = "CacheBaseLibrary" ERRORCODE = "ERRCMC0004" StackTrace: tại System.Data.Caching.ClientConfigFile.ThrowException (String errorCode, String param) tại System.Data.Caching.ClientConfigReader.GetDeployementMode() tại hệ thống. Data.Caching.ClientConfigurationManager.InitializeDepMode (ClientConfigReader cfr) tại System.Data.Caching.ClientConfigurationManager.Initialize (đường dẫn String) tại System.Data.Caching.ClientConfigurationManager..ctor() tại System.Data.Caching.CacheFactory.InitCacheFactory() tại Hệ thống .Data.Caching.CacheFactory.GetCache (String cacheName) tại NHibernate.Caches.Velocity.VelocityClient..ctor (String regionName, IDictionary`2 properties) trong C: \ Source \ Projects \ NHibernate.contrib \ trunk \ src \ NHibernate .Caches \ Velocity \ NHibernate.Caches.Velocity \ VelocityClient.cs: dòng 67 InnerException:
EDIT: Thêm đầu ra từ get-cachehost
theo yêu cầu của @PhilPursglove
Output từ get-cachehost
:
HostName : CachePort Service Name Service Status Version Info
-------------------- ------------ -------------- ------------
tn-staylor-02:22233 AppFabricCachingService UP 1 [1,1][1,1]
SOLUTION: @PhilPursglove là chỗ trên. Các nhà cung cấp vận tốc NHibernate đã sử dụng dll cũ để nâng cấp chúng và thực hiện một vài thay đổi mã giải quyết vấn đề của tôi. Tôi nghĩ rằng tôi sẽ bao gồm giải pháp hoàn chỉnh của tôi ở đây.
- Downloaded nguồn NHibernate.contrib từ kho SVN tại https://nhcontrib.svn.sourceforge.net/svnroot/nhcontrib/trunk
- Khai trương lên các giải pháp NHibernate.Caches.Everything và loại bỏ các tham chiếu đến vận tốc cũ dll từ dự án NHibernate.Caches.Velocity.
- Đã thêm tài liệu tham khảo vào dll Vải ứng dụng đã được cài đặt khi tôi cài đặt Vải ứng dụng. Đây không phải là trường hợp bình thường khi thêm một tham chiếu đến một assembly trong GAC, nhưng là this article describes how to do it.
- Thêm các tham chiếu mới có nghĩa là lớp VelocityClient không còn được biên dịch nữa. Với một chút trợ giúp từ this Tôi đã đưa ra phiên bản VelocityClient.cs bên dưới.
- Tôi đã thêm một tham chiếu đến phiên bản mới của NHibernate.Caches.Velocity vào dự án của tôi, thực hiện các thay đổi bên dưới để cấu hình của tôi và mọi thứ hoạt động.
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>
...
Tôi không thực hiện thêm bất kỳ thay đổi nào đối với cấu hình Vải ứng dụng của mình hoặc bất kỳ thứ gì.
Bộ nhớ cache của bạn có đang chạy không? Đầu ra từ 'get-cachehost' là gì? – PhilPursglove
@PhilPursglove, có bộ nhớ cache đang chạy và tôi đã thêm đầu ra từ get-cachehost vào câu hỏi gốc. Cảm ơn bạn đã dành thời gian để bình luận – s1mm0t
Vui vì bạn đã sửa nó! Bạn nên gửi những thay đổi NHibernate trở lại thân cây để không ai khác nhận được vấn đề này. – PhilPursglove