今天在启动项目后,控制台却报出如下错误:
java.sql.SQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:833)
at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:453)
at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198)
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1643)
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1709)
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2813)
即Data source rejected establishment of connection, message from server: "Too many connections"
。
正赶上最近ChatGPT
比较火,借助他来解决我的错误:
ChatGPT
说这是数据库的连接问题,可能由于连接数过多导致的。
于是,通过如下命令查看连接数:
mysql> show global status like 'Thread%';
+-------------------+-----------+
| Variable_name | Value |
+-------------------+-----------+
| Threads_cached | 4 |
| Threads_connected | 1 |
| Threads_created | 5 |
| Threads_running | 160 |
+-------------------+-----------+
4 rows in set (0.01 sec)
Threads_cached
:MySQL
管理的线程池中还有多少可以被复用的资源。
Threads_connected
:这个数值指的是打开的连接数。
Threads_created
:表示创建过的线程数。
如果发现Threads_created
值过大的话,表明MySQL
服务器一直在创建线程,这也是比较耗资源。可以适当增加配置文件中的thread_cache_size
值,如下代码所示:
mysql> set global thread_cache_size=60;
Query OK, 0 rows affected (0.00 sec)
Threads_running
:这个数值指的是激活的连接数,这个数值一般远低于connected
数值。Threads_connected
跟show processlist
结果相同,表示当前连接数。
如下show processlist;
,执行的结果如下图:
mysql> show processlist;
+----+------+-----------------+------+---------+------+----------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------------+------+---------+------+----------+------------------+
| 62 | root | localhost:56520 | NULL | Query | 0 | starting | show processlist |
+----+------+-----------------+------+---------+------+----------+------------------+
1 row in set (0.00 sec)
Threads_connected
的值为1,而show processlist
查出1条数据。
因而,Threads_connected
跟show processlist
结果相同。
准确的来说,Threads_running
是代表当前并发数,由上可以看出并发数是160。
于是,查询数据库设置的最大连接数,如下代码所示:
mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+
1 row in set, 1 warning (0.04 sec)
数据库的并发数是160
,而最大连接数是151
。
由此可见,数据库的并发数超过了最大的连接数。因而,我们需要修改最大连接数。
除了最大连接数,还要查看连接时长,如下代码所示:
mysql> show global variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 28800 |
+---------------+-------+
1 row in set, 1 warning (0.00 sec)
连接时长是28800
,也就是默认是8
小时。
我们在修改最大连接数时,同时也要修改连接时长。
因为,数据库的并发数超过了最大的连接数,我们可按如下命令修改最大连接数:
mysql> set GLOBAL max_connections=1000;
Query OK, 0 rows affected (0.04 sec)
重新查询最大连接数,来校验是否设置成功:
mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 1000 |
+-----------------+-------+
1 row in set, 1 warning (0.01 sec)
此时,便可以Too many connections
的问题。
我们除了设置最大连接数(max_connections
),同时,也要修改mysql
的连接数的时长。
我们可以使用如下命令,修改连接时长,自动杀死线程。
mysql> set global wait_timeout=300;
Query OK, 0 rows affected (0.00 sec)
使用如下命令,查看是否修改成功:
mysql> show global variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 300 |
+---------------+-------+
1 row in set, 1 warning (0.00 sec)
这种方式只是临时修改,重启mysql
会失效。
因而,修改mysql
的配置/etc/my.cnf
。
修改完毕后,重启mysql5.7
即可:
关于show variables like 'xxx'
的更多知识,可以参考这篇博文:全网详细介绍MySQL中的show variables like ‘%xxx%’