从Microsoft返回几个示例之后,我实现了DbContext的Elastic版本,该版本从依赖于当前用户租户(或客户)Id的Elastic ShardMapManager获取其连接字符串。使用ElasticContext进行连接池管理EF
这在技术上有效,我已将其部署到我的Azure帐户。现在我担心Connection Pool管理会覆盖默认的上下文连接创建机制。此外,我不确定每次调用shardMap.OpenConnectionForKey
时连接的管理方式(请参阅下面的ninject设置)。
昨天一些光测试我的web应用程序后失败,出现以下消息:
超时过期。在从池中获取连接之前已超时。出现这种情况可能是因为所有池连接使用,最大池大小reached.`
这可能是一次性的,因为我今天可以无法重新创建,但我想,以确保连接池正在被有效地使用,因为我想要的最后一件事是当真正的用户开始敲击系统时发生。
,它失败上的代码被注释掉下面的完整代码我ElasticScaleContext:
public class ElasticScaleContext<T> : DbContext
{
/// <summary>
///
/// </summary>
/// <param name="shardMapManager">This is injected - only one of these exists per Application (Singleton)</param>
/// <param name="customerId">The Shard Key is the Customer Id</param>
/// <param name="shardConnectionString">The connection string for the Shard - this should only have the credentials and NOT any datasource. The correct datasource and initial catalog are returned by the Shard Map</param>
/// <param name="metadataWorkSpaceConnectionString">Metadata required by EF model first cannot be passed in the shard connection string, it is passed here and used to return the MetadataWorkspace - no actual connection is created</param>
public ElasticScaleContext(ShardMapManager shardMapManager, IPrincipal user, string shardConnectionString, string metadataWorkSpaceConnectionString)
: base(CreateEntityConnection(shardMapManager, user, shardConnectionString, metadataWorkSpaceConnectionString), true)
{
}
private static DbConnection CreateEntityConnection(ShardMapManager shardMapManager, IPrincipal user, string shardConnectionString, string metadataWorkSpaceConnectionString)
{
int shardKey = 0; // Default just to get a valid connection string on login page (it's never actually used)
if (user != null && user.Identity.IsAuthenticated)
{
shardKey = user.Identity.GetCustomerId();
}
// Loads the Shard Map from the Shard Manager
// This has the details of which shards are located on which databases
ListShardMap<T> shardMap = shardMapManager.GetListShardMap<T>(AppConfig.ShardMapName);
// No initialization
Database.SetInitializer<ElasticScaleContext<T>>(null);
// Create Elastic Scale SqlConnection
// ******* FAILED HERE *********
var shardConnection = shardMap.OpenConnectionForKey(shardKey, shardConnectionString, ConnectionOptions.None);
// Allocate metadata workspace via an EF connection
var efConnection = new EntityConnection(metadataWorkSpaceConnectionString);
// Create Entity connection that holds the sharded SqlConnection and metadata workspace
var workspace = efConnection.GetMetadataWorkspace();
EntityConnection entcon = new EntityConnection(workspace, shardConnection);
return entcon;
}
}
我使用Ninject与ShardMapManager被注射作为一个Singleton:
// Only ever create one Shard Map Manager
kernel.Bind<ShardMapManager>().ToMethod(context =>
{
return ShardMapManagerFactory.GetSqlShardMapManager(AppConfig.ConnectionString, ShardMapManagerLoadPolicy.Lazy);
}).InSingletonScope();
和上下文是根据请求创建的:
kernel.Bind<DbContext>().ToMethod(ctx =>
{
return new ElasticScaleContext<int>(kernel.Get<ShardMapManager>(), kernel.Get<IPrincipal>(), AppConfig.BaseConnectionString, AppConfig.SCSMetaDataConnectionString);
}}).InRequestScope();
所以有几个问题:
如若语境中的我建立连接被布置关闭为正常?
有谁知道
ShardMapManger
连接是如何管理的?可能下面的代码(因为我的模型第一 EF 方法需要)打开,然后不关闭连接?
UPDATE - 从@Evk(见注释)意见后我已经修改了构造函数调用EntityConnection传递真实的entityConnectionOwnsStoreConnection
应该允许它正常关闭后使用的存储连接,见下文。我真的需要监视连接池的方式,看看是否有任何影响:
var efConnection = new EntityConnection(metadataWorkSpaceConnectionString);
// Create Entity connection that holds the sharded SqlConnection and metadata workspace
var workspace = efConnection.GetMetadataWorkspace();
EntityConnection entcon = new EntityConnection(workspace, shardConnection. true);
最后,有没有办法对我来说,监控和查看有关Azure的弹性SQL连接的当前状态池?
我意识到这是很多问题,但我在这方面的任何信息之后 - 网络上真的没有那么多的现有信息。
附加信息: 该解决方案采用EF6,SQL服务器2014年,MVC 5.0
请注意,您使用的EntityConnection构造函数的重载(新的EntityConnection(workspace,shardConnection))会将该实体连接的重要参数“entityConnectionOwnsStoreConnection”设置为false。这意味着实体连接不负责管理您的商店连接,并且不会关闭它。还有另外一个重载允许你设置这个参数为true。 – Evk
@Evk这很有趣,如果你看一下基础构造函数,你可以看到我作为entityConnectionOwnsStoreConnection的第二个参数传递了true。因此我不知道是否需要像在EntityConnection构造函数中所说的那样另外传递true? – CSL
@Evk我发现该属性的定义是:如果设置为true,则在实体连接处置时存储连接将被处置,否则调用者必须处理存储连接。“我认为对我来说这将是谨慎的对两个EnttityConnection构造函数都添加true。 – CSL