内网连接数偶尔突增

内网连接数偶尔突增,第1张

数据库连接数突增是数据库连接资源没有及时释放。

连接数据库超时是因为数据库连接资源释放的过早。

现象1:每次上线项目DB的连接数会突增。

原因:是项目关闭的时候没有释放连接资源导致。

DB的connection资源没有正常释放,导致项目启动的时候再次创建数据库连接资源,就出现了连接数突增的现象。一段时间后mysql根据wait_time的配置,自动回收conncetion,所以连接数又回落回来。

如果是是DB的connection资源没有正常释放,最可能的是在项目关闭的时候没有释放掉DB的连接资源。

经过在查看线上jekins的上线脚本后,发现线上停止项目使用的kill进程的方式来停止项目。那么就证明假设都成立了。接下来解决问题环节(程序员们喜闻乐见的百度和谷歌环节了)。

解决方案

1.主动释放

项目关闭使用正确的stop命令,保证项目能正确的释放掉各种资源。

执行命令:xxxx_tomcat.stop

2.被动释放

现象2:连接数据库超时。

com.mysql.jdbc.CommunicationsException: The last packet successfully received from the server was58129 seconds ago.The last packet sent successfully to the server was58129seconds ago, which is longer than the server configured value of'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured valuesforclient timeouts, or using the Connector/J connection property'autoReconnect=true'to avoidthisproblem. mysql

问题原因 :连接池里的connection资源mysql主动提前释放导致。

原因是在datasource连接池中配置的最大空闲时间到达之前(比如maxIdleTime,不通数据源配置名不一样),已经到达mysql的wait_timeout(最大空闲时间),是mysql主动把connection资源回收。但是项目中的连接池还持有connection,所以当项目中使用connection的时候会报CommunicationsException错误。

解决方案

1.修改mysql的wait_time,interactive_timeout把值调大(不建议如果太大,可能导致连接数较多,引起性能下降)

2.配置JDBC的重连机制autoReconnect(不建议,只有4.x版本,起作用)

jdbc:mysql://localhost:3306/test?user=root&password=&autoReconnect=true

3.减少连接池内的存活时间+JDBC探活(建议,搭配使用效果好)

最大闲置资源时间的配置

两个现象的解决方案都指向了同一个配置就是connection的最大闲置资源时间。

有两个地方可以配置最大闲置资源时间:

1.在项目的连接池中配置,比如maxIdleTime。

2.在mysql中也可以配置,interactive_timeout和wait_timeout。

三、MySql中的connection超时配置

mysql的配置中有interactive_timeout和wait_timeout两个参数,这两个参数有时候还存在覆盖的关系,所以还是给大伙说清楚一点两个的区别和联系方便大家理解。

建议interactive_timeout和wait_timeout参数值配置成一样的。

1.interactive_timeout和wait_timeout概念

mysql的连接超时时间配置

wait_timeout非交互式连接超时通过jdbc连接数据库是非交互式连接,最大闲置时间用于规定一个connection最大的空闲时间,默认是28800秒,超时MySQL会自动回收该connection。

interactive_timeout交互式连接超时通过mysql客户端连接数据库是交互式连接,最大闲置时间用于规定一个connection最大的空闲时间,默认是28800秒,超时MySQL会自动回收该connection。

2.修改配置参数的方式

1.修改配置文件my.ini

2.执行mysql命令

#修改global级别的配置

set global interactive_timeout = 10

set global wait_timeout = 10

#修改session级别的配置

set session interactive_timeout=20

set session wait_timeout=20

3.查看参数配置

mysql>show variables like '%timeout%'

+-----------------------------+----------+

| Variable_name | Value|

+-----------------------------+----------+

| connect_timeout| 10 |

| delayed_insert_timeout | 300 |

| have_statement_timeout | YES |

| innodb_flush_log_at_timeout | 1|

| innodb_lock_wait_timeout| 50 |

| innodb_rollback_on_timeout | OFF |

| interactive_timeout| 28800|

| lock_wait_timeout | 31536000 |

| net_read_timeout| 30 |

| net_write_timeout | 60 |

| rpl_stop_slave_timeout | 31536000 |

| slave_net_timeout | 60 |

| wait_timeout| 28800|

+-----------------------------+----------+

13 rows in set (0.00 sec)

3.参数不同的继承关系

1.interactive_timeout和wait_timeout配置最终生效都是作用在session交互的时候生效。

2.控制最大空闲时间的参数是wait_timeout在起作用。不管是非交互式还是交互式连接,都是wait_timeout起作用

3.交互式连接下的wait_timeout和interactive_timeout配置都会继承自全局的interactive_timeout参数。

1.wait_timeout决定连接超时时间的演示

因为我们是用mysql客户端连接,应该是交互式连接,连接超时起作用的应该是interactive_timeout参数,但是真是的这样吗。

确认设置连接空闲超时时间是WAIT_TIMEOUT

============= wait_timeout ================

mysql>set session WAIT_TIMEOUT=2

Query OK, 0 rows affected (0.00 sec)

等待2秒再次查询,连接已经丢失,说明配置生效。

mysql>select 1

ERROR 2006 (HY000): MySQL server has gone away

No connection. Trying to reconnect...

Connection id:50

Current database: *** NONE ***

+---+

| 1 |

+---+

| 1 |

+---+

1 row in set (0.00 sec)

============= interactive_timeout ================

mysql>set session interactive_timeout=2

Query OK, 0 rows affected (0.00 sec)

等待2秒再次查询,连接也没有丢失,说明配置未生效。

mysql>select 1

+---+

| 1 |

+---+

| 1 |

+---+

1 row in set (0.00 sec)

2.interactive_timeout不同的继承演示

设置interactive_timeout的配置

mysql>set global interactive_timeout=10

Query OK, 0 rows affected (0.00 sec)

mysql>select variable_name,variable_value from information_schema.global_variables where variable_name in ('interactive_timeout','wait_timeout')

+---------------------+----------------+

| variable_name | variable_value |

+---------------------+----------------+

| INTERACTIVE_TIMEOUT | 10|

| WAIT_TIMEOUT| 28800 |

+---------------------+----------------+

2 rows in set, 1 warning (0.00 sec)

新开一个窗口(交互式连接)查看,wait_timeout 和 interactive_timeout 都继承自global的interactive_timeout

交互式连接下可以看到interactive_timeout和wait_timeout都继承自全局INTERACTIVE_TIMEOUT

mysql>select variable_name,variable_value from information_schema.session_variables where variable_name in ('interactive_timeout','wait_timeout')

+---------------------+----------------+

| variable_name | variable_value |

+---------------------+----------------+

| INTERACTIVE_TIMEOUT | 10|

| WAIT_TIMEOUT| 10|

+---------------------+----------------+

2 rows in set, 1 warning (0.00 sec)

使用JDBC查询(非交互式)查看,wait_timeout继承自全局wait_timeout,interactive_timeout继承自全局interactive_timeout

Class.forName("com.mysql.jdbc.Driver")Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/deeluma_01","root","root")Statement statement = connection.createStatement()ResultSet resultSet = statement.executeQuery("select variable_name,variable_value from information_schema.session_variables where variable_name in ('interactive_timeout','wait_timeout')")while(resultSet.next()){String variable_name = resultSet.getString("variable_name")intvariable_value = resultSet.getInt("variable_value")System.out.println(variable_name+":"+variable_value)}//非交互式下查看,wait_timeout继承自全局wait_timeout,interactive_timeout继承自全局interactive_timeout//===============//INTERACTIVE_TIMEOUT:10WAIT_TIMEOUT:28800

前两天同事有个 MySQL 数据分组的需求,如下测试数据,需要找出每个 name 分组中 create_date 最近的记录:

需要注意的是,此处用的 MySQL 是5.6,最初是使用这条语句:

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10pxmargin-bottom: 10pxborder-radius: 5pxbox-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px">select name, value, create_date, update_date from t1 group by name order by create_date desc </pre>

用这条 SQL 得到的其实只是每个 name 分组中最先插入的记录,然后按照 create_date 进行了降序排列,和原始需求,完全不同。

此时可采用分而治之的策略,先做排序,再做分组:

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10pxmargin-bottom: 10pxborder-radius: 5pxbox-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px">select * from (select name, value, create_date, update_date from t1 order by create_date desc) t group by t.name </pre>

当然,针对此需求,可能有其他方法,有兴趣的朋友,可以尝试写写,共享一下。

可能有细心的朋友会发现个问题,就是上述 SQL 中的 group by ,好像有些奇怪,如果按照常规,select 中的字段需要出现在 group by 中,上述语句竟然没报错?

如果我们在 MySQL 5.7 执行相同的语句:

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10pxmargin-bottom: 10pxborder-radius: 5pxbox-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px">select name, value, create_date, update_date from t1 group by name order by create_date desc </pre>

因此从5.6升级到5.7,很可能出现这种相同的 SQL 执行结果不同的现象,这对兼容性测试的要求就会很高,究其原因,一方面是特性决定的,另一方面就是各种配置参数不同导致的。

可以在5.7的 sql_mode 中删除这个 ONLY_FULL_GROUP_BY ,即可达到5.6相同效果了,或者改写 SQL ,例如:

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10pxmargin-bottom: 10pxborder-radius: 5pxbox-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px">select * from t1 a where create_date = (select max(create_date) from t1 b where a.name = b.name) </pre>

或者,

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10pxmargin-bottom: 10pxborder-radius: 5pxbox-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px">select * from t1 a where not exists (select * from t1 b where a.name = b.name and b.create_date >a.create_date) </pre>

MySQL 8.0支持 row_number()函数, *** 作应该和如下 Oracle 相近的。

Oracle 中可以使用 row_number()实现此需求:

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10pxmargin-bottom: 10pxborder-radius: 5pxbox-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px">select * from (select name, create_date, row_number() over (partition by name order by create_date desc) as r from t1) where r=1 </pre>

1) 功能强大

MySQL 中提供了多种数据库存储引擎,各引擎各有所长,适用于不同的应用场合,用户可以选择最合适的引擎以得到最高性能,可以处理每天访问量超过数亿的高强度的搜索 Web 站点。MySQL5 支持事务、视图、存储过程、触发器等。

2) 支持跨平台

MySQL 支持至少 20 种以上的开发平台,包括 Linux、Windows、FreeBSD 、IBMAIX、AIX、FreeBSD 等。这使得在任何平台下编写的程序都可以进行移植,而不需要对程序做任何的修改。

3) 运行速度快

高速是 MySQL 的显著特性。在 MySQL 中,使用了极快的 B 树磁盘表(MyISAM)和索引压缩;通过使用优化的单扫描多连接,能够极快地实现连接;SQL 函数使用高度优化的类库实现,运行速度极快。

4) 支持面向对象

PHP 支持混合编程方式。编程方式可分为纯粹面向对象、纯粹面向过程、面句对象与面向过程混合 3 种方式。

5) 安全性高

灵活和安全的权限与密码系统,允许基本主机的验证。连接到服务器时,所有的密码传输均采用加密形式,从而保证了密码的安全。

6) 成本低

MySQL 数据库是一种完全免费的产品,用户可以直接通过网络下载。

7) 支持各种开发语言

MySQL 为各种流行的程序设计语言提供支持,为它们提供了很多的 API 函数,包括 PHP、ASP.NET、Java、Eiffel、Python、Ruby、Tcl、C、C++、Perl 语言等。

8) 数据库存储容量大

MySQL 数据库的最大有效表尺寸通常是由 *** 作系统对文件大小的限制决定的,而不是由 MySQL 内部限制决定的。InnoDB 存储引擎将 InnoDB 表保存在一个表空间内,该表空间可由数个文件创建,表空间的最大容量为 64TB,可以轻松处理拥有上千万条记录的大型数据库。

9) 支持强大的内置函数

PHP 中提供了大量内置函数,几乎涵盖了 Web 应用开发中的所有功能。它内置了数据库连接、文件上传等功能,MySQL 支持大量的扩展库,如 MySQLi 等,可以为快速开发 Web 应用提供便利。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/8658117.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-19
下一篇 2023-04-19

发表评论

登录后才能评论

评论列表(0条)

保存