Ao usar Stackexchange Redis milhares de conexões estão sendo criadas
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;
}
A classe é então injectada, quando necessário, em classes dependentes utilizando Ninject como singleton
kernel.Bind<RedisConnManager>().To<RedisConnManager>().InSingletonScope();
e depois consumido da seguinte forma
var cache = this.redisConnManager.Connection.GetDatabase();
key = cachable.GenerateKey();
RedisValue result = cache.StringGet(key);
Eu verifiquei que o construtor do ConnectionManager não é chamado mais de uma vez
Devemos estar a ver tantas ligações?
2 answers
Você está criando o objeto preguiçoso cada vez que a propriedade LazyConnection
é usada. Isto é muito errado.
Você deve criar o objeto preguiçoso apenas uma vez, por exemplo no construtor:
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; } }
}
Mas novamente, se você está criando a classe várias vezes, você terá vários objetos preguiçosos, ergo múltiplas conexões. Você provavelmente deve codificá-lo estaticamente:
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; } }
}
Agora o {[3] } é estático, assim será compartilhado por todas as instâncias da classe e será criado apenas quando. O código do mecanismo de bloqueio extra é evitar ter mais de um tópico criando o objeto preguiçoso.
Considere também tornar o campo configuration
estático.
Ou ainda melhor se você usar um coi configure - o para criar uma única instância dele em vez de tê-lo como um adereço estático. Vai tornar os testes de unidade muito mais fáceis.