Caching 使用Stackexchange Redis时,将创建数千个连接
我们刚刚开始从web和工作者角色使用Azure Redis缓存。我们发现,在相当轻的使用情况下,会创建约2.5K的连接 我们使用的是封装在连接管理器中的StackExchange.Redis nuget包Caching 使用Stackexchange Redis时,将创建数千个连接,caching,redis,lazy-initialization,stackexchange.redis,Caching,Redis,Lazy Initialization,Stackexchange.redis,我们刚刚开始从web和工作者角色使用Azure Redis缓存。我们发现,在相当轻的使用情况下,会创建约2.5K的连接 我们使用的是封装在连接管理器中的StackExchange.Redis nuget包 public class RedisConnManager { private readonly IConfiguration configuration; public RedisConnManager(IConfiguration configuration)
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;
}
我已经检查了ConnectionManager的构造函数不会被多次调用
我们应该看到这么多连接吗?每次使用
LazyConnection
属性时,您都在创建惰性对象。这是非常错误的
您应该只创建一次惰性对象,例如在构造函数中:
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; } }
}
公共类RedisConnManager
{
专用只读IConfiguration配置;
公共RedisConnManager(IConfiguration配置)
{
this.configuration=配置;
lazyConnection=new Lazy(()=>ConnectionMultiplexer.Connect(
configuration.SessionManagerRedisConnectionString);
}
私人懒散联系;
公共连接多路复用器连接{get{return lazyConnection.Value;}}
}
但是,同样,如果您多次创建该类,您将拥有多个惰性对象,因此会有多个连接。
您可能应该对其进行静态编码:
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; } }
}
公共类RedisConnManager
{
专用只读IConfiguration配置;
公共RedisConnManager(IConfiguration配置)
{
this.configuration=配置;
锁(储物柜)
{
if(lazyConnection==null)
{
lazyConnection=newlazy(()=>newconnectionmultiplexer(this.configuration));
}
}
}
私有静态懒散连接;
私有静态只读对象锁定器=新对象();
公共连接多路复用器连接{get{return lazyConnection.Value;}}
}
现在,lazyConnection
是静态的,因此将在类的所有实例中共享,并且只创建一次。
额外的锁机制代码是为了避免有多个线程创建惰性对象
还可以考虑将
配置
字段设置为静态。如果使用ioc将其配置为创建单个实例,而不是将其作为静态道具,则效果更好。这将使单元测试更容易看起来不错,谢谢你们的帮助,虽然我已经实现了这一点,但显然它的工作方式与你们不经意阅读文章的方式不同,因为在这个例子中,它们使用静态属性
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; } }
}
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; } }
}