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

RedisTimeoutException is crashing my aspnet core application

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

没有成功....

有什么帮助吗?

感谢

你试过把抛出异常的块放在try/catch块中吗?也许在超时时让它与 Polly 尝试几次。 https://github.com/App-vNext/Polly

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

如果您像下面这样创建一个服务 class,您可以封装所有的 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.
        });
    }
}

您如何创建 ConnectionMultiplexer 个实例?

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

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

关于 Asp.NET Core 上的异常处理,可以使用 UseExceptionHandler diagnostic middleware to handle exceptions globally. Check this article 完整的解释

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

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

在我的 aspnet 核心应用程序(像你一样)中,我使用了 StackExchange.Redis 并且我已经部署到 windows 服务器,在 Startup.cs 设置

以下没有任何错误
        #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