В чём преимущество асинхронных серверов перед PHP/nginx?
==========================================================

Здравствуйте.  

Такой вопрос: в чем основное преимущество асинхронных серверов (Node.js, Python Tornado), фреймворков (Python Twisted) и т. д. перед связкой асинхронный сервер + любой язык программирования (или, как написано в заголовке, PHP). То есть мы получаем, что nginx собирает запросы от пользователей, а PHP обробляет их по очереди. В асинхронном сервере в единый момент времени обрабатывается столько запросов, сколько есть воркеров и в PHP/nginx точно также.

 

Если коротко, то ошибка закралась вот тут:  
*В асинхронном сервере в единый момент времени обрабатывается столько запросов, сколько есть воркеров*  
  

Представьте себе, что у вас на сервер приходит запрос, связанный с выборкой данных из БД.  

Он отрабатывает, предположим, за 150 мс, из которых 130 это работа с базой данных.  
  

В случае с PHP у вас воркер будет заблокирован эти 150 мс для обработки других запросов.  

В случае с асинхронным сервером, он, пока запрос 1 ждет данные от БД в течение 130 мс, сможет принять и начать обрабатывать другие запросы. Предположим, что у нас один PHP-воркер. В этом случае таких запросов, как из примера, он сможет обработать семь штук за секунду.   
  

Асинхронному же, допустим, прилетят 20 запросов. Он обработает каждый до взаимодействия с БД, допустим за 10 мс, полетят 20 запросов к БД, пройдут, допустим, за 500 мс, и сервер сформирует ответ. И это все практически параллельно. Итого меньше чем за секунду мы таким образом обработаем 20 запросов.   
  

Можно, конечно, увеличить пул FastCGI, но оверхед при обработке запроса каждым воркером будет несоизмеримо выше, чем при обработке асинхронным сервером.

 

Вот это почитайте - <http://habrahabr.ru/post/128772/>  

Если вкратце - то асинхронная модель не лучше и не хуже. У неё своя область применения. Например, запускать тяжелую математику внутри NodeJS-сервера - смерть всему и всем. А вот тяжелые запросы в БД из PHP вполне себе бодренько будут бегать по серверу (ну насколько для них это возможно).   

Или хороший пример - из nginx-ового перла запросы в mysql-базу делать (да-да, он и такое может). Тогда он тоже начинает крайне отвратно работать)   
  

То есть асинхронная модель (по крайней мере, в районе web-серверов/приложений) хороша только тогда, когда все запросы у вас быстро отрабатывают. Как то так.  
  

(ну и как обычно - комментарии не менее ценны, чем статья).

 

Достаточно одного узкого места, чтобы поставить колом всю систему.  

Частично асинхронная система лучше, чем система вообще без асинхронности.  

Но хуже, чем полностью асинхронная.  
  

Создание и поддержка множества процессов и потоков для синхронной обработки - операция недешевая, даже если они в находятся в состоянии ожидания. На практике это выглядит как бешеный рост LoadAverage.  
  

Асинхронность позволяет держать фиксированное количество рабочих процессов (в идеале, по одному процессу на каждое процессорное ядро). Процессы создавать не надо, переключать почти не надо - в биткойне у меня такая схема обрабатывала тысячи одновременных коннектов с загрузкой cpu менее 1%.

 

Все сервера предназначенные для больших нагрузок являются асинхронными. То есть обработка новых входящих соединений происходит раньше, чем закончат работу текущие соединения.  

Преимущество готовых асинхронных серверов в том, что они готовы. Вы можете точно так же написать асинхронный сервер на php (socket + select), но это не настолько эффективно как в python и тем более в node.js, где этот функционал идет из коробки.  
  

Стандартный кейс применения node.js/Python twisted и любых других реализаций - обработка либо сырых tcp-соединений (например push уведомления) или же keep-alive для тех же целей. При обработке же коротких http запросов профит уже не так велик. Во всяком случае между php и python. node.js будет пошустрее, но и памяти он будет кушать чуточку больше.

 

Такой вопрос: в чем основное преимущество асинхронных серверов ... перед связкой асинхронный сервер + любой язык   

---  

перед связкой асинхронный сервер + любой язык - не совсем понятно, что Вы имеете в виду. Асинхронный сервер или нет, это одно, а вот асинхронный или нет доступ к данным у ЯП - это совсем другое. Я уверен, что Вас больше интересует второе.  
  

Вся прелесть, сложность и проблемы в асинхронном подходе возникают по одной и той-же причине. Результат на запрос приходит не сразу, а асинхронно. Это даёт огромное уменьшение времени отклика программы, если в ней используется результат нескольких не зависимых IO операций. Во всех остальных случаях синхронный подход проще, при таком-же времени доставки ответа. (IO - это работа с файлами, внешними api итп )  
  

Nodejs имеет один существенный недостаток - у неё один процесс выполнения. По этому тяжелые вычисления на ней значительно уступают в производительности PHP на многопроцессорных/ядерных системах. (это дело легко обходится воркерами итп, но это еще один недостаток)  

erlang, java и несколько других языков не имеют вышеуказанной проблемы.  
  

Nodejs по сравнению с PHP имеет еще 2 важных плюса:  

1. в ноде можно хранить данные, таймеры, дескрипторы итп между запросами. По этому это намного эффективнее различных механизмов кэширования PHP.  

2. в ноде не тратится время на подгрузку кода.  
  

>>В асинхронном сервере в единый момент времени обрабатывается столько запросов, сколько есть воркеров и в PHP/nginx точно также.  

Не верно, ни в первом ни во втором случае. В асинхронном сервере есть всего один поток, который обрабатывает любое количество запросов, в nginx - точно так-же. О PHP - другая история, но на каждый запрос нужен как минимум thread или process.