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