PooledRedisClientManager未释放连接

本文关键字:连接 释放 PooledRedisClientManager | 更新日期: 2023-09-27 17:58:54

我将json数据列表存储在redis中,并使用ServiceStack c#客户端访问它。我本质上是在管理我自己的外键,在那里我存储了一个id的zrange,我使用应用程序内部的接口从zrange中提取id,然后从Redis中获取底层json对象,并将它们打包为列表,返回到应用程序的其他部分。

我正在使用PooledRedisClientManager,因为我预计Redis将托管在与执行代码的服务器不同的服务器上。

我在Windows8上使用MSOpenTechRedis服务器本地完成所有的开发工作。目前,我最大的挑战是客户端连接没有被关闭。

我的Redis persister被注入了一个IRedisClientManager实例(IoC是CastleWindsor)。此代码在azure工作人员角色的上下文中执行。

这就是我从zrange:中提取项目的方式

public class MyRedisPersister<T> : IResourcePersister<T>
{ 
    IRedisClientManager _mgr;
    public MyRedisPersister(IRedisClientManager mgr)
    {
        _mgr = mgr;
    }
    public IResourceList<T> Get<T>(string key, int offset, int count) where T
    {
        using (var redis = _clientManager.GetClient())
        {
            var itemKeys = redis.GetRangeFromSortedSet(key, offset, offset + count - 1).ToList();
            var totalItems = redis.GetSortedSetCount(key);
            if (itemKeys.Count == 0)
            {
                return new ResourceList<T>
                    {
                        Items = new List<T>(),
                        Offset = 0,
                        PageSize = 0,
                        TotalItems = 0,
                        TotalPages = 0
                    };
            }
            else
            {
                return new ResourceList<T>
                    {
                        Items = itemKeys.Select(k => redis.Get<T>(k)).ToList(),
                        Offset = offset,
                        PageSize = count,
                        TotalItems = totalItems,
                        TotalPages = (int) Math.Ceiling((float) totalItems/count)
                    };
            }
        }
    }
}

这是我用来注册IRedisClientManager 的代码

var mgr = new PooledRedisClientManager(100, 10, "localhost:6379");
container.Register(Component.For<IRedisClientsManager>().Instance(mgr).LifeStyle.Singleton);

如有任何帮助,我们将不胜感激。

PooledRedisClientManager未释放连接

目前我最大的挑战是客户端连接没有关闭

您使用的是"PooledRedisClientManager",因此我的理解是,客户端连接不应关闭,只应放入池中进行重用。看起来您的池大小是100个连接。

您可以尝试使用var mgr = new BasicRedisClientManager("localhost:6379")其应当处置客户端。

edit不建议使用以下方法-您应该依赖IRedisClientsManager,并将所有redis客户端调用封装在using()块中,否则您将被小妖精咬。

我一直在遇到类似的问题,让Windsor与PooledRedisClientsManager打得很好,最终这似乎奏效了:

        container.Register(
            Component.For<IRedisClientsManager>()
                     .Instance(redisClients)
                     .LifestyleSingleton(),
            Component.For<IRedisClient>()
                     .UsingFactoryMethod(c => c.Resolve<IRedisClientsManager>().GetClient(),
                                        managedExternally: true));
    }

managedExternally参数告诉Windsor不要试图将停用问题应用于IRedisClients,而是让PooledRedisClientsManager处理回收。