私たちは、骨なしで実装されたAPIを持っています。Scala Akka HTTP - 重い計算(CPUとメモリを大量に消費する)に直面する2つのルート。クラスタ化はありません。すべてが1台の堅いマシンで実行されています。計算は重く、1つの独立した要求に対して60秒以上かかることがあります。そして、それほどスピードはあまり気にしません。ブロックIOはなく、多くのCPU処理があります。Akka HTTPと長時間実行されるリクエスト
パフォーマンステストを開始したとき、興味深いパターンが示されました:リクエストA1、A2、...、A10が来ると言う。彼らはリソースをかなり大量に使用しています.AkkaはoverranされたリクエストA5〜A10に対してHTTP 503を返します。問題は、結果を取り上げる人がいなくても計算がまだ実行されていることです。
そしてそこから、要求A11-A20が依頼依頼A5-A10に依然として対応しているサーバに到着します。明らかに、これらの新しい要求はまた、サーバがより混雑していることを考えると、それを上回る可能性があります。そのため、Akkaがタイムアウトを引き起こしてサーバーをより混雑させ、遅くしてから、新しいバッチのリクエストが届くようになるまでに、いくつかのサーバーが実行されます。システムを少し実行した後、特定のタイムアウトで失敗したポイントを開始します。また、負荷を停止すると、依然としてログに記録されているリクエストが表示されます。
私は計算を別のExecutionContextとシステムディスパッチャーで実行してみましたが、完全な非同期(未来のコンポジションを使用)にしようとしましたが、結果は変わりません。残念な仕事はサーバーを非常に忙しくして、最終的にはほとんどすべての要求が失敗します。
同様のケースはhttps://github.com/zcox/spray-blocking-testに記載されていますが、焦点はそこにシフトされています。/ping
は、長時間実行される要求を処理するエンドポイントで多かれ少なかれ安定した責任があります。
質問:ハングしたリクエストを中断するのに適したアプリケーションを設計するにはどうすればよいですか?重い負荷のもとでは失敗した要求の一部を許容できますが、数秒後にシステム全体を停止させることは受け入れられません。
かなり幅広い質問。要するに、重い負荷の直後にいくつかのリクエストを拒否する必要があります(あまりにも多くの計算を実行したり、キューを維持しているユーザーをごめんなさいと言いましょう)。また、計算、データベース、スプレーなどのために別々のコンテキストを使用する必要があります。そのため、httpフロントエンド層は常に応答します。 – ipoteka