大きな MP3 ファイルの固定在庫の小さな任意のセグメントを提供する Web サービスがあります。MP3 ファイルは、Python アプリケーションによってオンザフライで生成されます。モデルは、必要なセグメントを指定して URL に GET 要求を行い、audio/mpeg
応答でストリームを取得することです。これは高価なプロセスです。
フロントエンドのリクエスト ハンドラとして Nginx を使用しています。Nginx は、一般的なリクエストに対するレスポンスのキャッシュを処理します。
最初に、バックエンドで Tornado を使用して Nginx からのリクエストを処理しようとしました。ご想像のとおり、MP3 操作のブロックにより、Tornado は本来の機能 (非同期 I/O) を実行できませんでした。そのため、マルチスレッド化を行った結果、ブロックの問題が解決され、非常に優れたパフォーマンスを発揮しました。ただし、まだ診断や再現ができていない微妙な競合状態 (実際の負荷の下) が発生しました。競合状態により、MP3 出力が破損します。
そこで、アプリケーションを単純な WSGI ハンドラとして Apache/mod_wsgi の背後に設定することにしました (まだ Nginx を前に置いています)。これにより、ブロッキングの問題と競合状態が解消されますが、実際の条件下ではサーバー上にカスケード負荷 (つまり、Apache が作成するプロセスが多すぎる) が発生します。現在、Apache/mod_wsgi の調整に取り組んでいますが、まだ試行錯誤の段階です。(更新: Tornado に戻しました。以下を参照してください。)
最後に、質問があります。何か足りないものはありますか? HTTP 経由で CPU コストの高いリソースを提供するより良い方法はありますか?
更新: Graham の情報に基づいた記事のおかげで、これは Apache のチューニングの問題であると確信しています。その間、Tornado の使用に戻り、データ破損の問題を解決しようとしています。
すぐに問題に対処した人にとっては、Tornado と少しのマルチスレッド (スレッドによって導入されたデータの整合性の問題にもかかわらず) は、小さな (シングル コア) Amazon EC2 インスタンスで許容できる負荷を処理します。