【问题标题】:How to initiate a Redis Connection in the background without awaiting [closed]如何在不等待的情况下在后台启动 Redis 连接 [关闭]
【发布时间】:2021-02-06 04:50:00
【问题描述】:

我想将 Redis 连接作为后台任务启动,以便用户无需等待 Redis 连接建立。如果 Redis 连接未建立或 Redis 不可用,则应从源获取数据,而不影响用户。

该应用程序是一个 AWS Lambda Web API 项目。我想避免单个请求中的连接延迟,但我也不想在启动时等待连接来增加冷启动时间。

我正在使用 StackExchange Redis 客户端库。

为了完成这个,我想在后台任务中启动 Redis 连接。

【问题讨论】:

  • 这太模糊了——对于什么样的应用程序? the user need not await for the Redis connection to get established 是什么意思?对于桌面应用程序,这意味着 UI 不会冻结。 Web 应用程序在等待时不会冻结。 in thread safe manner 对您的代码意味着什么?如果您不修改全局状态,则没有风险,假设您的 Redis 库具有异步方法,那么简单的 await myClient.ConnectAsync() 就可以了
  • 这些事情都与线程安全或冻结无关。您要求使用后备缓存。这与线程无关,并且...可能已经通过the distributed caching middleware 至少部分实现了
  • 这是XY Problem 的情况。你有一个问题 X(如何使用 Redis 回退到另一个源)并假设 Y 是解决方案(后台线程),所以当事情不工作时,你询问 Y。但在这种情况下 Y 无关与 X
  • @Shaheer ********如果您这样做,您仍然需要等待********。无论如何,发布您的真实代码。
  • 没有理由这样做。并不是人们不理解你的问题。你问的是错误的问题。如果您想测试连接在启动时进行。后续连接不会花费那么长时间。如果需要,请添加 Redis 健康检查。如果您怀疑连接会中断,请编写代码,使其回退到数据库或您拥有的任何其他来源。

标签: c# .net-core redis aws-lambda stackexchange.redis


【解决方案1】:

无需额外的后台任务。 StackExchange.Redis 库允许与ConnectionMultiplexer.ConnectAsync 进行异步连接。需要一种方法来检查该连接是否完整,如果不完整,请使用其他来源。

做到这一点的一种方法是将数据访问包装在服务中,该服务在其构造函数中异步打开连接。它的方法可以检查连接是否打开,如果没有,则使用 Redis 或备用源(例如数据库)。

class MyFallbackService
{
    Task<ConnectionMultiplexer> _redisTask;

    public MyFallbackService(string redisConf,string conString)
    {
        _redisTask = ConnectionMultiplexer.ConnectAsync(redisConf);
        ...
    }

    public async Task<string> GetValue(string key)
    {
        if (_redisTask.IsCompleted)
        {
            var redis=_redisTask.Result;
            var db=redis.GetDatabase(...);
            var value= await db.StringGetAsync(key);
        }
        else
        {
            //Use the fallback source
        }
    }
}

此服务可以在Startup.ConfigureServices 中创建并注册为单例实例。这样连接过程将在启动时开始,但不会阻塞启动过程:

services.AddSingleton(new MyFallbackService(...));

【讨论】:

  • 非常感谢 Panagiotis Kanavos。看起来很有希望。在这个实现中,连接实际上会开始。
  • ConnectAsync 被调用时。但是线程在等待它完成时不会阻塞。这与在数据库连接中调用OpenAsync() 相同。在这两种情况下,您都可以立即或稍后返回您可以await 的任务。即使await 也不会阻塞调用线程。它释放它,一旦异步操作完成,执行将在await 之后恢复。与此同时,该线程可用于服务其他请求
  • 如果任务中发生任何异常,如果我想重新启动任务,那么如何在上述实现中完成。
  • 在等待任务或调用.Result 时会引发异常。如果您想以不同的方式处理错误,请创建一个将异步操作包装在 try/catch 中的方法,记录错误等,然后从构造函数调用该方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-03
  • 2019-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多