3

MySQL データベースからレコードをクエリするための ORM レイヤーとして嵐を使用して、web.py に基づく Web サービスを作成しています。Web サービスは、Linux ボックスで Apache2 を使用して mod_wsgi 経由でデプロイされます。create_database()ストームの方法を使用してスクリプトを開始すると、MySQL データベース サーバーへの接続が作成されます。Storeこれは、後でリクエストが入ったときにクエリを実行するために使用されるオブジェクトを作成するポイントでもあります。

非アクティブ状態が数時間続くとstore.find()DisconnectionError: (2006, 'MySQL server has gone away'). Apache/mod_wsgi が Python プロセスを長時間再初期化せずに再利用するため、データベース接続が切断されることに驚きはありません。私の質問は、これを正しく処理する方法ですか?

「SELECT 1」を繰り返し (300 秒ごとに) 送信することで、MySQL サーバーへの接続を維持するメカニズムをセットアップしようとしました。残念ながら、テスト マシンの問題は修正されましたが、デモ展開 (痛い) では解決されませんでしたが、どちらも同じ MySQL 構成を共有しています (wait_timeoutは 8 時間に設定されています)。

ストーム ストアをデータベースに再接続するための解決策を探しましたが、洗練されたものは見つかりませんでした。唯一の推奨事項は、例外をキャッチし、それを矛盾として扱いrollback()、ストアを呼び出してから再試行する必要があるようです。Storeただし、これは、クラス全体をラップするか、同じ再試行メカニズムを何度も実装する必要があることを意味します。より良い解決策はありますか、それともここで何か完全に間違っていますか?

更新:例外がキャッチされた場合にストーム ストアを再作成し、Andrey が推奨するように操作を再試行することで、切断エラーを適切に処理する web.py プロセッサを追加しました。ただし、これは不完全で次善の解決策です。(a) ストアは再利用のために少数のオブジェクトによって参照され、これらのオブジェクトのそれぞれでストア参照を再配線する追加のメカニズムが必要であり、(b)、データベースで書き込みを実行するときのトランザクション処理 (ロールバック) は対象外です。ただし、少なくとも現時点では、ストアでのすべての読み取り操作に対して許容できる修正です。

4

1 に答える 1

1

おそらく、web.py のアプリケーション プロセッサを使用してコントローラー メソッドをラップし、それらから DisconnectionError をキャッチすることができます。このようなもの:

def my_processor(handler): 
    tries = 3
    while True:
        try:
            return handler() 
        except DisconnectionError:
            tries -= 1
            if tries == 0:
                raise

または、web.py で SqlAlchemy を使用するためにアプリケーション プロセッサを使用する方法のクックブック エントリを確認することもできます: http://webpy.org/cookbook/sqlalchemy

def load_storm(handler):
    web.ctx.store = Store(database)
    try:
        return handler()
    except web.HTTPError:
       web.ctx.store.commit()
       raise
    except:
        web.ctx.store.rollback()
        raise
    finally:
        web.ctx.store.commit()

app.add_processor(load_storm)
于 2012-07-31T11:11:53.870 に答える