浅析 JNDI / DataSource / ConnectionPool 三者

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:

   最近有个用户量 5W-10W 的 web 应用,频繁导致 weblogic 崩溃,让运维组很难受。

   通过几天跟踪系统日志和 weblogic 运行状况,发现报错的姿势有很多,其中对定位问题比较关键的报错:

   ExecuteThread: '496' for queue: 'weblogic.kernel.Default (self-tuning)' has beenbusy for "712" seconds working on the request "XXXX", which is more than the configured time (StuckThreadMaxTime) of "600" seconds.

   weblogic 分配给 web 应用使用的线程响应返回周期最大为10分钟,线程迟迟无法返回结果导致阻塞,并且这样的刺头线程越来越多。

   运行一段时间后达到 weblogic 阻塞线程的阀值,weblogic 自然就崩溃了。

   刚开始也试着调大 weblogic 响应周期/阻塞线程的阀值,但是阻塞线程还是会存在并且很快达到阀值。

   仔细比对奔溃前后日志,查看 weblogic 阻塞线程详情,导致阻塞开始罪魁祸首是数据库查询需要很长时间。

   该系统与内外围很多厂商系统有进行数据交互,数据库里面旁根错杂的 db_link/synonyms/view/procedure。

   而且是老旧项目,代码经过很多人修改,已经风烛残年摇摇欲坠,俺想重造它不是一天两天了,因为很多原因无法进行,很无奈。

   规范数据库中的交互流程?然后动代码?oh,no! 限定解决的期限将至,不能拖。

   应用起初使用的是自带 C3P0 ConnectionPool,出现崩溃问题后,辗转尝试很多方法。

   将应用的数据库连接池改动为服务器 weblogic  JNDI ConnectionPool ,使数据库连接的压力从应用转移到 web 容器。

   崩溃问题得到了缓解,经过后续的 weblogic 连接池参数的调整,卡死崩溃问题得到妥善解决。

   实践证明 web 容器配置 JNDI 提供给应用使用效率远远大于应用自带的连接池,也使我不得不重新审视这块对于 web 项目的重要性。

   同样 JNDI 避免了程序与数据库之间的紧耦合,使应用更加易于配置、易于部署。  而且这样几乎无代码改动,只需变动下 DataSource 的获取。

   试想发布在 weblogic 上面的 10个自带连接池的应用,当数据库信息变动时,你是不是想哭?

1. DataSource / ConnectionPool /  JNDI 三者关系

   

   DataSource:数据源是在 JDBC2.0 中引入的一个概念;

                       在 JDBC 扩展包中定义了Java.sql.DataSource 接口,它负责建立与数据库的连接;

                       在应用程序访问数据库是不必编写连接数据库的代码,可直接从数据源获得数据库连接。

   ConnectionPool :在数据源中初始化建立了多个数据库连接,这些数据库连接保存在连接池(ConnectionPool)中。

                              Java程序访问数据库时,只需从连接池中取出空闲状态的数据库连接,当访问结束时,将数据库连接返回给连接池。

   JNDI : (Java Naming and Directory Interface)Java命名与目录接口;

              为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口。

              其实可以将 JNDI 理解为一种对象和名字绑定的技术,即指定一个资源名称,将该名称与某一资源或服务相关联。

              结合图和上面的简述,数据层关键性对象都已展露无遗,同样也很容易理解。

              JNDI 避免了程序与数据库之间的紧耦合,使应用更加易于配置、易于部署。

2. 配置 JNDI 数据源的方式和使用

   weblogic 上配置 JNDI 为图形界面,操作起来很方便,而且那是运维组的事情,术业有专攻。

   这里我拿 Tomcat 为例(开发时你也不可能在本机装个 weblogic 调试吧),简述下配置 JDNI 的几种方式:

a. 全局使用:Tomcat 的 conf 文件夹下的 context.xml  配置文件中添加:

复制代码
<Resource name="jndi/db_test"   
            auth="Container"   
            type="javax.sql.DataSource"   
            driverClassName="com.mysql.jdbc.Driver"   
            url="jdbc:mysql://localhost:3306/db_test"   
            username="root"   
            password="123456"   
            maxActive="20"   
            maxIdle="10"   
            maxWait="10000"/>      
复制代码

b.局部使用:Tomcat 的 conf 文件夹下 server.xml 的 <host> 标签内添加:

复制代码
Context path="/demo_jndi" docBase="/demo_jndi">  
   <Resource  
     name="jndi/db_test"  
     type="javax.sql.DataSource"  
     driverClassName="com.mysql.jdbc.Driver"  
     maxIdle="2"  
     maxWait="5000"  
     username="root"  
     password="123456"  
     url="jdbc:mysql://localhost:3306/db_test"  
     maxActive="4"/>  
</Context>  
复制代码

 c.局部使用:应用 META-INFO 下新建 context.xml 添加:

复制代码
<?xml version="1.0" encoding="UTF-8"?>  
<Context>  
    <Resource name="jndi/db_test"   
                auth="Container"   
                type="javax.sql.DataSource"   
                driverClassName="com.mysql.jdbc.Driver"   
                url="jdbc:mysql://localhost:3306/db_test"   
                username="root"   
                password="123456"   
                maxActive="20"   
                maxIdle="10"   
                maxWait="10000"/>      
</Context>  
复制代码

   上述几种配置使用的数据源都为 javax.sql.DataSource,当然你也可以引入其他开源的数据源。

   也就是 web 容器使用其他的开源数据库连接池,比如像下面这几种姿势(记得将依赖的 jar 添加到容器的 lib 中):

复制代码
<Resource name="jndi/db_test"   
            auth="Container"
            //DBCP
            type="javax.sql.DataSource"
            factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
        
            //C3P0
            type="com.mchange.v2.c3p0.ComboPooledDataSource"
            factory="org.apache.naming.factory.BeanFactory" 
              
            //Druid
            type="com.alibaba.druid.pool.DruidDataSource" 
            factory="com.alibaba.druid.pool.DruidDataSourceFactory"
            
            driverClassName="com.mysql.jdbc.Driver"   
            url="jdbc:mysql://localhost:3306/db_test"   
            username="root"   
            password="123456"   
            maxActive="20"   
            maxIdle="10"   
            maxWait="10000"/>    
复制代码

   配置好之后,使用起来也是相当的简单,核心如下2行代码即可:

    Context ctx = new InitialContext();  
    DataSource ds = (DataSource) ctx.lookup("java:comp/env/jndi/db_test");  

   如果项目中引入了 Spring 上述两行代码都可以省了,注入数据源配置,如下:

    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">  
        <property name="jndiName" value = "java:comp/env/jndi/db_test"/>  
    </bean>  

  因为命名前缀的不用,避免发布时忘记修改,统一配置 tomcat 和 weblogic 上的数据源 jndi 的方式:

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/db_test" />

 本文转自Orson博客园博客,原文链接:http://www.cnblogs.com/java-class/p/6717844.html,如需转载请自行联系原作者

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5月前
|
SQL Java 数据库连接
|
8月前
|
设计模式 Java 数据库连接
【Spring源码】JDBC数据源访问实现
我们再来看看阅读线索三,这方面我们从设计模式进行入手。阅读线索三:从这个模块可以学到什么我们看下以下代码,PreparedStatement实例的是由PreparedStatementCreator实现的。再来看看PreparedStatementCreator接口,一共有三个子类实现。也就是说PreparedStatement的三种不同实现被封装到三个子类中,而具体需要哪种实现,只需要传入不同。
【Spring源码】JDBC数据源访问实现
|
Java 关系型数据库 MySQL
Spring框架的JDBC模板技术
Spring框架的JDBC模板技术
|
Java 关系型数据库 MySQL
JNDI配置 | 学习笔记
快速学习JNDI配置
186 0
|
Java 数据库连接 容器
|
网络协议 Java 程序员
|
Java 关系型数据库 程序员
|
Java 关系型数据库 数据库
|
Java 关系型数据库 MySQL
spring 配置文件中dbcp连接池,jdbc连接池 引入 配置文件properties,但是不能用$符号引用里面的变量问题
spring 配置 注意红色字体 (1)懒加载要设为true,(2)引入配置文件  注意不能懒加载不能设为false,否则$不能引入配置文件中的变量 第一种配置 jdbc连接池 &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;beans xmlns="http://www.springframework.org/schema/b
2130 0