如何使用我的Python Flask API可靠地保持SSH隧道和MySQL连接?

时间:2017-10-06 13:34:33

标签: python mysql docker ssh flask

我在Flask中构建了一个API,使用Keras对文本消息进行分类。我目前正在使用sshtunnelMySQLdb连接到MySQL数据库以从远程数据库获取消息。整个应用程序都包含在Docker容器中。

我能够建立与远程数据库的连接并成功查询它,但每次POST请求进入API时我都会打开并关闭一个新的ssh隧道,这会降低性能。

我试图打开一个单独的ssh隧道和数据库连接“以统治它们”,但是如果一小时左右没有活动,连接就会变得陈旧,然后API请求将永远需要一天才能完成。

你是怎么做到的?这种缓慢是不可避免的还是有办法定期刷新ssh和数据库连接?

这就是我为每个传入请求连接到我的数据库的方式:

with SSHTunnelForwarder(
          (host, 22),
          ssh_username=ssh_username,
          ssh_private_key=ssh_private_key,
          remote_bind_address=(localhost, 3306)
     ) as server:
          conn = db.connect(host=localhost,
          port=server.local_bind_port,
          user=user,
          passwd=password,
          db=database)

1 个答案:

答案 0 :(得分:2)

好的,我明白了。我按照this answer中的建议创建了一个数据库对象,但略有修改。我跟踪创建与数据库的连接的时间,然后每30分钟重新建立一次连接。这意味着一两个查询需要稍长一些,因为我正在重建与数据库的连接,但其余的运行速度更快,连接也不会过时。

我在下面提供了一些代码。我意识到代码并不完美,但到目前为止它对我有用。

import MySQLdb as mydb
import time
import pandas as pd
from sshtunnel import SSHTunnelForwarder

class DB:

    def __init__(self):
        self.open_ssh_tunnel()

        self.conn = None

        self.server = None

        self.connect()

        self.last_connected_time = time.time()


    def open_ssh_tunnel(self):
        connection_success = False

        while not connection_success:
            try:
                self.server = SSHTunnelForwarder(
                        (host, 22),
                        ssh_username=ssh_username,
                        ssh_private_key=ssh_private_key,
                        ssh_password=ssh_pwd,
                        remote_bind_address=(localhost, 3306))
                connection_success = True
            except:
                time.sleep(0.5)

        self.server.start()


    def connect(self):
        connection_success = False

        while not connection_success:
            try:
                self.conn = mydb.connect(host=localhost,
                        port=server.local_bind_port,
                        user=user,
                        passwd=password,
                        db=database)
                connection_success = True
            except:
                time.sleep(0.5)


    def query(self, sql):

        result = None
        current_time = time.time()

        if current_time - self.last_connected_time > 1600:
            self.last_connected_time = current_time
            self.server.close()
            self.conn.close()
            self.open_ssh_tunnel()
            self.connect()
        try:
            result = pd.read_sql_query(sql, self.conn).values
            self.conn.commit()
        except:
            self.server.close()
            self.conn.close()
            self.open_ssh_tunnel()
            self.connect()
            result = pd.read_sql_query(sql, self.conn).values

        return result