【问题标题】:RedisTimeoutException is crashing my aspnet core applicationRedisTimeoutException 使我的 aspnet 核心应用程序崩溃
【发布时间】:2019-10-05 06:57:58
【问题描述】:

当我的应用程序流量变高时,StackExchange.Redis 开始抛出 RedisTimeoutException,几分钟后,我的 asp.net 核心应用程序崩溃。
Windows 事件查看器显示The process was terminated due to an unhandled exception. Exception Info: StackExchange.Redis.RedisTimeoutException。 好的,我知道我的应用和 Redis 之间存在一些问题,但是我无法解决这个问题,如何防止应用关闭?

startup.cs里面,我试着放了:

TaskScheduler.UnobservedTaskException += (object sender, UnobservedTaskExceptionEventArgs eventArgs) =>
{
    eventArgs.SetObserved();
    eventArgs.Exception.Handle(ex => true);
};

没有成功....

有什么帮助吗?

Tks

【问题讨论】:

    标签: asp.net-core redis stackexchange.redis


    【解决方案1】:

    您是否尝试将引发异常的块放入 try/catch 块中?并且当超时时,也许让它与 Polly 一起尝试几次。 https://github.com/App-vNext/Polly

    通常它不应该终止您的应用程序,但由于您没有共享任何代码,我们无法确定。

    如果你像下面这样创建一个服务类,你可以封装你所有的 redis 调用,从而捕获异常。

    public class EmptyClass
    {
        private readonly ConnectionMultiplexer _connectionMultiplexer;
    
        public EmptyClass(ConnectionMultiplexer connectionMultiplexer)
        {
            _connectionMultiplexer = connectionMultiplexer;
        }
    
        public void Execute(Action<ConnectionMultiplexer> action)
        {
            try
            {
                action.Invoke(_connectionMultiplexer);
            }
            catch(RedisTimeoutException ex)
            {
    
            }
        }
    
        public void TestRun()
        {
            Execute((ConnectionMultiplexer obj) =>
            {
                //do stuff with obj.
            });
        }
    }
    

    【讨论】:

      【解决方案2】:

      您如何创建ConnectionMultiplexer 实例?

      也许您没有重用多路复用器实例并创建大量连接。

      ConnectionMultiplexer 对象应该在调用者之间共享和重用。不建议为每个操作创建一个ConnectionMultiplexer。查看 StackExchange.Redis 文档here 了解更多信息。

      关于 Asp.NET Core 上的异常处理,您可以使用UseExceptionHandler 诊断中间件来全局处理异常。检查this article以获得完整的解释

      【讨论】:

      • 嘿!我们解决了这个问题,现在我们使用池策略,一切都很好,但主要问题是:如何避免应用程序崩溃?
      • 捕获异常。检查thisthis。和@Ahmet 回答
      • 有没有办法在aspnet core中全局捕获redis异常?
      • @Alexandre 我添加了一种方法来全局捕获所有 redis 超时异常到我的答案。
      • @Alexandre 您可以使用全局异常处理程序。检查this
      【解决方案3】:

      我同意@thepirat000 的回答,原因是ConnectionMultiplexer

      您可以根据您的 Redis 包(StackExchange.Redis 或 ServiceStack.Redis)和您的部署环境使用 ConnectionMultiplexer

      在我的 aspnet 核心应用程序(像你一样)中,我使用了 StackExchange.Redis,并且在 Startup.cs 设置下没有任何错误部署到 Windows 服务器

              #region Redis settings ConnectionMultiplexer
              services.AddDataProtection().ProtectKeysWithDpapi(protectToLocalMachine: true);
              services.AddDataProtection()
                  .PersistKeysToFileSystem(new DirectoryInfo(@"c:\temp-keys"))
                  .ProtectKeysWithDpapiNG($"CERTIFICATE=HashId:{thumbPrint}", flags: Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGProtectionDescriptorFlags.None);
              services.AddDataProtection().ProtectKeysWithDpapiNG();
      
              services.Configure<StorageConfiguration>(new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build());
              var redisConf = Configuration.GetSection("RedisConnection").Get<RedisConnection>();
              ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf.Host.ToString() + ":" + redisConf.Port.ToString());
              services.AddDataProtection().PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
              services.AddSingleton<IConnectionMultiplexer>(ConnectionMultiplexer.Connect(redisConf.Host.ToString() + ":" + redisConf.Port.ToString()));
              #endregion
      

      在这里查看基本用法https://stackexchange.github.io/StackExchange.Redis/Basics.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-30
        • 2017-03-26
        • 2011-10-06
        相关资源
        最近更新 更多