2017-10-06 4 views
0

私はKerasでテキストメッセージの分類を実行するFlaskにAPIを構築しました。現在、sshtunnelMySQLdbを使用してMySQLデータベースに接続し、リモートデータベースからメッセージを取得しています。アプリケーション全体がDockerコンテナにラップされています。Python Flask APIでSSHトンネルとMySQL接続を確実に開いたままにするにはどうしたらいいですか?

私はリモートデータベースへの接続を確立して正常にクエリを実行できますが、POSTリクエストがAPIに入る度に新しいsshトンネルを開いて閉じているため、パフォーマンスが低下します。

私は1時間以上経ってもアクティビティがないと接続が失効し、その後APIリクエストが完了するまでに1時間かかります。

これはどのように行いましたか?この遅さは避けられませんか、定期的に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

、なぜアプリケーションの外にトンネルを開けない 'のssh -L 3306:localhostを:3306':その後、3306ユーザーの@ remote'とは'ローカルホストでアプリケーションを指しますか?パフォーマンスに関して本当に気にしているのであれば、可能であればデータベースとアプリケーションを同じネットワークに配置する必要があります。 – Suever

答えて

0

さて、私はそれを考え出しました。私はthis answerに示唆されているようにDBオブジェクトを作成しましたが、少し修正しました。私はデータベースへの接続が作成された時間を追跡し、30分ごとに接続を再確立しました。これは、データベースへの接続を再構築しているために1つまたは2つのクエリが少し時間がかかることを意味しますが、残りの部分ははるかに高速に実行され、接続は古くなりません。

以下にいくつかのコードを記載しました。私はコードが完璧ではないことを認識していますが、これまでのところ私のために働いていたものです。あなたが本当にこれをしなければならない場合

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 
関連する問題