EFCore connection pool pit almost old age can not be maintained

Long story short

  A line of Things data science project last month the company, I am responsible for front-end accepts things event, and provide parameters for download.

webapp deployed on Azure cloud storage parameters Azure SQL Server. After the deployment of the full amount of the recent shift from gray-scale test, log often receive:

 SQL Session Session overrun error.

19/12/18 20:41:18 [Error].[Microsoft.EntityFrameworkCore.Query].[][0HLS3MS83SC3K:00000004].[http://localhost/api/v1/soc-prediction-model/all].[].[GetModeParameters] 
An exception occurred while iterating over the results of a query for context type 'Gridsum.SaicEnergyTracker.CarModelContext'.
Microsoft.Data.SqlClient.SqlException (0x80131904): Resource ID : 2. The session limit for the database is 300 and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance.
Changed database context to 'saic-carmodel'.
Changed language setting to us_english.
   at Microsoft.Data.ProviderBase.DbConnectionPool.CheckPoolBlockingPeriod(Exception e)
   at Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()

 Investigation

  I use on Azure is SQL Server Basic Edition (paid version is good and bad), the total amount released so far, average daily visits of about 10,000 SQL query the Azure SQL usage restrictions document :

Bottom line: Pay levels and computing resource size determines the maximum number of sessions and Azure SQL requests. To mitigate, or upgrade your hardware resources, optimize the query or utilization.

View EFCore use to access SQL Server process, but also the official default usage:

  •  In DbContext DI framework type register a custom
  • Get Controller DbContext instance constructor

This means that every request will create a DbContext instance, it is conceivable to

 ① at high concurrent requests, connections continue to accumulate, eventually exceed a certain time limit the number of connections of Azure.

 ② frequently created and destroyed DbContext instance, the impact App Service's own performance.

EFCore2.0 DbContext is the introduction of new registration, it is possible to register a transparent DbContext instance pool:

services.AddDbContextPool<CarModelContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SQL")));

   - continue to support the connection string lambda Register

  - The default number of connection pool of 128

  - each use DbContext will not release the object, but recovered to reset and DBContextPool

Web program by reusing DbContext cell throughput in high concurrent increase example scenario, which is similar to the connection pool operation ADO.NET Provider native conceptually, having the advantage of saving costs DbContext instantiated, which is EFCore2.0 wherein a bright spot performance.

Even such an important use Microsoft doc Demo is not recommended to use the default, it is really a pit.

After modifying the code re-deployment, a few days after the test, the beginning of the temporary SqlException exception does not appear.

verification

Looking back random verification operably linked SQL Server session:

SELECT DEC.session_id, DEC.protocol_type, DEC.auth_scheme,
  DES.login_name, DES.login_time
FROM sys.dm_exec_sessions AS DES
  JOIN sys.dm_exec_connections AS DEC
    ON DEC.session_id = DES.session_id;

to sum up

① Tip DbContextPool EFCore2.0 new properties, can effectively improve query throughput

② try to use SQL Server built-in scripting a witness session valid connections

+  https://stackoverflow.com/questions/48443567/adddbcontext-or-adddbcontextpool

https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.0#dbcontext-pooling

https://www.mssqltips.com/sqlservertip/5507/understanding-and-using-sysdmexecsessions-in-sql-server/

Guess you like

Origin www.cnblogs.com/JulianHuang/p/12074483.html