gpt4 book ai didi

asp.net - 多个实例使用共置缓存但无法访问,需要良好的命名缓存实现

转载 作者:行者123 更新时间:2023-12-03 03:18:36 25 4
gpt4 key购买 nike

我们一直在将我们的服务和 MVC4 网站转移到云端,总体来说这个过程进展顺利。除了缓存之外,由于我们已经迁移到 Azure,因此使用 azure 提供的某种缓存也是明智的。我们选择并置/专用缓存角色,其优点是缓存可用于所有实例。

设置缓存工作正常,我有一个命名的缓存客户端,我只在需要时才初始化它。它设置在 Controller 的继承层中。一旦调用其中一个函数,它就会检查与数据缓存的连接是否仍然存在或是否已创建。这一切似乎工作正常,但我正在构建一个模块来检索价格。多个ajax插入(使用javascript插入页面的 View )使用这些函数,其中一些函数由多个ajax View 同时调用。其中一些 View 然后返回 404 或 500 错误,除了无效的缓存或类似的东西之外,我无法解释这些错误来自哪里。

有人可以帮助我很好地实现命名缓存(并置或专用),因为我能找到的只是许多说明 DataCacheFactory 初始化的示例,而不是说明数据插入和检索的示例。

下面是我现在拥有的代码,我尝试了更多使用锁定等的方法,但到目前为止这个方法效果最好。

private static object magicStick = new object();

private static DataCacheFactory dcf = null;
private static DataCache priceCache = null;

protected void CreateCacheFactory()
{
dcf = new DataCacheFactory();

}
protected void CreatePricesCache()
{
if (dcf == null)
{
CreateCacheFactory();
}
priceCache = dcf.GetCache("Prices");

}
protected PriceData GetPrices(int productID)
{
if (priceCache == null)
{
CreatePricesCache();
}
string cacheKey = "something";
lock (magicStick)
{
PriceData datas = priceCache.Get(cacheKey) as PriceData;
if (datas == null)
{
lock (magicStick)
{
Services svc = new Services();
PriceData pData = svc.PriceService.GetPrices(productID);
if (pData != null && pData.Offers != null && pData.Offers.Count() > 0)
{
datas = pData;
datas.Offers = datas.Offers.OrderBy(pr => (pr.BasePrice + pr.ShippingCosts)).ToArray();
priceCache.Add(cacheKey, datas, new TimeSpan(0, cachingTimePricesKK, 0));
}
}
}
return datas;
}
}

一旦我到达有价格表的页面,并且使用相同的参数多次调用上面的函数,它有 5-10% 的机会返回错误而不是返回结果。谁能帮助我,我已经被这个问题困扰了一个星期了,它让我内心疲惫不堪。

最佳答案

首先,我会将您的缓存和cacheFactory 实例化移出您的getPrices 方法。另外,评估您对锁的需求 - 这可能会导致超时。另一个非常重要的观察结果 - 您正在使用恒定的缓存键并使用相同的缓存键为每个 ProductId 保存/检索数据。您应该使用如下缓存键:var cacheKey = string.format("priceDatabyProductId-{0}", ProductId);。您需要设置一些断点并准确检查正在缓存的内容以及从缓存中检索的内容。编写的代码会将第一个productId保存到缓存中,然后无论productId如何,都会继续返回该数据。

这是我们在生产中使用专用缓存角色中的“默认”命名缓存的完整工作示例:

public static class MyCache
{
private static DataCacheFactory _cacheFactory = null;
private static DataCache ACache
{
get
{
if (_cacheFactory == null)
{
try
{
_retryPolicy.ExecuteAction(() => { _cacheFactory = new DataCacheFactory(); });
return _cacheFactory == null ? null : _cacheFactory.GetDefaultCache();
}
catch (Exception ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
return null;
}
}

return _cacheFactory.GetDefaultCache();
}
}

public static void FlushCache()
{
ACache.Clear();
}

// Define your retry strategy: retry 3 times, 1 second apart.
private static readonly FixedInterval _retryStrategy = new FixedInterval(3, TimeSpan.FromSeconds(1));

// Define your retry policy using the retry strategy and the Windows Azure storage
// transient fault detection strategy.
private static RetryPolicy _retryPolicy = new RetryPolicy<StorageTransientErrorDetectionStrategy>(_retryStrategy);

// Private constructor to prevent instantiation
// and force consumers to use the Instance property
static MyCache()
{ }

/// <summary>
/// Add an item to the cache with a key and set a absolute expiration on it
/// </summary>
public static void Add(string key, object value, int minutes = 90)
{
try
{
_retryPolicy.ExecuteAction(() => { ACache.Put(key, value, TimeSpan.FromMinutes(minutes)); });
}
catch (Exception ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
}
}

/// <summary>
/// Add the object with the specified key to the cache if it does not exist, or replace the object if it does exist and set a absolute expiration on it
/// only valid for Azure caching
/// </summary>
public static void Put(string key, object value, int minutes = 90)
{
try
{
_retryPolicy.ExecuteAction(() => { ACache.Put(key, value, TimeSpan.FromMinutes(minutes)); });
}
catch (Exception ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
}
}

/// <summary>
/// Get a strongly typed item out of cache
/// </summary>
public static T Get<T>(string key) where T : class
{
try
{
object value = null;

_retryPolicy.ExecuteAction(() => { value = ACache.Get(key); });

if (value != null) return (T) value;
return null;
}
catch (DataCacheException ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
return null;
}
catch (Exception ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
return null;
}
}
/// <summary>
/// Microsoft's suggested method for cleaning up resources such as this in a static class
/// to ensure connections and other consumed resources are returned to the resource pool
/// as quickly as possible.
/// </summary>
public static void Uninitialize()
{
if (_cacheFactory == null) return;
_cacheFactory.Dispose();
_cacheFactory = null;
}
}

注意:这还使用企业库中的 transient 故障处理 block 来进行 transient 异常故障处理。

关于asp.net - 多个实例使用共置缓存但无法访问,需要良好的命名缓存实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17279603/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com