CherryPy Ping 数据库连接或重启连接

CherryPy Ping Database Connection Or Restart Connection

我使用带有本地 MySQL 数据库的 CherryPy 网络服务器 (Python 2.7)。 简而言之,几天后,我在执行新的 SQL 查询时收到以下错误:

MySQL server has gone away 

虽然我可以找到这个问题的一些来源,但它们实际上与 CherryPy 无关。重新启动 CherryPy 可解决问题。我想,CherryPy 失去了连接并且无法重新连接?

因此,我的问题是:

在下文中,我展示了一些我正在使用的简化代码版本:

def dbconnect(thread_index):
    """
    Creates a database connection for each thread that CherryPy creates
    :param thread_index:
    """
    cherrypy.thread_data.db = MySQLdb.connect("localhost", "user",
                                          "password", "databasename")

class website(object):

    @cherrypy.expose
    def index(self):
        c = cherrypy.thread_data.db.cursor()
        c.execute("Select * from ATable")
        (output,) = c.fetchone()
        # generate some html output ...


cherrypy.engine.subscribe('start_thread', dbconnect)
website = website()
cherrypy.quickstart(website)

现在,如果我在服务器上没有发生任何事情的几天后访问索引页面,索引方法会抛出 MySQL 服务器已消失 错误。

希望这个问题对于所有使用 CherryPy 并有一天遇到 SQL 错误的人来说可能会很有趣。 非常感谢:-)

CherryPy 保留一个线程池来为客户端请求提供服务。 start_thread 在其中一个线程启动时被调用,并在创建线程时创建数据库连接。在处理一些请求并处于空闲状态后,某些东西正在断开连接(可能是 mysql 客户端,或者服务器已断开连接(likely),甚至是网络上的中间服务器终止了空闲连接) .只有当该线程上的下一个请求到达时才会引发错误。

解决这个问题的一种简单但可能效率低下的方法是在每个请求上打开一个新的数据库连接 - 在 on_start_resource 或类似的地方绑定 dbconnect

也许更好的做法是同时让 start_thread 建立连接,然后让 on_start_resource 检查连接状态并在未连接时重新连接。

更好的是,我可能会做的是识别或创建一个对象来管理断开的连接,类似于 MySQLReconnectDB,它与普通 mysql.Connection 对象具有相同的接口,但会自动重新连接断开连接。 This answer 提出了一个可能的解决方案。然后,在您现有的 start_thread 处理程序中使用该实例。

我知道这不是一个完整的答案,但我希望它能为提出适合您的解决方案奠定基础。