暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Mysql是长连接还是短连接?

波波的小书房 2021-04-21
7936
Mysql是长连接。

什么是TCP的长连接与短连接?

长连接:
  • client与server先建立连接,连接建立后不断开,然后再进行报文发送和接收;此种方式常用于点对点通信;

短连接:
  • client与server每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接;此方式常用于一对多通信;


长连接与短连接的使用时机:

长连接:多用于操作频繁、点对点通讯、而且连接数不能太多的情况,因为每个TCP连接的建立都需要三次握手、每个TCP连接的断开要四次握手,如果每次操作都要先建立连接然后再操作的话处理速度会降低;例如:数据库的连接用长连接,如果用短连接频繁的通信会造成socket错误,频繁的socket创建也是对资源的浪费。

短连接:web网站的http服务一般都用短连接。因为长连接对于服务器来说要耗费一定的资源,像web网站这么频繁的成千上万甚至上亿客户端的连接用短连接更省一些资源。试想如果都用长连接,而且同时有成千上万的用户,每个用户都占有一个连接的话,可想而知服务器的压力有多大。所以并发量大的情况下肯定用短连接。


总之:长连接和短连接的选择要视需求而定。

下面来用JDBC代码感受一下Mysql长连接。
Class.forName("com.mysql.jdbc.Driver");
// 建立连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306", "root", "ok");
Statement stmt = conn.createStatement();
ResultSet rs1 = stmt.executeQuery("show databases");
int num = 0;
while (rs1.next()) num++;
System.out.println("当前Mysql一共有"+num+"个数据库");

stmt.execute("use test");
ResultSet rs2 = stmt.executeQuery("select * from student");
num = 0;
while (rs2.next()) num++;
System.out.println("student表一共有"+num+"条数据");

// 释放连接
conn.close();


输出结果如下。

当前Mysql一共有17个数据库
student表一共有20条数据


这段代码首先是建立了一个长连接,在连接期间,客户端一共向服务端发起了三次请求,分别是:
  • show databases

  • use test

  • select * from student

最后释放连接。

Too many connctions?

Mysql是单进程多线程。客户端每发起一次请求,Mysql都会为其建立一个连接,一个连接也就是一个线程,称为用户线程或客户端连接。当客户端连接数超过Mysql设定的最大值时,Mysql就不再接收新的请求,报出Too many connections的错误!

下面用JDBC代码演示一下Too many connections的报错。
Class.forName("com.mysql.jdbc.Driver");
for (int i=0;i<200;i++){
  new Thread(()->{
    try {
      Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306", "root", "ok");
      //使当前线程阻塞,不关闭连接
      System.in.read();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }).start();
}


程序报错信息如下。
Data source rejected establishment of connection, 
message from server: "Too many connections"



如何解决呢?有两种方案:
  1. 修改服务端配置信息

  2. 通过数据库连接池管理客户端连接


在真实的web项目中,一般都会用到数据库连接池,所以下面就来介绍一下第一种方案:如何在服务端做手脚。

我们可以执行show full processlist,来查看Mysql的连接信息,如下图所示。

User:客户端连接使用的用户
Host:客户端的ip和端口号
db:客户端连接使用的数据库
Command:客户端连接状态
Time:客户端从连接到现在的时间

我们可以看到,红色框中的客户端连接,都是刚才用JDBC代码创建的未释放的连接。

可以使用show variables like '%max_connections%'查看Mysql的最大连接数,如下图所示。


如果需要修改最大连接数,有两种方式:
  • 修改mysql启动参数文件

  • set global max_connections = 200


show variables like  '%timeout%'命令可以查看Mysql中所有关于timeout的变量,如下图所示。


闲置连接(也就是上面状态为Sleep的连接)的超时时间由wait_timeout控制,默认8小时,可以通过set wait_timeout=60修改。


会话(Session)与连接的关系?

连接是一个物理概念,而会话是一个逻辑概念,会话存在于数据库实例中。
一个连接可以有多次会话,也可以没有会话。比如打电话,先建立连接,但是有没有通话不管。当双方进行通话,则 session建立了,如果换人,则新的session建立,原session结束,因此可以在同一个connect上进行多个会话;最后挂 机,connect结束。
一个会话可以创建多个事务,事务只能由会话来创建。
一个事务可能会产生一个或多个线程,比如RMAN备份,是可以创建多个线程可加快备份速度。
一个线程在同一时间内只能执行一个事务,在没结束当前事务前是无法释放资源来执行第二个事务的。

上述关系可以理解为:连接>会话>事务>线程
文章转载自波波的小书房,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论