2

从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(); 

所以有几个问题:

  1. 如若语境中的我建立连接被布置关闭为正常?

  2. 有谁知道ShardMapManger连接是如何管理的?

  3. 可能下面的代码(因为我的模型第一 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

+0

请注意,您使用的EntityConnection构造函数的重载(新的EntityConnection(workspace,shardConnection))会将该实体连接的重要参数“entityConnectionOwnsStoreConnection”设置为false。这意味着实体连接不负责管理您的商店连接,并且不会关闭它。还有另外一个重载允许你设置这个参数为true。 – Evk

+0

@Evk这很有趣,如果你看一下基础构造函数,你可以看到我作为entityConnectionOwnsStoreConnection的第二个参数传递了true。因此我不知道是否需要像在EntityConnection构造函数中所说的那样另外传递true? – CSL

+0

@Evk我发现该属性的定义是:如果设置为true,则在实体连接处置时存储连接将被处置,否则调用者必须处理存储连接。“我认为对我来说这将是谨慎的对两个EnttityConnection构造函数都添加true。 – CSL

回答

1

正如评论想通了,在CreateEntityConnection方法你从底层的连接建立EntityConnection,但不设置重要参数“entityConnectionOwnsStoreConnection”为true。这意味着实体连接不负责管理您的商店连接,并且不会关闭它,因此您的连接将会泄漏。要修复,使用其他EntityConnection构造:

var entcon = new EntityConnection(workspace, shardConnection, true); 

然后,情境设置时,它会处理你的EntityConnection,这反过来将处理底层数据库连接。