Tornado中使用Django遇到的MySQL has gone away问题

背景,web框架使用tornado,数据库ORM使用django,然后碰到Mysql重启后,发现django后台正常,tornado web服务却一直报500:

OperationalError: (2006, 'MySQL server has gone away')

直观分析,感觉是django建立的mysql连接没有被关闭,还是使用的mysql重启前的。

还有另一种可能,mysql有一个空闲时间,超过这个时间一直未使用的连接会被关闭掉,这个时间可以通过sql查询查看:

SHOW SESSION VARIABLES LIKE 'wait_timeout'

而django的settings中有个参数,CONN_MAX_AGE ,控制的是长连接最长保持的时间,只要这个值设置的比mysql的wait_timeout小就可以避免上面说的问题。

但是我遇到的,是mysql重启后tornado报错,而django自己的admin运行正常,这说明django的管理后台有处理重新关闭、再打开mysql连接的逻辑,而我们tornado层没有。

在 django.db.__init__.py 中,有以下代码片段:

# Register an event to reset transaction state and close connections past
# their lifetime.
def close_old_connections(**kwargs):
    for conn in connections.all():
        conn.close_if_unusable_or_obsolete()
signals.request_started.connect(close_old_connections)
signals.request_finished.connect(close_old_connections)

signals.request_started 和 signals.request_finished 分别是django处理一个http请求的开始与结束信号。

我们可以仿照这个写法,在tornado的处理http请求开始与结束调用一下 close_old_connections 就ok了。

from django.db import connections
from tornado.web import RequestHandler


def close_old_connections():
    for conn in connections.all():
        conn.close_if_unusable_or_obsolete()

class CustomHandler(RequestHandler):

	def prepare(self, *args, **kwargs):
	    close_old_connections()
	    super(MoviexHandler, self).prepare(*args, **kwargs)