我讨厌那些“没有足够信息”的问题。所以我会尝试提供详细信息。在这种情况下,它是代码。
服务器: 64位https://github.com/MSOpenTech/redis/tree/2.6/bin/release
有三个类:
DbOperationContext.cs :https://gist.github.com/glikoz/7119628
PerRequestLifeTimeManager.cs :https://gist.github.com/glikoz/7119699
RedisRepository.cs https://gist.github.com/glikoz/7119769
我们正在使用Redis和Unity ..
在这种情况下,我们收到了这条奇怪的信息:
“Redis Timeout已过期。在从池中获取连接之前已经过了超时时间。这可能是因为所有池连接都在使用中。”;
我们检查了这些:
问题配置问题
我们使用的是错误的RedisServer.exe
是否有任何架构问题
有什么想法吗?有类似的故事吗?
感谢。
额外信息1
服务器统计信息没有被拒绝的连接问题(我已经通过redis-cli.exe info命令检查了它)
答案 0 :(得分:10)
我继续调试此问题,并在我的平台上修复了许多内容以避免此异常。以下是我为解决这个问题所做的工作:
执行摘要:
遇到此异常的人应该检查:
我的问题的解决方案:
首先,PooledRedisClient because it has no more pooled connections available抛出此异常。
我正在StructureMap IoC容器中注册所有必需的Redis内容(不像作者的情况那样是统一的)。感谢this post我被提醒说PooledRedisClientManager应该是一个单例 - 我还决定将RedisMqServer注册为单身:
ObjectFactory.Configure(x =>
{
// register the message queue stuff as Singletons in this AppDomain
x.For<IRedisClientsManager>()
.Singleton()
.Use(BuildRedisClientsManager);
x.For<IMessageService>()
.Singleton()
.Use<RedisMqServer>()
.Ctor<IRedisClientsManager>().Is(i => i.GetInstance<IRedisClientsManager>())
.Ctor<int>("retryCount").Is(2)
.Ctor<TimeSpan?>().Is(TimeSpan.FromSeconds(5));
// Retrieve a new message factory from the singleton IMessageService
x.For<IMessageFactory>()
.Use(i => i.GetInstance<IMessageService>().MessageFactory);
});
我的“BuildRedisClientManager”功能如下所示:
private static IRedisClientsManager BuildRedisClientsManager()
{
var appSettings = new AppSettings();
var redisClients = appSettings.Get("redis-servers", "redis.local:6379").Split(',');
var redisFactory = new PooledRedisClientManager(redisClients);
redisFactory.ConnectTimeout = 5;
redisFactory.IdleTimeOutSecs = 30;
redisFactory.PoolTimeout = 3;
return redisFactory;
}
然后,当涉及到生成消息时,使用RedisClient被正确处理是非常重要的,否则我们会遇到可怕的“Timeout Expired”(感谢this post)。我有以下帮助程序代码将消息发送到队列:
public static void PublishMessage<T>(T msg)
{
try
{
using (var producer = GetMessageProducer())
{
producer.Publish<T>(msg);
}
}
catch (Exception ex)
{
// TODO: Log or whatever... I'm not throwing to avoid showing users that we have a broken MQ
}
}
private static IMessageQueueClient GetMessageProducer()
{
var producer = ObjectFactory.GetInstance<IMessageService>() as RedisMqServer;
var client = producer.CreateMessageQueueClient();
return client;
}
我希望这也有助于解决您的问题。