Rails Mysql2::Error: closed MySQL connection 报错

来源:互联网 发布:能听裂空小说软件 编辑:程序博客网 时间:2024/05/21 21:35

最近遇到一个问题,查询数据库的时候报了一个Mysql2::Error: closed MySQL connection 的错误。为什么会出现这种错误呢?我分析了一下:

我使用的是mysql,姑且用mysql服务做说明。

mysql server有个配置项:wait_timeout,我们查查官方文档:

connect_timeoutCommand-Line Format--connect_timeout=#System VariableNameconnect_timeoutVariable ScopeGlobalDynamic VariableYesPermitted ValuesTypeintegerDefault10Min Value2Max Value31536000The number of seconds that the mysqld server waits for a connect packet before responding with Bad handshake. The default value is 10 seconds.Increasing the connect_timeout value might help if clients frequently encounter errors of the form Lost connection to MySQL server at 'XXX', system error: errno. 
不仔细解释了,这个配置项的意思就是一个数据库连接的等待超时时间,就是说,如果一个连接建立之后,如果超过这个时间没有操作,这个连接就会断开。

基于这个知识点,我来解释一下我为什么会出现这个错误。
我的使用场景是启动一个进程,在这个进程里会得到别的服务推送过来的数据,然后根据这些数据去查库写库,当长时间没有数据来的时候,不会查库和写库,如果mysql server的wait_timeout的配置是600,如果600秒还是没有操作,这个连接就会断开,当有数据来的时候,去拿这个连接进行数据库操作就会报出这个错误Mysql2::Error: closed MySQL connection 。

怎么避免这个问题呢?

我想到了两个方案,第一个是保持连接不断开,第二个是如果连接断开了,就重连。

保持连接不断

我们可以在这个进程里启动一个线程每20秒进行一个最普通、最快的查询:
ActiveRecord::Base.connection.execute('select 1;')
至于怎么启动线程,这里就不多说了。
这样,我们可以定时的使用这个连接,连接就不会等待超时。

断开重连

这种方式就是在操作数据库之前,查看连接状态,如果断开了,就进行重连,rails的代码如下:
unless ActiveRecord::Base.connection.active?  ActiveRecord::Base.connection.reconnect!end
rails针对这个有处理方法,rails还是很强大的。
ActiveRecord::Base.connection.verify!

至于用什么方式去处理这个问题,就需要斟酌一下了。我建议使用第一种,因为第二种需要在业务代码里加入判断逻辑,第一种处理方式不会干扰业务代码的执行。



0 0
原创粉丝点击