4

その一部が大きなファイルを解析しているpython djangoアプリを持っています。これには永遠に時間がかかるため、ユーザーがサイトを閲覧し続けることができるように、処理を処理するためにフォークを配置しました。fork コード内には、Amazon でホストされている postgres データベースへの呼び出しが多数あります。

次のエラーが表示されます。

SSL error: decryption failed or bad record mac

コードは次のとおりです。

pid = os.fork()
if pid == 0:
    lengthy_code_here(long)
    database_queries(my_database)
    os._exit(0)

フォークを挿入する前は正常に機能していましたが、データベース呼び出しはどれも機能していません。少し調べてみると、データベース接続が古くなっている可能性があるようですが、修正方法がわかりません。誰にもアイデアはありますか?

4

2 に答える 2

7

ソケットを開いたまま(データベース接続など)にフォークすることは、両方のプロセスが同じソケットを同時に使用しようとするため、一般的に安全ではありません。

少なくとも、フォーク後にデータベース接続を閉じて再度開く必要があります。

ただし、理想的には、これはおそらくCeleryのようなタスクキューイングシステムに適しています。

于 2012-06-13T19:04:15.663 に答える
2

本番環境の Django には通常、django/python を収容する一連のプロセスにディスパッチするプロセスがあります。これらのプロセスは長時間実行されます。1 つの要求を処理した後は終了しません。むしろ、彼らはリクエストを処理し、次に別のリクエストを処理し、次に別のリクエストを処理します。これは、リクエストのサービスの最後に復元/クリーンアップされていない変更が将来のリクエストに影響することを意味します。

プロセスを fork すると、開いているすべての記述子 (ファイル、キュー、ディレクトリ) を含むさまざまなものを子プロセスが親プロセスから継承します。記述子で何もしない場合でも、プロセスが終了すると、開いているすべての記述子がクリーンアップされるため、問題は残ります。

したがって、長時間実行されているプロセスから fork すると、子プロセスが処理を終了した後に終了したときに、開いているすべての記述子 (ssl 接続など) を閉じるように設定されます。フォークでこれが起こらないようにする方法はありますが、正しく行うのが難しい場合があります。

より良い設計は、フォークせずに、実行中またはより安全な方法で開始された別のプロセスに引き渡すことです。例えば:

  • at(1) を使用して、後で (またはすぐに) 実行するためにジョブをキューに入れることができます
  • メッセージキューを使用して、メッセージを他のデーモンに渡すことができます
  • パイプなどの標準 IPC 構造を使用して、他のデーモンと通信できます。

アップデート:

at(1) を使用する場合は、スタンドアロン スクリプトを作成する必要があります。シリアライザーを使用して、django からスクリプトにデータを渡すことができます。

于 2012-06-13T19:26:22.150 に答える