ServiceStack.Redis 与 Azure Redis 的连接问题
ServiceStack.Redis connection issues with Azure Redis
我在多个环境(即不同的 Azure Redis 实例)中遇到与此类似的问题 post:ServiceStack.Redis: Unable to Connect: sPort:
但是我们当然不能移动或更改 Redis 服务器,因为我们依赖于 Azure Redis。如果这是一个延迟问题,我们可能会搞砸......
我们使用的是较旧版本的 SS (4.0.42.0),此后已更新至最新版本 (4.0.56.0),并发现同样的间歇性问题。
这里是一些背景:
- 只有在至少 2K 请求(有时或多或少)后才会出现问题。是的,我们使用的是最新的 SS 许可证。
- 这是非常间歇性的,大多数请求都是成功的,但失败的请求通常以小串(1-5 左右)的形式失败,然后问题会消失一段时间
- 我尝试过 RedisPoolManager、PooledRedisClientManager,结果相同。
- 我为每个请求都做了一份客户端统计报告,并确保池中包含充足的客户端,none 出错,等等。我很少看到 40 个客户端同时使用超过 2-3 个。
-
不同的例外:
-IOException
消息 Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host
和包含 RedisClient 提及的堆栈跟踪。这是完整的错误转储:
"exception": {
"message": "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.",
"source": "System",
"targetSite": "Int32 Read(Byte[], Int32, Int32)",
"stackTrace": " at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)\r\n at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)\r\n at System.Net.Security._SslStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security._SslStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security._SslStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslStream.Read(Byte[] buffer, Int32 offset, Int32 count)\r\n at System.IO.BufferedStream.ReadByte()\r\n at ServiceStack.Redis.RedisNativeClient.ReadLine()\r\n at ServiceStack.Redis.RedisNativeClient.ReadData()\r\n at ServiceStack.Redis.RedisClient.<>c__DisplayClass1c
1.b__1b(RedisClient r)\r\n 在 ServiceStack.Redis.RedisClient.Exec[T](Func2 action)\r\n at ServiceStack.Redis.RedisClientManagerCacheClient.Get[T](String key)\r\n at API.ServiceInterface.RequestExtensions.GetUserSession(IRequest req, Boolean createIfNotExists) in F:\src\CCCAPI CD (DevLab)\ServiceInterface\Extensions\RequestExtensions.cs:line 26\r\n at API.WebHost.AuthImpl.HandleBlacklistedUserSessions(IRequest req, IResponse httpResponse) in F:\src\CCCAPI CD (DevLab)\WebHost\Authentication\AuthImpl.cs:line 30\r\n at ServiceStack.ServiceStackHost.ApplyPreRequestFilters(IRequest httpReq, IResponse httpRes)\r\n at ServiceStack.Host.RestHandler.ProcessRequestAsync(IRequest httpReq, IResponse httpRes, String operationName)",
"type": "IOException",
"innerException": {
"message": "An existing connection was forcibly closed by the remote host",
"source": "System",
"targetSite": "Int32 Read(Byte[], Int32, Int32)",
"stackTrace": " at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)",
"type": "SocketException"
}
}
-我们看到的另一个异常是异常类型ServiceStack.Redis
with message Unable to Connect: sPort: 50447
(这里有趣的是端口发生了变化,而且永远不是应该使用的真正的Azure Redis SSL端口,似乎池管理器可能不会将正确的传递给该客户端?)。这是完整的转储:
"exception": {
"message": "Unable to Connect: sPort: 50447",
"source": "ServiceStack.Redis",
"targetSite": "ServiceStack.Redis.RedisException CreateConnectionError()",
"stackTrace": " at ServiceStack.Redis.RedisNativeClient.CreateConnectionError()\r\n at ServiceStack.Redis.RedisNativeClient.SendExpectData(Byte[][] cmdWithBinaryArgs)\r\n at ServiceStack.Redis.RedisClient.<>c__DisplayClass1c
1.b__1b(RedisClient r)\r\n 在 ServiceStack.Redis.RedisClient.Exec[T](Func2 action)\r\n at ServiceStack.Redis.RedisClientManagerCacheClient.Get[T](String key)\r\n at API.ServiceInterface.RequestExtensions.GetUserSession(IRequest req, Boolean createIfNotExists) in F:\src\CCCAPI CD (DevLab)\ServiceInterface\Extensions\RequestExtensions.cs:line 26\r\n at API.WebHost.AuthImpl.HandleBlacklistedUserSessions(IRequest req, IResponse httpResponse) in F:\src\CCCAPI CD (DevLab)\WebHost\Authentication\AuthImpl.cs:line 30\r\n at ServiceStack.ServiceStackHost.ApplyPreRequestFilters(IRequest httpReq, IResponse httpRes)\r\n at ServiceStack.Host.RestHandler.ProcessRequestAsync(IRequest httpReq, IResponse httpRes, String operationName)",
"type": "RedisException",
"innerException": {
"message": "An existing connection was forcibly closed by the remote host",
"source": "System",
"targetSite": "Void Write(Byte[], Int32, Int32)",
"stackTrace": " at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)",
"type": "SocketException"
}
我正在为这个问题苦苦挣扎...任何帮助将不胜感激。
An existing connection was forcibly closed by the remote host
这是一个一般的 TCP 网络错误,表明您的连接已被远程 redis 实例或可能有故障的网络硬件终止,没有什么可以阻止它在客户端上发生,但应该通过 ServiceStack.Redis Automatic Retries 特征。
Unable to Connect: sPort: 50447
sPort(source)是指clientPort,即客户端随机选择的TCP连接端口,不是指在连接字符串。
该错误表明Redis 客户端正在尝试建立新的TCP 连接但已被拒绝。客户端只能不断重试。
鉴于此问题在某些负载后更频繁地出现,这可能是服务器过饱和的结果,在这种情况下,您可以尝试增加正在使用的 Azure Redis 缓存的大小。
我一直注意到这些间歇性问题似乎在 Azure 上发生的次数比其他任何地方都多(不清楚是由于流行还是不可靠),redis 通常在其自然环境中坚如磐石,即 运行 在 Linux 上并从同一子网访问。您可以尝试的另一种解决方案是 运行 Linux VM 上的 Redis 服务器,位于从其访问的同一数据中心 - 这可能会绕过托管 Azure Redis 服务可能添加的任何限制或其他限制。
我在多个环境(即不同的 Azure Redis 实例)中遇到与此类似的问题 post:ServiceStack.Redis: Unable to Connect: sPort:
但是我们当然不能移动或更改 Redis 服务器,因为我们依赖于 Azure Redis。如果这是一个延迟问题,我们可能会搞砸......
我们使用的是较旧版本的 SS (4.0.42.0),此后已更新至最新版本 (4.0.56.0),并发现同样的间歇性问题。
这里是一些背景: - 只有在至少 2K 请求(有时或多或少)后才会出现问题。是的,我们使用的是最新的 SS 许可证。 - 这是非常间歇性的,大多数请求都是成功的,但失败的请求通常以小串(1-5 左右)的形式失败,然后问题会消失一段时间 - 我尝试过 RedisPoolManager、PooledRedisClientManager,结果相同。 - 我为每个请求都做了一份客户端统计报告,并确保池中包含充足的客户端,none 出错,等等。我很少看到 40 个客户端同时使用超过 2-3 个。 -
不同的例外:
-IOException
消息 Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host
和包含 RedisClient 提及的堆栈跟踪。这是完整的错误转储:
"exception": {
"message": "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.",
"source": "System",
"targetSite": "Int32 Read(Byte[], Int32, Int32)",
"stackTrace": " at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)\r\n at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)\r\n at System.Net.Security._SslStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security._SslStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security._SslStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslStream.Read(Byte[] buffer, Int32 offset, Int32 count)\r\n at System.IO.BufferedStream.ReadByte()\r\n at ServiceStack.Redis.RedisNativeClient.ReadLine()\r\n at ServiceStack.Redis.RedisNativeClient.ReadData()\r\n at ServiceStack.Redis.RedisClient.<>c__DisplayClass1c
1.b__1b(RedisClient r)\r\n 在 ServiceStack.Redis.RedisClient.Exec[T](Func2 action)\r\n at ServiceStack.Redis.RedisClientManagerCacheClient.Get[T](String key)\r\n at API.ServiceInterface.RequestExtensions.GetUserSession(IRequest req, Boolean createIfNotExists) in F:\src\CCCAPI CD (DevLab)\ServiceInterface\Extensions\RequestExtensions.cs:line 26\r\n at API.WebHost.AuthImpl.HandleBlacklistedUserSessions(IRequest req, IResponse httpResponse) in F:\src\CCCAPI CD (DevLab)\WebHost\Authentication\AuthImpl.cs:line 30\r\n at ServiceStack.ServiceStackHost.ApplyPreRequestFilters(IRequest httpReq, IResponse httpRes)\r\n at ServiceStack.Host.RestHandler.ProcessRequestAsync(IRequest httpReq, IResponse httpRes, String operationName)",
"type": "IOException",
"innerException": {
"message": "An existing connection was forcibly closed by the remote host",
"source": "System",
"targetSite": "Int32 Read(Byte[], Int32, Int32)",
"stackTrace": " at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)",
"type": "SocketException"
}
}
-我们看到的另一个异常是异常类型ServiceStack.Redis
with message Unable to Connect: sPort: 50447
(这里有趣的是端口发生了变化,而且永远不是应该使用的真正的Azure Redis SSL端口,似乎池管理器可能不会将正确的传递给该客户端?)。这是完整的转储:
"exception": {
"message": "Unable to Connect: sPort: 50447",
"source": "ServiceStack.Redis",
"targetSite": "ServiceStack.Redis.RedisException CreateConnectionError()",
"stackTrace": " at ServiceStack.Redis.RedisNativeClient.CreateConnectionError()\r\n at ServiceStack.Redis.RedisNativeClient.SendExpectData(Byte[][] cmdWithBinaryArgs)\r\n at ServiceStack.Redis.RedisClient.<>c__DisplayClass1c
1.b__1b(RedisClient r)\r\n 在 ServiceStack.Redis.RedisClient.Exec[T](Func2 action)\r\n at ServiceStack.Redis.RedisClientManagerCacheClient.Get[T](String key)\r\n at API.ServiceInterface.RequestExtensions.GetUserSession(IRequest req, Boolean createIfNotExists) in F:\src\CCCAPI CD (DevLab)\ServiceInterface\Extensions\RequestExtensions.cs:line 26\r\n at API.WebHost.AuthImpl.HandleBlacklistedUserSessions(IRequest req, IResponse httpResponse) in F:\src\CCCAPI CD (DevLab)\WebHost\Authentication\AuthImpl.cs:line 30\r\n at ServiceStack.ServiceStackHost.ApplyPreRequestFilters(IRequest httpReq, IResponse httpRes)\r\n at ServiceStack.Host.RestHandler.ProcessRequestAsync(IRequest httpReq, IResponse httpRes, String operationName)",
"type": "RedisException",
"innerException": {
"message": "An existing connection was forcibly closed by the remote host",
"source": "System",
"targetSite": "Void Write(Byte[], Int32, Int32)",
"stackTrace": " at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)",
"type": "SocketException"
}
我正在为这个问题苦苦挣扎...任何帮助将不胜感激。
An existing connection was forcibly closed by the remote host
这是一个一般的 TCP 网络错误,表明您的连接已被远程 redis 实例或可能有故障的网络硬件终止,没有什么可以阻止它在客户端上发生,但应该通过 ServiceStack.Redis Automatic Retries 特征。
Unable to Connect: sPort: 50447
sPort(source)是指clientPort,即客户端随机选择的TCP连接端口,不是指在连接字符串。
该错误表明Redis 客户端正在尝试建立新的TCP 连接但已被拒绝。客户端只能不断重试。
鉴于此问题在某些负载后更频繁地出现,这可能是服务器过饱和的结果,在这种情况下,您可以尝试增加正在使用的 Azure Redis 缓存的大小。
我一直注意到这些间歇性问题似乎在 Azure 上发生的次数比其他任何地方都多(不清楚是由于流行还是不可靠),redis 通常在其自然环境中坚如磐石,即 运行 在 Linux 上并从同一子网访问。您可以尝试的另一种解决方案是 运行 Linux VM 上的 Redis 服务器,位于从其访问的同一数据中心 - 这可能会绕过托管 Azure Redis 服务可能添加的任何限制或其他限制。