我正在将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,这样就可以在不设置注册表项的情况下工作
1条答案
按热度按时间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