无法使用StackExchange.Redis连接到C#中的Azure Redis缓存(超时错误)

e0bqpujr  于 2023-03-19  发布在  Redis
关注(0)|答案(1)|浏览(273)

我正在将Azure Redis缓存(Basic C 0 for dev)集成到我们的一个.Net系统(.Net 4.6.1)中,并使用StackExchange.Redis v2.6.90客户端库。这一切都在Windows环境中运行(10用于本地开发,Server 2019 Std用于测试)
我创建了一个基本的 Package 器来处理连接:

using System;
using System.Net;
using StackExchange.Redis;

namespace Rimes.Azure
{
    public class RedisCache
    {
        private ConnectionMultiplexer _redis;

        private void Initialize(ConfigurationOptions options)
        {
            // Azure requires TLS 1.2 but .Net uses TLS 1.1 by default
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            _redis = ConnectionMultiplexer.Connect(options);
        }

        public RedisCache(string endPoint, string token, bool useSsl = true, bool abortOnConnectFail = true)
        {
            var options = ConfigurationOptions.Parse(endPoint);
            options.Password = token;
            options.Ssl = useSsl;
            options.AbortOnConnectFail = abortOnConnectFail;

            Initialize(options);
        }

        public string Get(string key)
        {
            IDatabase db = _redis.GetDatabase();
            return db.StringGet(key);
        }

        public bool Set(string key, string value, int timeToLive)
        {
            IDatabase db = _redis.GetDatabase();
            return db.StringSet(key, value, TimeSpan.FromSeconds(timeToLive));
        }
    }
}

这在我的本地开发机器上运行得很好(很惊讶!我知道,这是那些问题中的一个),性能很好。在测试服务器上,它根本不工作--唯一的响应是RedisTimeoutException(gets,sets,我相信还有示例化,考虑到示例化所花的时间):

Exception type: RedisTimeoutException 
Exception message: Timeout performing PSETEX (5000ms), inst: 0, qu: 1, qs: 0, aw: False, bw: SpinningDown, last-in: 0, cur-in: 0, sync-ops: 2, async-ops: 1, serverEndpoint: xxx.redis.cache.windows.net:6380, conn-sec: n/a, mc: 1/1/0, mgr: 10 of 10 available, clientName: xxx(SE.Redis-v2.6.90.64945), IOCP: (Busy=0,Free=1000,Min=12,Max=1000), WORKER: (Busy=2,Free=32765,Min=12,Max=32767), v: 2.6.90.64945 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts)
at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor`1 processor, ServerEndPoint server, T defaultValue)
at Rimes.Azure.RedisCache.Set(String key, String value, TimeSpan expiry)

我已经浏览了错误消息中提供的链接中的建议,并阅读了大量的材料,但似乎没有任何关于寻找什么的建议在我的情况下有效
我尝试过的:

  • 超时从默认值5000 ms提升到30000 ms-无变更
  • psping,以验证到Azure的连接-这是成功的
  • 已检查本地服务器和Azure上的防火墙设置-Azure中没有防火墙配置,本地服务器配置为允许传出连接
  • 检查.Net版本-实际上在两个环境中都运行4.8。唯一的区别似乎是我的本地计算机运行4.8.04084,而服务器运行4.8.03761
  • 与网络团队进行了检查,以验证没有外部因素-他们找不到任何东西
  • 用Python重新开发,使用redis 3.5.3库-该高速缓存在两台机器上都能完美工作

基于以上所述,我知道这个问题存在于我的.Net环境中的某个地方,但是我的经验有限,我不确定现在该怎么办。我欢迎任何建议!

更新日期:

我确实在2月14日星期五在测试服务器上运行了此程序,但在2月17日星期一却无法运行。环顾四周,我发现了两个针对.Net的MS安全更新,它们是为了修复14日发布的一个关键安全更新而发布的-KB 5022504和KB 5022782
删除这些更新没有什么不同,但它确实让我研究了.Net更新,似乎不同的组策略设置导致不同的更新实践。在我们的服务器上,我们只得到安全更新,而在我的开发机器上,我只得到功能更新

更新日期:

在Azure Redis上打开和使用非SSL端口可以正常工作。回拨到TLS 1.0也可以正常工作。将TLS设置为更高的值将失败,并在额外日志中显示以下输出:

11:09:02.9964: Allowing 1 endpoint(s) 00:00:05 to respond...
11:09:02.9964: Awaiting 1 available task completion(s) for 5000ms, IOCP: (Busy=0,Free=1000,Min=2,Max=1000), WORKER: (Busy=4,Free=32763,Min=10,Max=32767)
11:09:03.0241: Configuring TLS
11:09:03.0554: Connection failed: xxx.redis.cache.windows.net:6380 (Subscription, AuthenticationFailure): AuthenticationFailure on xxx.redis.cache.windows.net:6380/Subscription, Initializing/NotStarted, last: NONE, origin: ConnectedAsync, outstanding: 0, last-read: 0s ago, last-write: 0s ago, keep-alive: 60s, state: Connecting, mgr: 10 of 10 available, last-heartbeat: never, global: 0s ago, v: 2.6.96.30123
11:09:03.0554: > A call to SSPI failed, see inner exception.
11:09:03.0554: > The function requested is not supported
11:09:03.0554: xxx.redis.cache.windows.net:6380: OnConnectedAsync completed (Disconnected)
...
11:09:03.1178: Endpoint Summary:
11:09:03.1178:   xxx.redis.cache.windows.net:6380: Standalone v4.0.0, primary; keep-alive: 00:01:00; int: Disconnected; sub: Disconnected; not in use: DidNotRespond
11:09:03.1178:   xxx.redis.cache.windows.net:6380: int ops=0, qu=0, qs=0, qc=0, wr=0, socks=3; sub ops=0, qu=0, qs=0, qc=0, wr=0, socks=3
11:09:03.1178:   xxx.redis.cache.windows.net:6380: Circular op-count snapshot; int: 0 (0.00 ops/s; spans 10s); sub: 0 (0.00 ops/s; spans 10s)
11:09:03.1178: Sync timeouts: 0; async timeouts: 0; fire and forget: 0; last heartbeat: -1s ago
11:09:03.1178: Starting heartbeat...
11:09:08.1781: Encountered exception: StackExchange.Redis.RedisTimeoutException: The timeout was reached before the message could be written to the output buffer, and it was not sent, command=SUBSCRIBE, timeout: 5000, inst: 0, qu: 0, qs: 0, aw: False, bw: CheckingForTimeout, rs: NotStarted, ws: Initializing, in: 0, last-in: 0, cur-in: 0, sync-ops: 0, async-ops: 1, serverEndpoint: xxx.redis.cache.windows.net:6380, conn-sec: n/a, mc: 1/1/0, mgr: 10 of 10 available, clientName: LDOKTATEST01(SE.Redis-v2.6.96.30123), IOCP: (Busy=0,Free=1000,Min=2,Max=1000), WORKER: (Busy=6,Free=32761,Min=10,Max=32767), v: 2.6.96.30123 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebugge

基于配置TLS后的SSPI故障,我决定删除SecurityProtocol设置,并尝试通过注册表配置.Net以使用TLS 1.2。这样可以
我现在缺少的是如何在代码中将TLS版本设置为1.2,这样就可以在不设置注册表项的情况下工作

ttp71kqs

ttp71kqs1#

对于我来说,我使用的是.NET Framework 4.5.1。将以下内容添加到现有连接字符串中可以解决此问题:我使用的是StackExchange.Redis v 1.2.6(当时是支持.Net Framework的最新版本)。
此外,确保您的应用程序使用TLS 1.2。在C#中,这可以通过以下代码完成:ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
部署到Azure时,请确保资源配置也设置为使用TLS 1.2。
参考https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-remove-tls-10-11#net-framework

相关问题