使用DbContextPool提高EfCore查询性能

简介: ① 提示EFCore2.0新推出的DbContextPool特性,有效提高SQL查询吞吐量② 尝试使用SQL Server 内置脚本自证会话中有效连接数

长话短说


上个月公司上线了一个物联网数据科学项目,我主要负责前端接收设备Event,并提供模型参数下载(数据科学团队会优化参数)。WebApp部署在Azure,模型参数使用Azure SQL Server存储。


最近从灰度测试转向全量部署之后,日志中时常出现:SQL Session会话超限的报错。


    19/12/18 20:41:18 [Error].[Microsoft.EntityFrameworkCore.Query].[][0HLS3MS83SC3K:00000004].[http://******/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()


    排查


    Azure上使用的是SQL Server Basic Edition(好歹也是付费版),全量发布至今,日均SQL访问次数约为10000,查询了Azure SQL的使用限制文档


    一句话:付费级别和计算资源大小决定了Azure SQL最大会话数/请求数。


    若要缓解,要么升级硬件资源,要么优化查询利用率。


    本次使用EFCore操作SQL Server的方式, 是官方默认用法:


    • 依赖注入框架注册一个自定义的 DbContext类型
    • 在Controller构造函数中获取 DbContext实例


    这意味着每次请求都会创建一个 DbContext实例, 可以想象到


    在高并发请求下,连接数不断累积,最终某时刻会超过 Azure 的连接限制数量。

     频繁创建和销毁 DbContext 实例,影响App Service自身性能。


    EFCore2.0 为DbContext引入新的注册方式:透明地注册了 DbContext实例池:


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

       

      - 一如既往支持lambda方式注册连接字符串

       

      - 默认的连接池数量为 128


      - 每次使用完DbContext不会释放对象,而是重置并回收到DBContextPool


      Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量, 这在概念上类似于ADO.NET Provider原生的连接池操作方式,具有节省DbContext实例化成本的优点, 这也是EFCore2.0 其中一个性能亮点。


      这么重要的使用方式竟然不在 EFCore Doc指南中默认演示,真是一个坑。

      7b7cbae2eafd6937fd63ef036214fbd0.png


      修改代码重新部署之后,历经几天测试,暂时未出现最开始的SqlException异常。


      验证


      回过头随机验证SQL Server会话中的有效连接数量:48


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


        42a75d090771384876bf49ac136b0353.jpg


        总结


        ①  提示EFCore2.0新推出的DbContextPool特性,有效提高SQL查询吞吐量


        ②  尝试使用SQL Server 内置脚本自证会话中有效连接数

        相关文章
        |
        虚拟化 Docker Windows
        Docker - Win10 Hyper-V 和 VirtualBox 冲突的问题
        Docker - Win10 Hyper-V 和 VirtualBox 冲突的问题
        1276 0
        |
        Go API 开发工具
        Opentelemetry SDK的简单用法
        Opentelemetry SDK的简单用法
        457 3
        |
        人工智能 内存技术
        Gemini 2.0 Flash Thinking:谷歌推出实验性多模态推理模型,在快速生成的同时展示详细的思考过程
        谷歌推出的实验性推理模型Gemini 2.0 Flash Thinking,展示了详细的思考过程,能够在多个领域快速解决问题,并提供推理路径。本文将详细介绍该模型的功能、技术原理及使用限制。
        670 26
        Gemini 2.0 Flash Thinking:谷歌推出实验性多模态推理模型,在快速生成的同时展示详细的思考过程
        |
        开发框架 JavaScript 前端开发
        HarmonyOS UI开发:掌握ArkUI(包括Java UI和JS UI)进行界面开发
        【10月更文挑战第22天】随着科技发展,操作系统呈现多元化趋势。华为推出的HarmonyOS以其全场景、多设备特性备受关注。本文介绍HarmonyOS的UI开发框架ArkUI,探讨Java UI和JS UI两种开发方式。Java UI适合复杂界面开发,性能较高;JS UI适合快速开发简单界面,跨平台性好。掌握ArkUI可高效打造符合用户需求的界面。
        652 8
        |
        Java 监控 自然语言处理
        一站式链路追踪:阿里云的端到端解决方案
        端到端链路追踪是覆盖全部关联 IT 系统,能够完整记录用户行为在系统间调用路径与状态的最佳实践方案。而真正实现端到端链路追踪,需要解决三个难题:链路插桩、链路采集与加工、链路上下文透传。阿里云 ARMS 目前已支持全链路端到端追踪,快来查看转发吧~
        61980 97
        |
        应用服务中间件 nginx Docker
        connect() failed (113: No route to host) while connecting to upstream
        connect() failed (113: No route to host) while connecting to upstream
        733 0
        |
        存储 数据可视化 数据挖掘
        单细胞分析|将 Seurat 与多模态数据结合使用
        单细胞分析|将 Seurat 与多模态数据结合使用
        |
        存储 Kubernetes Docker
        docker-compose转化为pod配置文件
        docker-compose转化为pod配置文件
        |
        JavaScript Java 测试技术
        基于SpringBoot+Vue+uniapp的宠物小程序的详细设计和实现(源码+lw+部署文档+讲解等)
        基于SpringBoot+Vue+uniapp的宠物小程序的详细设计和实现(源码+lw+部署文档+讲解等)
        262 1
        |
        Prometheus Kubernetes Cloud Native
        Collector的配置和使用
        Collector的配置和使用
        561 1

        热门文章

        最新文章