apache的commons-pool2原理与使用详解

news2025/7/21 11:17:36

Apache Commons Pool2 是一个高效的对象池化框架,通过复用昂贵资源(如数据库连接、线程、网络连接)优化系统性能。

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

在这里插入图片描述


一、核心原理与组件

  1. 三大核心模块
    • ObjectPool(对象池)

    管理对象的生命周期,提供borrowObject()(借出)和returnObject()(归还)方法,内部通过LinkedBlockingDeque维护空闲对象队列,并支持LIFO(默认)或FIFO策略。
    • PooledObject(池化对象)

    对原生对象的包装类(如DefaultPooledObject),记录对象状态(IDLE、ALLOCATED、EVICTION等)、创建时间、最后使用时间等元数据,便于池管理。
    • PooledObjectFactory(对象工厂)

    定义对象创建、销毁、验证等逻辑,需用户实现以下方法:
    makeObject():创建新对象并包装为PooledObject

    destroyObject():销毁不再可用的对象;

    validateObject():检查对象是否有效;

    activateObject()/passivateObject():激活或钝化对象状态(如重置连接)。

  2. 对象生命周期管理流程
    • 借出对象:

    1. 检查空闲队列是否存在有效对象;

    2. 若无效则销毁,并创建新对象(未达maxTotal上限时);

    3. 返回对象前调用activateObject()激活。
      • 归还对象:

    4. 调用validateObject()验证有效性;

    5. 若有效则passivateObject()钝化后放回空闲队列;

    6. 若空闲对象超过maxIdle或池已关闭,则销毁对象。


二、使用步骤详解(以数据库连接池为例)

  1. 添加依赖

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.11.1</version>
    </dependency>
    
  2. 实现对象工厂

    public class ConnectionFactory extends BasePooledObjectFactory<Connection> {
        @Override
        public Connection create() throws Exception {
            return DriverManager.getConnection("jdbc:mysql://localhost:3306/test");
        }
    
        @Override
        public PooledObject<Connection> wrap(Connection conn) {
            return new DefaultPooledObject<>(conn);
        }
    
        @Override
        public boolean validateObject(PooledObject<Connection> p) {
            return p.getObject().isValid(5); // 检查连接有效性
        }
    }
    
  3. 配置对象池参数

    GenericObjectPoolConfig<Connection> config = new GenericObjectPoolConfig<>();
    config.setMaxTotal(50);       // 最大对象数
    config.setMaxIdle(10);        // 最大空闲数
    config.setMinIdle(5);        // 最小空闲数
    config.setTestWhileIdle(true); // 空闲时定期验证
    config.setTimeBetweenEvictionRunsMillis(30000); // 驱逐检查周期
    
  4. 创建池实例并操作

    ObjectPool<Connection> pool = new GenericObjectPool<>(new ConnectionFactory(), config);
    // 借出对象
    Connection conn = pool.borrowObject();
    // 使用对象执行SQL...
    // 归还对象
    pool.returnObject(conn);
    

三、高级配置与优化

  1. 关键参数解析

    参数名作用
    maxTotal池中最大对象数,防止资源耗尽
    maxIdle / minIdle控制空闲对象数量,平衡资源占用与快速响应
    testOnBorrow / testOnReturn借出或归还时验证对象有效性,确保可用性但增加延迟
    blockWhenExhausted资源耗尽时是否阻塞等待(maxWaitMillis设置超时时间)
  2. 性能优化建议
    • 避免频繁驱逐:设置较长的timeBetweenEvictionRunsMillis(如30秒),减少检查开销。

    • 异步操作支持:通过GenericObjectPool的异步方法提升高并发场景下的吞吐量。

    • 资源泄漏防护:结合LeakDetectionHandler监控未归还的对象,设置removeAbandonedTimeout自动回收。


四、典型应用场景

  1. 数据库连接池
    如DBCP、HikariCP底层依赖Commons Pool2,复用连接减少TCP握手开销。
  2. Redis客户端连接池
    Jedis通过JedisPool管理连接,避免频繁创建Socket。
  3. FTP连接池
    复用FTPClient对象,减少登录/注销开销(需实现activateObject重置连接状态)。
  4. 自定义资源池
    如线程池、内存缓存对象池,适用于创建成本高的对象。

五、注意事项与最佳实践

  1. 资源泄漏处理
    finally块中确保returnObject()调用,或使用try-with-resources模式包装池对象。
  2. 异常管理
    捕获destroyObject()中的异常,避免因个别对象销毁失败影响整体池稳定性。
  3. 线程安全
    GenericObjectPool内部通过锁机制保证并发安全,但自定义工厂需确保create()等方法的线程安全性。

六、Lettuce 使用 Apache Commons Pool2

Lettuce 是 Spring Boot 默认的 Redis 客户端,其本身通过 commons-pool2 提供连接池支持,适用于需要控制连接复用或处理阻塞操作的场景。以下是基于 commons-pool2 的 Lettuce 连接池完整使用实例及关键要点:


1、核心依赖配置

Lettuce 连接池依赖 commons-pool2,需在项目中显式引入:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.11.1</version>
</dependency>

若未添加此依赖,连接池功能将无法启用。


2、连接池参数配置(YAML 示例)

在 Spring Boot 的 application.yml 中配置连接池参数:

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    lettuce:
      pool:
        max-active: 20    # 最大活跃连接数
        max-idle: 10      # 最大空闲连接
        min-idle: 5       # 最小空闲连接
        max-wait: 5000ms  # 获取连接最大等待时间
        time-between-eviction-runs: 30000ms  # 空闲连接检查周期

此配置会通过 LettuceConnectionFactory 自动创建连接池实例。


3、代码实例:手动创建连接池

对于非 Spring 环境或需要自定义的场景,可手动创建 GenericObjectPool

// 创建 RedisClient
RedisClient client = RedisClient.create("redis://localhost:6379");

// 配置连接池参数
GenericObjectPoolConfig<StatefulRedisConnection<String, String>> poolConfig = new GenericObjectPoolConfig<>();
poolConfig.setMaxTotal(20);
poolConfig.setMaxIdle(10);
poolConfig.setMinIdle(5);

// 创建连接池(包装连接模式)
GenericObjectPool<StatefulRedisConnection<String, String>> pool = ConnectionPoolSupport.createGenericObjectPool(
    () -> client.connect(),  // 连接工厂
    poolConfig,
    true  // 包装连接,close() 自动归还
);

// 使用示例
try (StatefulRedisConnection<String, String> connection = pool.borrowObject()) {
    RedisCommands<String, String> commands = connection.sync();
    commands.set("key", "value");
}  // 此处自动调用 close() 归还连接到池中

• 包装模式(wrapConnections=true):调用 connection.close() 时自动归还连接。

• 直接模式(wrapConnections=false):需手动调用 pool.returnObject(connection) 归还。


4、连接池生效验证
  1. 性能对比
    插入大量数据时,开启连接池的执行速度显著快于单连接(如 1W 条数据耗时减少 30%+)。

  2. 连接数监控
    使用 redis-cli info clients 或 Linux 命令 lsof -i:6379 查看实际连接数。初始可能仅 1 个连接,随压力增加逐步升至 max-active,空闲后逐步回收至 min-idle


5、关键注意事项
  1. 共享连接开关
    Spring Boot 默认开启 shareNativeConnection,需在配置类中关闭以强制使用连接池:

    @Bean
    public LettuceConnectionFactory lettuceConnectionFactory() {
        LettuceConnectionFactory factory = new LettuceConnectionFactory();
        factory.setShareNativeConnection(false);  // 禁用共享连接
        return factory;
    }
    

    否则连接池配置可能不生效。

  2. 阻塞操作与事务
    涉及 BLPOP、事务(MULTI/EXEC)等阻塞操作时,必须使用连接池避免线程阻塞。

  3. 异常处理
    • 确保 borrowObject()returnObject()try-finally 块中调用,防止连接泄漏。

    • 捕获 RedisConnectionException 处理连接失效问题,配置 testWhileIdle 定期验证连接有效性。


6、扩展配置项
参数名作用默认值
max-active最大活跃连接数(并发上限)8
min-idle最小空闲连接(预热保留)0
max-wait获取连接超时时间(-1 表示无限等待)-1
time-between-eviction-runs空闲连接驱逐检查周期禁用
test-on-borrow借出时是否验证连接有效性false

Lettuce 通过 commons-pool2 实现灵活连接池管理,适用于高并发或需要资源隔离的场景。在 Spring Boot 中通过 YAML 配置即可快速启用,非 Spring 项目则需手动创建 GenericObjectPool 并管理连接生命周期。关键点在于正确关闭共享连接、验证池化效果及处理阻塞操作,以充分发挥连接池的性能优势。


总结

Apache Commons Pool2通过标准化的对象池管理机制,显著提升了高成本资源的使用效率。其核心在于对象复用与生命周期控制,结合灵活的配置参数,可广泛应用于数据库、网络连接等场景。开发者需重点掌握工厂实现、池配置优化及异常处理,以构建高性能、稳定的资源池。

Lettuce使用详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2392326.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

打印Yolo预训练模型的所有类别及对应的id

有时候我们可能只需要用yolo模型检测个别类别&#xff0c;并显示&#xff0c;这就需要知道id&#xff0c;以下代码可打印出 from ultralytics import YOLO# 加载模型 model YOLO(yolo11x.pt)# 打印所有类别名称及其对应的ID print(model.names) {0: person, 1: bicycle, 2: c…

设计模式26——解释器模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 解释器模式&#xff08;Interp…

在MDK中自动部署LVGL,在stm32f407ZGT6移植LVGL-8.3,运行demo,显示label

在MDK中自动部署LVGL&#xff0c;在stm32f407ZGT6移植LVGL-8.3 一、硬件平台二、实现功能三、移植步骤1、下载LVGL-8.42、MDK中安装LVGL-8.43、配置RTE4、配置头文件 lv_conf_cmsis.h5、配置lv_port_disp_template 四、添加心跳相关文件1、在STM32CubeMX中配置TIM7的参数2、使能…

ArcGIS 与 HEC-RAS 协同:流域水文分析与洪水模拟全流程

技术点目录 洪水淹没危险性评价方法及技术介绍基于ArcGIS的水文分析基于HecRAS淹没模拟的洪水危险性评价洪水风险评价综合案例分析应用了解更多 —————————————————————————————————————————————————— 前言综述 洪水危险性及…

多模态大语言模型arxiv论文略读(九十九)

PartGLEE: A Foundation Model for Recognizing and Parsing Any Objects ➡️ 论文标题&#xff1a;PartGLEE: A Foundation Model for Recognizing and Parsing Any Objects ➡️ 论文作者&#xff1a;Junyi Li, Junfeng Wu, Weizhi Zhao, Song Bai, Xiang Bai ➡️ 研究机构…

Fine-tuning:微调技术,训练方式,LLaMA-Factory,ms-swift

1&#xff0c;微调技术 特征Full-tuningFreeze-tuningLoRAQLoRA训练参数量全部少量极少极少显存需求高低很低最低模型性能最佳中等较好接近 LoRA模型修改方式无变化局部冻结插入模块量化插入模块多任务共享不便较便非常适合非常适合适合超大模型微调❌✅✅✅&#xff08;最优&…

XCTF-web-mfw

发现了git 使用GitHack下载一下源文件&#xff0c;找到了php源代码 <?phpif (isset($_GET[page])) {$page $_GET[page]; } else {$page "home"; }$file "templates/" . $page . ".php";// I heard .. is dangerous! assert("strpos…

电机控制选 STM32 还是 DSP?技术选型背后的现实博弈

现在搞电机控制&#xff0c;圈里人都门儿清 —— 主流方案早就被 STM32 这些 Cortex-M 单片机给拿捏了。可要是撞上系统里的老甲方&#xff0c;技术认知还停留在诺基亚砸核桃的年代&#xff0c;非揪着 DSP 不放&#xff0c;咱也只能赔笑脸&#xff1a;“您老说的对&#xff0c;…

.NET 开源工业视觉系统 OpenIVS 快速搭建自动化检测平台

前言 随着工业4.0和智能制造的发展&#xff0c;工业视觉在质检、定位、识别等场景中发挥着越来越重要的作用。然而&#xff0c;开发一个完整的工业视觉系统往往需要集成相机控制、图像采集、图像处理、AI推理、PLC通信等多个模块&#xff0c;这对开发人员提出了较高的技术要求…

AI智能分析网关V4室内消防逃生通道占用检测算法打造住宅/商业/工业园区等场景应用方案

一、方案背景​ 火灾严重威胁生命财产安全&#xff0c;消防逃生通道畅通是人员疏散的关键。但现实中通道被占用、堵塞现象频发&#xff0c;传统人工巡查监管效率低、不及时。AI智能分析网关V4结合消防逃生通道占用算法&#xff0c;以强大的图像识别和数据分析能力&#xff0c;…

关于无法下载Qt离线安装包的说明

不知道出于什么原因考虑&#xff0c;Qt官方目前不提供离线的安装包下载&#xff0c;意味着网上各种文章提供的各种下载地址都失效了&#xff0c;会提示Download from your IP address is not allowed&#xff0c;当然目前可以在线安装&#xff0c;但是据说只提供了从5.15开始的…

Java开发经验——阿里巴巴编码规范实践解析4

摘要 本文主要介绍了阿里巴巴编码规范中关于日志处理的相关实践解析。强调了使用日志框架&#xff08;如 SLF4J、JCL&#xff09;而非直接使用日志系统&#xff08;如 Log4j、Logback&#xff09;的 API 的重要性&#xff0c;包括解耦日志实现、统一日志调用方式等好处。同时&…

HTML应用指南:利用GET请求获取全国捞王锅物料理门店位置信息

随着新零售业态的快速发展&#xff0c;门店位置信息的获取变得越来越重要。作为知名中式餐饮品牌之一&#xff0c;捞王锅物料理自2009年创立以来&#xff0c;始终致力于为消费者提供高品质的锅物料理与贴心的服务体验。经过多年的发展&#xff0c;捞王在全国范围内不断拓展门店…

算法日记32:埃式筛、gcd和lcm、快速幂、乘法逆元

一、埃式筛&#xff08;计算质数&#xff09; 1.1、概念 1.1.1、在传统的计算质数中&#xff0c;我们采用单点判断&#xff0c;即判断(2~sqrt(n))是否存在不合法元素&#xff0c;若存在则判否&#xff0c;否则判是 1.1.2、假设&#xff0c;此时我们需要求1~1000的所有质数&am…

黑马点评-分布式锁Lua脚本

文章目录 分布式锁Redis setnxredis锁误删Lua脚本 分布式锁 当我们的项目服务器不只是一台&#xff08;单体&#xff09;&#xff0c;而是部署在多态服务器上&#xff08;集群/分布式&#xff09;&#xff0c;同样会出现线程安全问题。不同服务器内部有不同的JVM&#xff0c;每…

机械师安装ubantu双系统:三、GPT分区安装Ubantu

目录 一、查看磁盘格式 二、安装ubantu 参考链接&#xff1a; GPT分区安装Ubuntu_哔哩哔哩_bilibili 一、查看磁盘格式 右击左边灰色区域&#xff0c;点击属性 二、安装ubantu 插入磁盘&#xff0c;重启系统&#xff0c;狂按F7&#xff08;具体我也忘了&#xff09;&#…

kafka学习笔记(三、消费者Consumer使用教程——从指定位置消费)

1.简介 Kafka的poll()方法消费无法精准的掌握其消费的起始位置&#xff0c;auto.offset.reset参数也只能在比较粗粒度的指定消费方式。更细粒度的消费方式kafka提供了seek()方法可以指定位移消费允许消费者从特定位置&#xff08;如固定偏移量、时间戳或分区首尾&#xff09;开…

【后端高阶面经:架构篇】46、分布式架构:如何应对高并发的用户请求

一、架构设计原则:构建可扩展的系统基石 在分布式系统中,高并发场景对架构设计提出了极高要求。 分层解耦与模块化是应对复杂业务的核心策略,通过将系统划分为客户端、CDN/边缘节点、API网关、微服务集群、缓存层和数据库层等多个层次,实现各模块的独立演进与维护。 1.1 …

网络编程学习笔记——TCP网络编程

文章目录 1、socket()函数2、bind()函数3、listen()4、accept()5、connect()6、send()/write()7、recv()/read()8、套接字的关闭9、TCP循环服务器模型10、TCP多线程服务器11、TCP多进程并发服务器 网络编程常用函数 socket() 创建套接字bind() 绑定本机地址和端口connect() …

Vue+element-ui,实现表格渲染缩略图,鼠标悬浮缩略图放大,点击缩略图播放视频(一)

Vueelement-ui&#xff0c;实现表格渲染缩略图&#xff0c;鼠标悬浮缩略图放大&#xff0c;点击缩略图播放视频 前言整体代码预览图具体分析基础结构主要标签作用videoel-popover 前言 如标题&#xff0c;需要实现这样的业务 此处文章所实现的&#xff0c;是静态视频资源。 注…