背景,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)