博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bonecp回缩功能实现
阅读量:5880 次
发布时间:2019-06-19

本文共 2934 字,大约阅读时间需要 9 分钟。

起因

bonecp不具备回缩功能,即连接池持有连接之后,不会主动去释放这些连接(即使这些连接始终处于空闲状态),因此在使用一段时间之后,连接池会达到配置的最大值。

这种方式一定程度上造成了资源的浪费。

改造

参考tomcat-jdbc的策略,每隔一段时间(可配置)会启动定时任务扫描partition中的idle队列,判断idle连接数是否大于partition可持有的最小连接数,如果是,则启动清理方法,将连接释放掉。

为了达到这个目的,实现了ConnectionCleanThread类:

package com.jolbox.bonecp;import java.sql.SQLException;import java.util.concurrent.BlockingQueue;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class ConnectionCleanThread implements Runnable {    private static final Logger logger = LoggerFactory.getLogger(ConnectionCleanThread.class);        private ConnectionPartition partition;        private BoneCP pool;        protected ConnectionCleanThread(ConnectionPartition connectionPartition, BoneCP pool) {        this.partition = connectionPartition;        this.pool = pool;    }        @Override    public void run() {        BlockingQueue freeQueue = null;        ConnectionHandle connection = null;        //获得partition的大小        int partitionSize = this.partition.getAvailableConnections();        for (int i = 0; i < partitionSize; i++) {            //得到free连接的queue            freeQueue = this.partition.getFreeConnections();            //如果空闲连接大于partition的最小允许连接数,回缩到最小允许连接数            while (freeQueue.size() > this.partition.getMinConnections()) {                connection = freeQueue.poll();                connection.lock();                closeConnection(connection);                connection.unlock();            }        }    }        /** Closes off this connection     * @param connection to close     */    private void closeConnection(ConnectionHandle connection) {        if (connection != null && !connection.isClosed()) {            try {                connection.internalClose();            } catch (SQLException e) {                logger.error("Destroy connection exception", e);            } finally {                this.pool.postDestroyConnection(connection);                connection.getOriginatingPartition().getPoolWatchThreadSignalQueue().offer(new Object()); // item being pushed is not important.            }        }    }}

同时需要对核心类ConnectionHandle进行改造,加上连接的上锁方法:

protected void lock() {    lock.writeLock().lock();}    protected void unlock() {    lock.writeLock().unlock();}

在BoneCP类的构造器内加上该线程的定时任务:

/** * 空闲连接清理任务*/private ScheduledExecutorService connectionCleanScheduler;...this.connectionCleanScheduler = Executors.newScheduledThreadPool(this.config.getPartitionCount(), new CustomThreadFactory("BoneCP-connection-clean-thread"+suffix, true));...//定期启动一个线程清理空闲连接//add 2017-2-10final Runnable connectionCleaner = new ConnectionCleanThread(connectionPartition, this);this.connectionCleanScheduler.scheduleAtFixedRate(connectionCleaner, this.config.getConnectionCleanTimeInSeconds(), this.config.getConnectionCleanTimeInSeconds(), TimeUnit.SECONDS);

效果

经过实际测试,可以在后台自动的回收idle连接。

现在只是实现了功能,各种情况暂时没有加入考虑,比如没有判断该连接是否应该被释放。

GitHub地址

转载于:https://www.cnblogs.com/wingsless/p/6387768.html

你可能感兴趣的文章
raid技术-研究感受
查看>>
远程主机探测技术FAQ集 - 扫描篇
查看>>
C++中调用python函数
查看>>
Nomad添加acl认证
查看>>
“TI门外汉”网路知识笔记一 OSI参考模型
查看>>
你不需要jQuery(五)
查看>>
DatanodeDescriptor说明
查看>>
ServlertContext
查看>>
eclipse编辑器生命周期事件监听
查看>>
Python WOL/WakeOnLan/网络唤醒数据包发送工具
查看>>
sizeof(long)
查看>>
pxe网络启动和GHOST网克
查看>>
2.5-saltstack配置apache
查看>>
django数据库中的时间格式与页面渲染出来的时间格式不一致的处理
查看>>
Python学习笔记
查看>>
java String
查看>>
renhook的使用
查看>>
Linux学习笔记(十二)--命令学习(用户创建、删除等)
查看>>
DOCKER windows 7 详细安装教程
查看>>
养眼美女绿色壁纸
查看>>