ServiceStack PooledRedisClient超时异常

时间:2014-11-27 19:52:25

标签: c# redis servicestack servicestack.redis

我在servicestack API中使用ServiceStack.Redis池化客户端,经过几个小时的流量大约3000rpm后,我从池管理器收到连接超时异常。实施如下:

在AppStart中:

 container.Register<IRedisClientsManager>(
                    p => new RedisManagerPool(Configuration.Config.Instance.RedisConfig.Server)
                    {
                        MaxPoolSize = 10000,
                        PoolTimeoutMs = 2000
                    }).ReusedWithin(ReuseScope.Container);

在服务中:

Pool = (RedisManagerPool) GetResolver().TryResolve<IRedisClientsManager>();
            RedisClient = (RedisClient)Pool.GetClient();

....

RedisClient.Dispose();

我还尝试使用Pool.DisposeClient(RedisClient)处理客户端,以便将客户端返回到池中,但我看到了相同的结果。

我还检查了Redis服务器,但没有CPU使用,内存使用,0拒绝连接等问题。

如果有人遇到这个,你能告诉我吗?

谢谢

1 个答案:

答案 0 :(得分:3)

我不会有一个大的池大小,保持 10000 打开连接似乎比没有任何连接池更糟糕。

您也不需要指定ReuseScope.Container,因为默认情况下使用的单例是管理器/工厂的正确范围,所以我首先尝试默认配置:

container.Register<IRedisClientsManager>(c => 
    new RedisManagerPool(Configuration.Config.Instance.RedisConfig.Server));

池超时异常表明连接池已填满,并且池超时内没有任何连接被释放(即处置)。

我建议使用RedisManagerPool that's on MyGet的最新v4.0.34有一个备用池策略,一旦连接池已满,将创建新的非托管池实例,而不是在池超时后锁定和抛出已经到达。

同样在您的服务中,您可以在首次访问时使用base.Redis since it automatically creates an instance访问Redis客户端,并在执行服务后处置,即:

public class Service : IDisposable
{
    private IRedisClient redis;
    public virtual IRedisClient Redis
    {
        get { return redis ?? (redis = TryResolve<IRedisClientsManager>().GetClient()); }
    }

    //...

    public virtual void Dispose()
    {
        if (redis != null)
            redis.Dispose();
    }

}

这有助于确保在每次请求后妥善处理Redis客户端。