【问题标题】:Azure DataCache InstantiationAzure 数据缓存实例化
【发布时间】:2015-07-07 01:45:43
【问题描述】:

我正在创建一个新的 MVC 应用程序以从 Azure 数据缓存中提取数据。但是,一旦我尝试实例化 DataCache 对象,我的代码就会无限期地挂起。我没有收到错误或超时,它只是坐在那里尝试创建新对象。

目前我的代码实际上不过是:

public ActionResult Index()
{
  DataCache cache = new DataCache();
  Debugger.break;
}

buts 永远不会超过 new DataCache() 声明。如果我在 Visual Studio 中暂停调试器,我可以看到它在 new DataCache() 行上暂停,所以这绝对是执行停止的地方。

当我导入新的 azure 缓存包时,我的 web.config 包含 NuGet 添加的部分,如下所示:

<dataCacheClients>
  <dataCacheClient name="default">
    <!--To use the in-role flavor of Windows Azure Caching, set identifier to be the cache cluster role name -->
    <!--To use the Windows Azure Caching Service, set identifier to be the endpoint of the cache cluster -->
    <autoDiscover isEnabled="true" identifier="{{REMOVED}}" />

    <!--<localCache isEnabled="true" sync="TimeoutBased" objectCount="100000" ttlValue="300" />-->

    <!--Use this section to specify security settings for connecting to your cache. This section is not required if your cache is hosted on a role that is a part of your cloud service. -->
    <securityProperties mode="Message" sslEnabled="false">
      <messageSecurity authorizationInfo="{{REMOVED}}" />
    </securityProperties>
  </dataCacheClient>
</dataCacheClients>

我已经仔细检查了 web.config 中的值与 Azure 门户中的值是否匹配。

有人知道这是什么原因吗?鉴于它是多么的新,我猜它是非常基本的东西。

【问题讨论】:

  • 您使用的是什么类型的缓存?同地办公、专用角色还是共享?
  • 如下:-缓存产品-基本缓存内存-1GB位置-西欧;如何确定“类型”?在 Azure 门户中,我去了:New>Data Services>Cache (Preview) 并在那里设置...

标签: azure azure-caching


【解决方案1】:

我对面有个开发人员在使用 IIS Express 时无法访问缓存。

当他切换到 IIS Proper 时,它可以工作。

【讨论】:

    【解决方案2】:

    您正在使用共享缓存(缓存服务预览版) - 其他两个选项是“角色”缓存 - 更多信息请访问 Windows Azure Cache。假设您在配置中的所有设置都是正确的,那么,您没有正确实例化缓存。阅读How to Use Windows Azure Cache Service (Preview)。您需要使用:

    DataCache cache = new DataCache("default");
    

    或:

    // Cache client configured by settings in application configuration file.
    DataCacheFactory cacheFactory = new DataCacheFactory();
    DataCache cache = cacheFactory.GetDefaultCache();
    // Or DataCache cache = cacheFactory.GetCache("default");
    // cache can now be used to add and retrieve items.
    

    最后,创建缓存对象的成本很高——您应该为缓存创建一个新的单例类,以便创建一次——而不是每次调用操作时。以下是单例类的完整示例:

    public static class MyCache
    {
        private static DataCacheFactory _cacheFactory = null;
        private static ObjectCache Cache
        {
            get
            {
                return MemoryCache.Default;
            }
        }
    
        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
            {
                if (RoleEnvironment.IsAvailable)
                {
                    _retryPolicy.ExecuteAction(() => { ACache.Put(key, value, TimeSpan.FromMinutes(minutes)); });
                }
                else
                {
                    Cache.Add(key, value, new CacheItemPolicy { AbsoluteExpiration = DateTime.Now + 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
            {  
                if (RoleEnvironment.IsAvailable)
                {
                    _retryPolicy.ExecuteAction(() => { ACache.Put(key, value, TimeSpan.FromMinutes(minutes)); });
                }
                else
                {
                    Cache.Add(key, value, new CacheItemPolicy { AbsoluteExpiration = DateTime.Now + 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;
    
                if (RoleEnvironment.IsAvailable)
                {
                    _retryPolicy.ExecuteAction(() => { value = ACache.Get(key); });
                }
                else
                {
                    value = Cache[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;
        }
    }
    

    【讨论】:

    • 感谢您的信息。最有用。根据文档,DataCache cache = new DataCache("default") 与 DataCache cache = new DataCache() 相同。我也尝试过使用 DataCacheFactory cacheFactory = new DataCacheFactory(); DataCache 缓存 = cacheFactory.GetDefaultCache();根据您上面的代码,并且永远不会超过第一条语句....任何想法为什么会这样?
    • 如果您在本地运行,您是否在 Azure 模拟器中运行?
    • 针对 Azure 模拟器运行什么?这是一个独立的 MVC 应用程序。我只是尝试将缓存设置为 Azure 托管缓存,而不是服务器上的进程内缓存。
    • 您是否已将 Windows Azure Caching Nuget 包添加到您的项目中?
    • 是的,事实上我只是按照 Scott Gu 的公告博客 (weblogs.asp.net/scottgu/archive/2013/09/03/…) 中的步骤进行操作 - 请参阅创建缓存和使用缓存的部分
    【解决方案3】:

    您确实添加了正确的 NuGet 包。您使用的是缓存服务(预览版)的基本产品,而不是共享缓存 - 已被弃用。

    在标识符字段中,您是否指定了完整的端点名称 - [yourcachename].cache.windows.net?

    【讨论】:

      【解决方案4】:

      这是我的猜测,基于我自己的经验。我打赌您正在使用缓存服务预览版,您正在尝试从本地网络(而不是从 Azure 实例)访问,并且您的网络会阻止出站 tcp 端口(正如许多公司默认情况下所做的那样)。

      你说没有超时,但你等了多久?我发现在这种情况下失败需要花费过多的时间(也许几分钟?),但它们确实来了。异常表明缓存客户端尝试使用的端口号。我已经看到端口 22233 和 22234,这两个端口都在我的公司网络上被阻止。当我说服我的 IT 团队允许流量通过这些端口时,问题就消失了。

      我还没有找到缓存客户端可能想要使用的所有端口的文档,也没有关于该主题的论坛帖子得到答复。

      【讨论】:

        【解决方案5】:

        我发现 DataCache 构造函数由于性能计数器初始化而无限期挂起。我已经看到了各种可能导致问题的报告,例如安装 Office 2013。

        我已经通过运行ClientPerfCountersInstaller.exe 解决了这个问题,该ClientPerfCountersInstaller.exe 在您安装 Azure 缓存 NuGet 包时添加到您的项目中。

        使用管理权限和cd 打开一个命令提示符到此文件夹。然后使用以下命令运行安装程序:

        ClientPerfCountersInstaller.exe install
        

        之后我的项目运行没有挂起。

        【讨论】:

          【解决方案6】:

          我一直在努力解决这个问题几个小时,直到我遇到了解释它的堆栈溢出。 TL;DR:最新版本的软件包与 SDK 的 2.3 版本不能很好地配合。当我回滚到 Azure 缓存 2.1 时,一切正常。

          Exception while using Windows Azure Caching : No such host is known

          【讨论】:

            【解决方案7】:

            我从 Hours 开始就一直在解决这个问题,并通过卸载 SDK v2.6 并安装 SDK 2.4 来解决。

            请参阅下面的说明。 https://www.nuget.org/packages/Microsoft.WindowsAzure.Caching/2.4.0

            【讨论】:

              猜你喜欢
              • 2017-05-14
              • 1970-01-01
              • 1970-01-01
              • 2013-08-20
              • 1970-01-01
              • 2013-02-28
              • 2012-08-06
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多