- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们一直在将我们的服务和 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/
嗨,我正在考虑开发一种文件传输程序,想知道我是否想要尽可能好的加密,我应该使用什么? 我会用 C# 开发它,所以我可以访问 .net 库 :P在我的 usb 上有一个证书来访问服务器是没有问题的,如果
我创建的这个计算两个数组的交集是线性的方法的复杂度(在良好、平均、最差的情况下)? O(n) public void getInt(int[] a,int[] b){ int i=0; int
我已经能够使用 RTCPeerConnection.getStats() API 获得 WebRTC 音频调用的各种统计信息(抖动、RTT、丢包等)。 我需要将整体通话质量评为优秀、良好、一般或差。
基本问题: 如果我正在讲述/修改数据,我应该通过索引硬编码索引访问文件的元素,即 targetFile.getElement(5);通过硬编码标识符(内部翻译成索引),即 target.getElem
在 Linux 上,我想知道要调用什么“C”API 来获取每个 CPU 的统计信息。 我知道并且可以从我的应用程序中读取 /proc/loadavg,但这是系统范围的负载平均值,而不是每个 CPU 的
在客户端浏览器中使用 fetch api,GET 或 POST 没有问题,但 fetch 和 DELETE 有问题。它似乎将 DELETE 请求方法更改为 OPTIONS。 大多数研究表明是一个cor
我是一名优秀的程序员,十分优秀!