RedisTimeoutException崩溃了我的aspnet核心应用程序

时间:2019-05-18 00:15:09

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

当我的应用程序流量很高时,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

3 个答案:

答案 0 :(得分:3)

您是否尝试过将引发异常的块放在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.
        });
    }
}

答案 1 :(得分:2)

您如何创建ConnectionMultiplexer实例?

也许您不是在复用复用器实例并创建大量连接。

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

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

答案 2 :(得分:0)

我同意@ 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