python - 如何使用 Python Flask API 可靠地保持 SSH 隧道和 MySQL 连接打开?

标签 python mysql docker ssh flask

我在 Flask 中构建了一个 API,可以使用 Keras 对文本消息进行分类。我目前正在使用 sshtunnel 和 MySQLdb 连接到 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)

最佳答案

好吧,我明白了。我按照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  

关于python - 如何使用 Python Flask API 可靠地保持 SSH 隧道和 MySQL 连接打开?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46607014/

相关文章:

PHPMailer 受密码保护的附件

php - 如何动态添加到PHPExcel电子表格

Docker - 绑定(bind) 0.0.0.0 :4000 failed: port is already allocated

python - 如何用堆叠在 numpy 数组中的一组图像制作电影?

python - 使用带有 MacOSX 后端的 python matplotlib 设置图形的绝对位置

mysql - 如何在具有别名的字段上进行 ORDER BY

docker - 在另一个Nginx负载平衡器之后使用多个Docker Nginx负载平衡器,这是否被认为是不好的做法?

docker - Jenkins管道 Alpine 代理 “apk update ERROR: Unable to lock database: Permission denied”

python - Django 将表迁移到新数据库

python - 运行 docker 时没有此类文件或目录