当前位置: 首页 > wzjs >正文

做个公司网站一般多少钱深圳百度开户

做个公司网站一般多少钱,深圳百度开户,做网站前端用什么软件好,外贸网站什么采集目录 为什么需要JDBC连接池 Tomcat JDBC Pool 相关参数 1. 基本配置 2. 连接池大小控制 3. 连接验证与测试 4. 空闲连接回收 5. 连接泄漏与超时 Tomcat JDBC Pool 源码分析(tomcat 8.5.3) DataSourceFactory DataSource ConnectionPool Pool…

目录

为什么需要JDBC连接池

Tomcat JDBC Pool 相关参数

1. 基本配置

2. 连接池大小控制

3. 连接验证与测试

4. 空闲连接回收

5. 连接泄漏与超时

Tomcat JDBC Pool 源码分析(tomcat 8.5.3)

DataSourceFactory

DataSource

ConnectionPool

PoolCleaner


对于JAVA开发者来说,JDBC肯定都比较熟悉,它其实是Java提供了一套用于数据库操作的接口API,Java程序员只需要面向这套接口编程即可,不同的数据库厂商需要针对这套接口提供不同的实现。

为什么需要JDBC连接池

使用传统的jdbc做开发时,一方面频,繁的进行数据库连接操作将占用很多的系统资源,另一方面,每次拿到connection使用完都要主动去断开,那如果程序出现异常导致链接没有关闭,就会发生内存会泄露,因此可以发现使用jdbc开发时在连接管理上是存在风险的。另外,用传统的连接方法无法控制程序中创建的连接数量,如果连接过多也会导致内存泄漏。

那JDBC连接池的作用,就是可以避免频繁创建连接,帮我们做连接的生命周期管理,以及在请求较大时控制应用内连接的数量防止出现崩溃。

目前java生态里主流的JDBC连接池有HikariCP,Druid等,还有本文写的Tomcat JDBC Pool。

Tomcat JDBC Pool 相关参数

下面列举了一些基本参数和连接管理方面检测机制相关的参数

1. 基本配置

  • driverClassName
    数据库驱动类名(如 com.mysql.jdbc.Driver)。
  • url
    数据库连接 URL(如 jdbc:mysql://localhost:3306/mydb)。
  • username
    数据库用户名。
  • password
    数据库密码。

2. 连接池大小控制

  • initialSize
    连接池初始化时创建的连接数(默认 0)。
  • maxActive
    最大活跃连接数(默认 100)。
  • maxIdle
    最大空闲连接数(默认与 maxActive 相同)。
  • minIdle
    最小空闲连接数(默认 0)。
  • maxWait
    获取连接的最大等待时间(毫秒,默认 30000,超时抛异常)。

3. 连接验证与测试

  • testOnBorrow
    从池中获取连接时是否验证有效性(默认 false)。
  • testOnReturn
    归还连接时是否验证有效性(默认 false)。
  • testWhileIdle
    空闲时是否定期验证连接(默认 false)。
  • validationQuery
    用于验证连接的 SQL 查询(如 SELECT 1)。
  • validationQueryTimeout
    验证查询的超时时间(秒,默认 -1 表示无限制)。

4. 空闲连接回收

  • timeBetweenEvictionRunsMillis
    空闲连接检查线程的运行间隔(毫秒,默认 5000)。
  • minEvictableIdleTimeMillis
    连接被回收前的最小空闲时间(默认 60000)。
  • numTestsPerEvictionRun
    每次检查回收的空闲连接数(默认使用所有空闲连接)。

5. 连接泄漏与超时

  • removeAbandoned
    是否自动回收泄露的连接(默认 false)。
  • removeAbandonedTimeout
    连接被标记为泄露的时间阈值(秒,默认 60)。
  • logAbandoned
    是否记录泄露连接的堆栈信息(默认 false)。

     

Tomcat JDBC Pool 源码分析(tomcat 8.5.3)

下面简单分析下tomcat连接池是如何创建,又是如何实现连接检测的。

DataSourceFactory

DataSourceFactory是Tomcat JDBC Pool 中用来创建DataSource的工厂类,这个类在org.apache.tomcat.jdbc.pool包下。

下面是类中与连接池创建相关的部分代码片段:

public DataSource createDataSource(Properties properties) throws Exception {return createDataSource(properties,null,false);
}public DataSource createDataSource(Properties properties,Context context, boolean XA) throws Exception {PoolConfiguration poolProperties = DataSourceFactory.parsePoolProperties(properties);if (poolProperties.getDataSourceJNDI()!=null && poolProperties.getDataSource()==null) {performJNDILookup(context, poolProperties);}org.apache.tomcat.jdbc.pool.DataSource dataSource = XA? new org.apache.tomcat.jdbc.pool.XADataSource(poolProperties) : new org.apache.tomcat.jdbc.pool.DataSource(poolProperties);//创建连接池dataSource.createPool();return dataSource;
}

可以看到 DataSourceFactory.createDataSource 方法返回一个DataSource实例,DataSource初始化后调用了 createPool 方法来初始化连接池相关的组件。

DataSource

DataSource是内置了数据源连接池 ConnectionPool 的对象,基于JDBC标准对外提供了一些方法。

Tomcat JDBC Pool 中支持两种DataSource类型,一种是普通DataSource,另一种是XADataSourced。

ConnectionPool

ConnectionPool 就是连接池最核心的资源对象,但是他不会直接对外暴露,而是被包装在上面说的DataSource中,开发过程中通常先获取到的是DataSource对象实例。

了解了DataSource 和 ConnectionPool 后,继续来看DataSourceFactory.createDataSource 方法中的createPool方法逻辑,这个方法在DataSource或XADataSourced共同的父类DataSourceProxy,打开DataSourceProxy类可以进一步看具体的方法内容:

public ConnectionPool createPool() throws SQLException {if (pool != null) {return pool;} else {return pCreatePool();}
}/*** Sets up the connection pool, by creating a pooling driver.*/
private synchronized ConnectionPool pCreatePool() throws SQLException {if (pool != null) {return pool;} else {pool = new ConnectionPool(poolProperties);return pool;}
}
public ConnectionPool(PoolConfiguration prop) throws SQLException {init(prop);
}

 createPool  方法最终后调用到 init 方法:

protected void init(PoolConfiguration properties) throws SQLException {poolProperties = properties;//make sure the pool is properly configuredcheckPoolConfiguration(properties);//make space for 10 extra in case we flow over a bitbusy = new LinkedBlockingQueue<>();//busy = new FairBlockingQueue<PooledConnection>();//make space for 10 extra in case we flow over a bitif (properties.isFairQueue()) {idle = new FairBlockingQueue<>();//idle = new MultiLockFairBlockingQueue<PooledConnection>();//idle = new LinkedTransferQueue<PooledConnection>();//idle = new ArrayBlockingQueue<PooledConnection>(properties.getMaxActive(),false);} else {idle = new LinkedBlockingQueue<>();}initializePoolCleaner(properties);//create JMX MBeanif (this.getPoolProperties().isJmxEnabled()) createMBean();//Parse and create an initial set of interceptors. Letting them know the pool has started.//These interceptors will not get any connection.PoolProperties.InterceptorDefinition[] proxies = getPoolProperties().getJdbcInterceptorsAsArray();for (int i=0; i<proxies.length; i++) {try {if (log.isDebugEnabled()) {log.debug("Creating interceptor instance of class:"+proxies[i].getInterceptorClass());}JdbcInterceptor interceptor = proxies[i].getInterceptorClass().getConstructor().newInstance();interceptor.setProperties(proxies[i].getProperties());interceptor.poolStarted(this);}catch (Exception x) {log.error("Unable to inform interceptor of pool start.",x);if (jmxPool!=null) jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.NOTIFY_INIT, getStackTrace(x));close(true);SQLException ex = new SQLException();ex.initCause(x);throw ex;}}//initialize the pool with its initial set of membersPooledConnection[] initialPool = new PooledConnection[poolProperties.getInitialSize()];try {for (int i = 0; i < initialPool.length; i++) {initialPool[i] = this.borrowConnection(0, null, null); //don't wait, should be no contention} //for} catch (SQLException x) {log.error("Unable to create initial connections of pool.", x);if (!poolProperties.isIgnoreExceptionOnPreLoad()) {if (jmxPool!=null) jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.NOTIFY_INIT, getStackTrace(x));close(true);throw x;}} finally {//return the members as idle to the poolfor (int i = 0; i < initialPool.length; i++) {if (initialPool[i] != null) {try {this.returnConnection(initialPool[i]);}catch(Exception x){/*NOOP*/}} //end if} //for} //catchclosed = false;
}

这个方法中执行了 initializePoolCleaner 这个方法

 public void initializePoolCleaner(PoolConfiguration properties) {//if the evictor thread is supposed to run, start it nowif (properties.isPoolSweeperEnabled()) {poolCleaner = new PoolCleaner(this, properties.getTimeBetweenEvictionRunsMillis());poolCleaner.start();} //end if}

initializePoolCleaner 方法的逻辑是初始化一个PoolCleaner,然后启动它。

注意初始化这个构造器,传入了一个关键参数:

betweenEvictionRunsMillis

这个参数用来指定对于空闲链接检测的任务多久执行一次,默认值是5000ms,默认值实在 org.apache.tomcat.jdbc.pool.PoolProperties 类中定义的固定值,如果外部设置了会覆盖。

PoolCleaner

PoolCleaner 是 ConnectionPool 中的一个内部静态类。这个类继承TimerTask ,实例化后其实是一个线程任务,Tomcat JDBC Pool 就是通过启动这个定时任务来实现连接池中的各种检测功能。

run方法中就是检测任务的具体逻辑,包括:

1.对最小连接数的维护,数量少于最小连接数则新建补充,数量多了则销毁多余的。

2.对空闲链接的检测,如果 testWhileIdle 参数设置为true,那在任务每次执行时会获取一定数量的链接,判断是否可用,如果不可用就销毁。

 protected static class PoolCleaner extends TimerTask {protected WeakReference<ConnectionPool> pool;protected long sleepTime;PoolCleaner(ConnectionPool pool, long sleepTime) {this.pool = new WeakReference<>(pool);this.sleepTime = sleepTime;if (sleepTime <= 0) {log.warn("Database connection pool evicter thread interval is set to 0, defaulting to 30 seconds");this.sleepTime = 1000 * 30;} else if (sleepTime < 1000) {log.warn("Database connection pool evicter thread interval is set to lower than 1 second.");}}@Overridepublic void run() {ConnectionPool pool = this.pool.get();if (pool == null) {stopRunning();} else if (!pool.isClosed()) {try {if (pool.getPoolProperties().isRemoveAbandoned()|| pool.getPoolProperties().getSuspectTimeout() > 0)pool.checkAbandoned();if (pool.getPoolProperties().getMinIdle() < pool.idle.size())pool.checkIdle();if (pool.getPoolProperties().isTestWhileIdle())pool.testAllIdle();} catch (Exception x) {log.error("", x);}}}public void start() {registerCleaner(this);}public void stopRunning() {unregisterCleaner(this);}}

http://www.dtcms.com/wzjs/232862.html

相关文章:

  • 网站建设收费标准教程cnzz
  • 网站seo优化seo自媒体培训
  • 做网站密云今日要闻 最新热点
  • 网站建设视觉效果百度的营销中心上班怎么样
  • 铁岭房地产网站建设今日头条seo
  • 网站流量真难做免费b站推广网站2022
  • 南京市公共资源建设中心网站淘宝seo推广优化
  • 武汉品牌网站设计百度推广开户费用多少
  • 如何查看网站的建设者外贸网站优化
  • 优化是企业通过网站来做吗seo综合查询系统
  • 重庆网站建设开发公司友链提交入口
  • 做彩票网站要多大服务器正规推广平台
  • 教育行业怎么做网站投放竞价排名是按照什么来计费的
  • 织梦软件展示网站网上软文发稿平台
  • mvc做的游戏网站代码长沙seo公司排名
  • wordpress网站变灰班级优化大师怎么加入班级
  • 有做公司网站的吗百度seo关键词怎么做
  • 南昌专业网站建设正规代运营公司
  • 微信分享网站短链接怎么做的网页模板建站系统
  • 怎么看别人网站是怎么做的产品网络营销分析
  • ae免费素材网站网站seo优化总结
  • pinterest 网站开发语言 java pythonseo海外
  • 空间购买后打不开网站谷歌优化的最佳方案
  • 博客系统做网站营销方案包括哪些内容
  • 中英文企业网站制作广告推广平台
  • 微信里的小程序都是真的吗山西seo排名
  • 天长做网站中国国家培训网靠谱吗
  • 企业建站系统官网今天最新新闻事件报道
  • 邱县做网站宁波seo推广服务
  • 天津网站优化流程寻找郑州网站优化公司