数据库连接池,简称dbcp database connection pool存在意义:数据库的连接是非常耗费系统资源的,一个应用通常都是需要与数据库打交道,也就需要经常连接数据库,这样导致浪费大量系统资源;连接池的原理就是:我事先创建好几个数据库连接放着,当我的系统需要 *** 作数据库时就从连接池里直接拿连接,并将这个连接标记为 忙 ;用完后在放会池中,标记为 空闲;;;当连接池里的连接都在被使用,如果此时还要连接,连接池就会在创建连接放到池里,,这些连接的数量,都是在配置文件里由你控制的
数据库连接池的好处是不言而喻的,现在大部分的application
server都提供自己的数据库连接池方案,此时,只要按照application server的文档说明,正确配置,即可在应用中享受到数据库连接池的好处。
但是,有些时候,我们的应用是个独立的java
application,并不是普通的WEB/J2EE应用,而且是单独运行的,不要什么application
server的配合,这种情况下,我们就需要建立自己的数据库连接池方案了。
1、 DBCP
DBCP是Apache的一个开源项目:
commonsdbcp
DBCP依赖Apache的另外2个开源项目
commonscollections和commonspool
dbcp包,目前版本是121:>
在了解连接池之前,我们需要对长、短链接建立初步认识。我们都知道,网络通信大部分都是基于 TCP/IP 协议,数据传输之前,双方通过“ 三次握手 ”建立连接,当数据传输完成之后,又通过“ 四次挥手 ”释放连接,以下是“三次握手”与“四次挥手”示意图:
三次握手建立连接示意图:
四次挥手释放连接示意图:
长、短连接是相对通信时间而言的。长连接相对短连接而言,多了一个 保持连接 的过程,可以在一个连接上可以连续发送多个数据包,在连接保持期间,如果没有数据包发送,需要双方发链路检测包。
短连接的 *** 作步骤是:
建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接
client向server发起连接请求,server接到请求,然后双方建立连接。client向server发送消息,server回应client,然后一次请求就完成了。这时候双方任意都可以发起close *** 作,不过一般都是client先发起close *** 作。上述可知,短连接一般只会在 client/server间传递一次请求 *** 作。
短连接的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段。
长连接的 *** 作步骤是:
建立连接——数据传输…(保持连接)…数据传输——关闭连接
client向server发起连接,server接受client连接,双方建立连接,client与server完成一次请求后,它们之间的连接并不会主动关闭,后续的读写 *** 作会继续使用这个连接。
TCP长连接保持的两种办法:
自定义心跳消息头,一般客户端主动发送到服务端,服务器接收后进行回应(也可以不回应),以便能够侦测连接是否异常断开。
通过设置TCP keepalive的属性,并设置发送底层心跳包的时间间隔。TCP keepalive是在底层定时发送心跳报文,服务器端接收到底层的心跳报文直接丢弃,不关心其内容。
>
。。。,各个都系出名门,都号称具有什么什么优势,更有好事者自己开发一个连接池。那为什么要引入连接池呢?换句话说引入连接池会带来什么好处呢?下面就让我们来分析一下,探测一下谜底。[编辑]解密[编辑]数据库连接的原理
数据库连接的本底上都是tcp连接,tcp连接位于osi的4层上,所有的数据库驱动都在7层上实现自己的协议。数据库连接的协议一般都是二进制的协议。应用程序和数据库每建一个数据库其实就是在底层建立了一个tcp线路,tcp线路是有底层的 *** 作系统实现的,每个线路占用两个端口,发送端口和接收端口,这两个端口在数据交换过程中会互换角色,时而发送、时而接收。当web应用连接mysql数据库时,目标的接收端口是3306,连接时3306要被明确的指定,此时web应用方也有一个端口被占用,这个端口不需要被明确的指定,是 *** 作系统自动分配的。 *** 作系统的端口数是有限的,一般缺省可能是1024,不同的 *** 作系统会有所不同,每一个socket也是占用资源的,一般叫socket的资源描述符,这些资源对于 *** 作系统来说也是有限的,linux下通过ulimit命令可以指定更多资源。[编辑]连接无法打开原因
占用端口不释放,每一个socket在调用close后,socket会处于Time_wait状态,处于此状态的socket需要经过一段时间才能释放,这个释放时间随不同的 *** 作系统而不同,socket的不释放导致端口不释放,再次连接时 *** 作系统分配不出端口
socket文件描述符不释放,还是上面的原因,socket资源不释放, *** 作系统不能分配新的资源[编辑]建立连接的资源开销
java的数据库连接相对来说是重量级的,构建一个连接的系统开销很大,不停的关闭、创建数据库连接对应用系统来说开销太大[编辑]连接池的应用
连接池是存储、管理数据库连接的容器,应用程序把获取数据库连接的功能委托给连接池,每个连接池都有一个上限,如果连接池达到上限,应用程序线程申请连接时被堵塞,等待其他线程释放连接,每个线程使用完连接后并不马上关闭,至少把它返还给连接池。由于连接的共享,不会频繁的创建、销毁连接,因此就不会增加创建连接的开销,也不会出现socket释放延迟现象。[编辑]其他jndi连接池是整个web容器持有,容器内所有的应用共享,有可能造成应用之间的竞争
应用级的连接池,粒度较小,容易控制
package test;
import javasql;
import javautil;
public class DBConnpool
{
private int inUse = 0;
private Vector<Connection> connections = new Vector<Connection>();
private String poolname = "dbconnpool";
private String dbid = "jdbc:mysql://localhost:3306/teasystem";
private String drivername = "commysqljdbcDriver";
private String username = "root";
private String password = "123";
private int maxconn = 5000;
public DBConnpool(){}
public void setdbid(String dbid)
{
thisdbid = dbid;
}
public void setusername(String username)
{
thisusername = username;
}
public void setpassword(String password)
{
thispassword = password;
}
public void setmaxconn(int maxconn)
{
thismaxconn = maxconn;
}
public String getdbid()
{
return dbid;
}
public String getusername()
{
return username;
}
public String getpassword()
{
return password;
}
public int getmaxconn()
{
return maxconn;
}
//将连接返还给连接池
public synchronized void reConnection(Connection conn)
{
Connection con = conn;
connectionsaddElement(con);
inUse--;
}
//从连接池获取一个连接
public synchronized Connection getConnection()
{
Connection con = null;
if(connectionssize()>0)
{
con = (Connection)connectionselementAt(0);
connectionsremoveElementAt(0);
try{
if(conisClosed())
{
con = getConnection();
}
}catch(Exception e){
eprintStackTrace();
}
}else if(maxconn == 0||inUse<maxconn)
{
con = newConnection();
}
if(con != null)
{
inUse++;
}
return con;
}
private Connection newConnection()
{
Connection con = null;
try{
ClassforName(drivername);
con = DriverManagergetConnection(dbid,username,password);
}catch(Exception e){
eprintStackTrace();
return null;
}
return con;
}
public synchronized void closeConn()
{
Enumeration allConnections = connectionselements();
while(allConnectionshasMoreElements())
{
Connection con = (Connection)allConnectionsnextElement();
try{
conclose();
}catch(SQLException e){
eprintStackTrace();
}
}
}
}
使用连接池,把暂时不使用的链接放入连接池,到需要使用的时候,从连接池中取出链接使用
不能。建立连接池的目的不是为了提高查询语句的执行效率。
连接池的主要优点有以下三个方面。
第一、减少连接创建时间。连接池中的连接是已准备好的、可重复使用的,获取后可以直接访问数据库,因此减少了连接创建的次数和时间。
第二、简化的编程模式。当使用连接池时,每一个单独的线程能够像创建一个自己的JDBC连接一样 *** 作,允许用户直接使用JDBC编程技术。
第三、控制资源的使用。如果不使用连接池,每次访问数据库都需要创建一个连接,这样系统的稳定性受系统连接需求影响很大,很容易产生资源浪费和高负载异常。连接池能够使性能最大化,将资源利用控制在一定的水平之下。连接池能控制池中的连接数量,增强了系统在大量用户应用时的稳定性。
类似一个银行营业厅,开了几个窗口,然后大厅里还有等待的座位。
人们去银行办理业务,就类似于使用连接池。
你去办理业务就是使用端口,你在大厅里就是等待使用资源。
如有不明白的,请继续追问下,谢谢。
以上就是关于系统开大量的数据库连接池会有什么问题全部的内容,包括:系统开大量的数据库连接池会有什么问题、Java开发常用的几个数据库连接池、长链接、短链接与连接池等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)