美文网首页@IT·互联网
bonecp回缩功能的实现

bonecp回缩功能的实现

作者: 有财君 | 来源:发表于2017-02-10 15:51 被阅读0次

起因

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-10
final Runnable connectionCleaner = new ConnectionCleanThread(connectionPartition, this);
this.connectionCleanScheduler.scheduleAtFixedRate(connectionCleaner, this.config.getConnectionCleanTimeInSeconds(), this.config.getConnectionCleanTimeInSeconds(), TimeUnit.SECONDS);

效果

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

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

GitHub地址

bonecp

相关文章

  • bonecp回缩功能的实现

    起因 bonecp不具备回缩功能,即连接池持有连接之后,不会主动去释放这些连接(即使这些连接始终处于空闲状态),因...

  • 布局拼图功能实现

    一、功能简述 二、布局模板 三、布局功能实现构建矩形边框模型构建图片缩放平移模型布局绘制事件触发边框拖动规则图片缩...

  • Cron HPA动态扩缩容实践

    Kubernetes 默认 HPA 功能可实现基于Metric CPU 与 MEM 的使用率来进行动态扩缩容,在实...

  • 【转载】线程池-2

    线程池基本调度功能。 线程池自动扩容缩容。 队列缓存线程。 关闭线程池。 这些功能,最后也留下了三个待实现的 fe...

  • boneCP原理研究

    ** 转载请注明源链接:http://www.cnblogs.com/wingsless/p/6188659.ht...

  • 包子回缩、包子发硬,这三点工艺上的改进,可以帮你解决这个问题

    蒸熟后回缩变硬回缩是包子馒头制作中常见的问题。包子馒头回缩是指做好的包子经发酵膨胀后,在蒸制过程或蒸制后出现体积明...

  • react-navigation 自定义返回按钮

    需求在相应的页面实现自定义goback功能,支持回调方法。

  • Kubernetes学习系列(一)

    一、Kubernetes是容器集群管理系统,是一个开源的平台,可以实现容器集群的自动化部署、扩缩容、维护等功能。 ...

  • iOS RunLoop

    RunLoop 实现自动释放池、延迟回调、触摸事件、屏幕刷新等功能

  • Redis学习笔记

    一、Redis事务 Redis实现了基本的事务功能,但是不具有回滚功能。Redis通过使用 MULTI和EXEC两...

网友评论

    本文标题:bonecp回缩功能的实现

    本文链接:https://www.haomeiwen.com/subject/hzggittx.html