我们刚刚开始使用来自Web和辅助角色的Azure Redis缓存。我们发现在相当轻的情况下使用~2.5K连接。
我们正在使用包装在连接管理器中的StackExchange.Redis nuget包
public class RedisConnManager
{
private readonly IConfiguration configuration;
public RedisConnManager(IConfiguration configuration)
{
this.configuration = configuration;
}
public Lazy<ConnectionMultiplexer> LazyConnection
{
get
{
return new Lazy<ConnectionMultiplexer>(
() => ConnectionMultiplexer.Connect(
this.configuration.SessionManagerRedisConnectionString));
}
}
public ConnectionMultiplexer Connection => this.LazyConnection.Value;
}
然后使用Ninject作为单例
将类注入需要的依赖类中 kernel.Bind<RedisConnManager>().To<RedisConnManager>().InSingletonScope();
然后消费如下
var cache = this.redisConnManager.Connection.GetDatabase();
key = cachable.GenerateKey();
RedisValue result = cache.StringGet(key);
我已经检查过ConnectionManager的构造函数不会被多次调用
我们应该看到这么多联系吗?
答案 0 :(得分:3)
每次使用LazyConnection
属性时,都在创建Lazy对象。这是非常错误的。
您应该只创建一次Lazy对象,例如在构造函数中:
public class RedisConnManager
{
private readonly IConfiguration configuration;
public RedisConnManager(IConfiguration configuration)
{
this.configuration = configuration;
lazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(
configuration.SessionManagerRedisConnectionString));
}
private Lazy<ConnectionMultiplexer> lazyConnection;
public ConnectionMultiplexer Connection { get { return lazyConnection.Value; } }
}
但是,如果你多次创建类,你将拥有多个Lazy对象,ergo多个连接。 您应该静态编码:
public class RedisConnManager
{
private readonly IConfiguration configuration;
public RedisConnManager(IConfiguration configuration)
{
this.configuration = configuration;
lock (locker)
{
if (lazyConnection == null)
{
lazyConnection = new Lazy<ConnectionMultiplexer>(() => new ConnectionMultiplexer(this.configuration));
}
}
}
private static Lazy<ConnectionMultiplexer> lazyConnection;
private static readonly object locker = new object();
public ConnectionMultiplexer Connection { get { return lazyConnection.Value; } }
}
现在lazyConnection
是静态的,因此将在类的所有实例中共享,并且只创建一次。
额外的锁机制代码是为了避免让多个线程创建惰性对象。
还要考虑将configuration
字段设为静态。
答案 1 :(得分:-1)
或者甚至更好,如果您使用 ioc configure It 来创建它的单个实例,而不是将其作为静态道具。这将使单元测试更容易