web-dev-qa-db-ja.com

応答時間が長いリクエストのパターンは?

現在、独自のpython "web server"を維持しています。一部のリクエストに対する応答の生成には、主に重い計算のために非常に長い時間がかかる可能性があります。これらのリクエストは、基本的に非常に長いタイムアウト(投稿分から数十分)。

このアーキテクチャの1つの問題は、そのようなリクエストをキャンセルする必要がある場合があることです。ユーザーはリクエストの設定中に間違いに気付きました。現在、キャンセルは別のリクエストで、長時間実行されているリクエストをキャンセルしますが、ギャップがたくさんあります。 g。クライアントが単にウェブサイトを閉じるとどうなりますか?

現在、私たちは自社開発のWebサーバーの廃止を廃止し、賢明なものに切り替えることを計画しています-e。 g。 Flask内部で実行中IIS wfastcgiを使用しています。政治上の理由により、IISが設定されているため、グニコーンは窓の外です。

(w)fastcgiによって実行されるプロセスを強制終了する方法は誰にもわからないため、すべての開発はそれで行き詰まっています。その懸念は単にfastcgi仕様の一部ではありません。

私の感想は、それを組み込んだものを構築する試みは間違いだということです。サーバーがそのような計算集中型のタスクをバックグラウンドサーバー(フラスコ+セロリ?)にオフロードし、そのためのフロントエンドポーリングをオフロードするソリューションを好みます。

残念ながら、古いソリューションは非常に長い間使用されていたため、一部の開発者はすべてのコストで動作を維持したいと考えていました。

Webサーバーの男ではないので、そのような問題の賢明な解決策がどのようなものになるかについて、いくつかのヒントやパターンを教えてください。

7
Christian Sauer

あなたが示唆していることはまったく正しい。

非同期でなければなりません。

リクエストを投稿すると、リクエストに一意のIDが付与されます。ポーリングできるいくつかのストアで、この一意のIDの完了を投稿します。

リクエストをキャンセルする必要がある場合は、同じIDを使用したキャンセルリクエストを投稿する必要があります。

また、この計算が実行されているバックエンド(スレッド(Javaスタイル)の実行インターフェースなど)では、キャンセル投稿が要求されているかどうかを確認することで、プロセスがキャンセルされたかどうかを数秒ごとに確認できます。存在する場合、スレッドは終了する必要があります。これはきれいな出口です。スレッドへの割り込みを使用することもできます。

8
Learner_101

wsgi を調べて multithreading を使用することをお勧めします。スレッド内の各要求を管理し、スレッドにタイムアウトを実装できます。また、スレッドを管理し、リクエストをより簡単にキャンセルできる必要があります。

2
Tereus Scott

単純なHTTPポストで現在直面している問題は、そのプロトコルでは解決できません。 HTTPは厳密なクライアント/サーバーで非同期に機能するため、サーバー側の通知やネイティブキャンセルはありません。また、インターネットネットワークのタイムアウトのために回答が失われるという問題にも直面します。私は別の現代的なアプローチを提案します。免責事項: ブラウザのサポートが90%未満

情報の流れを逆にしてWebSocketを使用することをお勧めします。タスクが完了したら、ユーザーに通知し、サーバーからクライアントにPush通知を送信する必要があります。

タスクが投稿されたら、またはより正確には投稿の代わりとして、WebSocketを開きます(好きなサーバーテクノロジー、トルネード、Gevent、Python WebSocketなどを使用します)。サーバーwebsocketオープンイベントにタスクスレッドを関連付けます。クライアントが終了すると、クライアントはcloseイベントをwebsocketハンドラーに送信するため、それに関連付けられているスレッドを終了できます。それ以外の場合、タスクが正常に終了すると、サーバーはデータをクライアントに送信してWebSocketを閉じることができます。また、WebSocketが1分以上アクティブでない場合は閉じられるため、30秒ごとにサーバーにpingを実行する必要があります。

これを適用すると、実際の双方向チャネルがあるため、ギャップの問題を解決しながら、クライアント側のポーリングよりも高速でクリーンになります。セッション、進行状況のpingなど、タスクスキーマに追加のサービスを実装できることに注意してください。

1
Arthur Havlicek

タスクの実行にそれだけ多くの時間が必要な場合は、その要求に対してそれを行わないでください。それをキューに入れ、作業を行う別のプロセスを作成します。

作業が完了したら、「操作x」が完了したことをユーザーに通知します。その間、「作業は約x分で完了します」というメッセージが表示されます。

0
Djuro