У нас есть веб-сервис, который обслуживает небольшие произвольные сегменты фиксированного инвентаря больших файлов MP3. Файлы MP3 генерируются на лету приложением python. Модель состоит в том, чтобы выполнить запрос GET к URL-адресу, указывающему, какие сегменты вы хотите, получить в ответ поток audio/mpeg
. Это дорогой процесс.
Мы используем Nginx в качестве обработчика запросов переднего плана. Nginx заботится о кэшировании ответов на общие запросы.
Изначально мы пытались использовать Tornado на сервере для обработки запросов от Nginx. Как и следовало ожидать, блокирующая операция MP3 удерживала Tornado от своей работы (асинхронный ввод-вывод). Итак, мы пошли в многопоточном режиме, что решило проблему блокировки и показало хорошие результаты. Тем не менее, он ввел тонкое состояние гонки (под нагрузкой реального мира), которое мы еще не смогли диагностировать или воспроизвести. Состояние гонки искажает наш вывод MP3.
Итак, мы решили настроить наше приложение как простой обработчик WSGI за Apache / mod_wsgi (все еще с Nginx впереди). Это устраняет проблему блокировки и состояние гонки, но создает каскадную нагрузку (т. Е. Apache создает слишком много процессов) на сервере в реальных условиях. Мы работаем над настройкой Apache / mod_wsgi прямо сейчас, но все еще на стадии проб и ошибок. (Обновление: мы вернулись к Торнадо. См. Ниже.)
Наконец, вопрос: мы что-то упускаем? Есть ли лучший способ обслуживать дорогостоящие ресурсы ЦП через HTTP?
Обновление: Благодаря информированной статье Грэма, я почти уверен, что это проблема настройки Apache. Тем временем мы вернулись к использованию Tornado и пытаемся решить проблему повреждения данных.
Для тех, кто так быстро бросил железо в эту проблему, Tornado и немного многопоточности (несмотря на проблему целостности данных, вызванную многопоточностью) приемлемо справляются с нагрузкой на небольшом (одноядерном) экземпляре Amazon EC2.