软件设计思想:池化技术

简介: 软件设计思想:池化技术

软件设计思想:池化技术



先举个例子


一种简单的架构:前端一台 Web 服务器运行业务代码,后端一台数据库服务器存储业务数据。


640.png


系统上线时,用户量不大,运行平稳,但是随着流量的提升,系统访问速度会变慢。

分析日志后,发现系统慢的原因是出现在系统库的交互上,因为数据调用的方式是首先获取数据库的连接,然后依靠这个连接,查询数据库的数据,最后释放数据库资源。


为什么频繁创建连接响应会变慢?


整个 MySQL 创建连接过程主要分成两个部分:

  1. 第一部分是采用建立 TCP 连接。通过三次握手 建立 TCP 连接。
  • 客户端向服务端发送一个 SYN 包
  • 服务端给客户端发送一个 ACK  包和一个 SYN 包
  • 第三个是客户端给服务端发送一个 ACK  包
  1. 第二部分是 MySQL 服务端校验客户端密码的过程

第一个包是服务端给客户端要认证的报文,第二个和第三个包是客户端加密后发送给服务端的包,最后两个包是服务端给客户端 OK  的报文。

数据校验过程大概占整个查询过程的80% 时间,比如 数据校验占 4ms ,查询过程使用 1ms 这样频繁创建连接,创建连接严重影响了性能。


如何优化呢?


如果数据库不再频繁创建连接,如果实现就使用连接池,将连接先建立好,这样不频繁创建连接,那么查询性能会大大提升。

用连接池预先建立数据库连接

开发过程中往往会用到很多连接池,比如数据库连接池, HTTP 连接池,Redis 连接池等。


数据库连接池配置


  • 如果当前连接数小于最小连接数,则创建新的数据库请求;
  • 如果连接池中有空闲连接则复用空闲连接
  • 如果空闲池中没有连接并且连接数小于最大连接数,则创建新的连接处理请求;
  • 如果当前连接数已经大于等于最大连接数,则按照配种中设定的时间(c3p0 checkoutTimeOut)等待旧连接可用。
  • 如果等待超过这个设定值则向用户抛出异常。

看个实例:


<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="xxxx"/>
        <property name="username" value="xxxx"/>
        <property name="password" value="xxxx"/>
        <!-- 连接池最大数量 --> 
        <property name="maxActive" value="60"/>
        <!-- 初始化连接大小 -->
        <property name="initialSize" value="5"/>
         <!-- 连接池最小空闲 -->  
        <property name="minIdle" value="5"/>
        <!-- 连接池最大空闲 -->  
        <property name="maxIdle" value="10"/>
        <!-- 获取连接最大等待时间 -->  
        <property name="maxWait" value="60000"/>
        <property name="testOnBorrow" value="true"/>
        <!-- 是否对sql进行自动提交-->
        <property name="defaultAutoCommit" value="true"/>
        <!-- 读写1分钟超时 -->
        <property name="connectionProperties" value="oracle.jdbc.ReadTimeout=60000"/> 
        <property name="validationQuery" value="SELECT 1 FROM dual"/>
    </bean>


"select 1"  的命令用来检查连接是否可用。

testOnBorrow 配置项 是先校验连接是否可用,如果可用采用执行 SQL 语句。这种连接方式会引入多余的开销,线上可用尽量不要使用,在测试服务上可用。


  • initialSize,连接初始值,连接池启动时创建的连接数量的初始值
  • maxActive,连接池的最大值,同一时间可以从池分配的最多连接数量,0时无限制
  • maxIdle,最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 ,0时无限制
  • minIdle,最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请
  • poolPreparedStatements,是否对已备语句进行池管理(布尔值),是否对PreparedStatement进行缓存
  • defaultAutoCommit,是否对sql进行自动提交,进行事务管理的时候往往要关闭jdbc的自动提交功能。

假设有一个接口,需要三次访问数据库,但是根据经验判断,觉得这个可能成为系统瓶颈,为避免频繁创建线程导致的开销,可以使用线程池来管理多个线程与数据库的交互


用线程池创建线程


JDK 1.5 中引入的 ThreadPoolExecutor 就是一种线程池的实现,有几个重要的参数:coreThreadPool 和 maxThreadCount,这两个参数控制整个线程池的执行过程。

  • 当线程池中的线程数小于 coreThreadCount 时,处理新的任务是会创建新的线程。
  • 如果线程数大于 coreThreadCount ,则把任务丢到一个队列中,当有空闲线程再执行。
  • 当队列中的任务队列满了的时候,则继续创建线程,直到达到 maxThreadCount。
  • 当线程数达到 maxThreadCount 时,还有新的任务提交,那么我们不得不将他们丢弃。


640.png


实际项目中曾经有这么个问题,任务丢给线程池后,长时间都没有被执行,后来排查发现是 coreThreadCount 和 maxThreadCount 设置的比较小。


池化技术


池化技术的思想: 核心思想是空间换时间,期望使用预先创建好的对象来减少频繁创建对象的性能开销,同时还可以对对象进行统一管理,减少对象使用成本。


总结


  • 池子的最大值和最小值设置需要根据实际运行情况做调整
  • 池子中的对象在需要在使用前预先初始化,比如线程池先创建核心线程。
  • 池化技术的核心思想是空间换时间,避免出现空间过度使用出现内存泄露或者频繁垃圾回收等问题。
相关文章
|
前端开发 JavaScript Java
JavaScript闭包深入剖析:性能剖析与优化技巧
JavaScript 闭包是强大而灵活的特性,广泛应用于数据封装、函数柯里化和事件处理等场景。闭包通过保存外部作用域的变量,实现了私有变量和方法的创建,提升了代码的安全性和可维护性。然而,闭包也可能带来性能问题,如内存泄漏和执行效率下降。为优化闭包性能,建议采取以下策略:及时解除对不再使用的闭包变量的引用,减少闭包的创建次数,使用 WeakMap 管理弱引用,以及优化闭包结构以减少作用域链查找的开销。在实际开发中,无论是 Web 前端还是 Node.js 后端,这些优化措施都能显著提升程序的性能和稳定性。
488 70
|
安全 Java Maven
关于安卓artifactory本地仓库搭建
关于安卓artifactory本地仓库搭建
796 0
|
API Android开发 开发者
AppCompat 用了这么久,你真的了解吗?
为了能够让低版本的Android系统能够运行新特性,AppCompat框架自Support时代就已推出。但随着AndroidX的一统江湖,AppCompat的相关类则一并迁移到了AndroidX库里。
1196 0
|
安全 Java 数据库连接
C# | 对象池
当我们在做软件开发时经常会需要创建很多的相同且特殊的对象,比如线程、内存、数据库连接、文件句柄等,这类特殊对象有着占用IO资源、创建或销毁的开销大等特点,会导致系统的性能下降和资源浪费。而对象池的出现就是为了解决此类问题,使用对象池来管理这些对象让它们可以被重复使用,从而提高效率。
424 0
|
存储 算法 NoSQL
面试官:什么是对象池?有什么用?别说你还不会!
对象池顾名思义就是存放对象的池,与我们常听到的线程池、数据库连接池、http连接池等一样,都是典型的池化设计思想。 对象池的优点就是可以集中管理池中对象,减少频繁创建和销毁长期使用的对象,从而提升复用性,以节约资源的消耗,可以有效避免频繁为对象分配内存和释放堆中内存,进而减轻jvm垃圾收集器的负担,避免内存抖动。
780 0
深圳:新版创业担保贷款实施办法出台
7月6日,深圳市人力资源和社会保障局、市财政局、市地方金融监管局、人民银行深圳市中心支行联合制定了《深圳市创业担保贷款实施办法》。
|
6天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
6225 8
|
4天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
1172 3
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
5天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
705 4

热门文章

最新文章