RedisTimeoutException сбивает мое основное приложение aspnet - PullRequest
9 голосов
/ 18 мая 2019

Когда трафик моего приложения становится высоким, 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 ]

3 голосов
/ 05 июня 2019

Вы пытались поместить блок, который выбрасывает исключение, в блок try / catch?И, возможно, сделайте это несколько раз с Полли, когда будет тайм-аут.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 голосов
/ 05 июня 2019

Как вы создаете ConnectionMultiplexer экземпляров?

Возможно, вы не используете повторно экземпляр мультиплексора и не создаете много соединений.

* ConnectionMultiplexerобъект должен быть разделен и повторно использован вызывающими.Не рекомендуется создавать ConnectionMultiplexer для каждой операции.Обратитесь к документации StackExchange.Redis здесь для получения дополнительной информации.

Об обработке исключений в Asp.NET Core вы можете использовать диагностическое промежуточное ПО UseExceptionHandler для обработки исключенийво всем мире.Проверьте эту статью для полного объяснения

0 голосов
/ 12 июня 2019

Я согласен с ответом @ thepirat000, причина в ConnectionMultiplexer

Вы можете использовать ConnectionMultiplexer в соответствии с вашим пакетом Redis (StackExchange.Redis или ServiceStack.Redis) и в соответствии с вашей средой развертывания

В моем приложении ядра 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...