Пул акцептора и балансировка нагрузки в Erlang?
С http://www.erlang.org/doc/man/gen_tcp.html:
Стоит отметить, что вызов accept не должен выполняться из процесса владельца сокета. При использовании эмулятора версии 5.5.3 и выше можно одновременно отправлять несколько запросов на прием от разных процессов, что позволяет создавать пул процессов-акцепторов, обрабатывающих входящие соединения.
(Q1) Значит ли это, что в Erlang мы можем использовать балансировку нагрузки в стиле Unicorn?
(Q2) Если так, существуют ли какие-либо серверы или библиотеки, использующие эту функцию?
(Q3) Unicorn работает в предположении, что обработка запросов выполняется быстро. При том же предположении, возможно ли получить лучшую производительность путем объединения акцепторов и рабочих в Erlang?
Для тех, кто не знаком с Unicorn, это традиционный веб-сервер prefork для UNIX. Балансировка нагрузки между рабочими процессами осуществляется ядром ОС. Все работники имеют общий набор слушающих сокетов и неблокирующим принимают на них accept(). Ядро решит, какому рабочему процессу отдать сокет, и рабочие будут спать, если нечего принимать (). Я полагаю, что для одного сокета-слушателя происходит то же самое, когда рабочие процессы блокируют accept() и ядро ОС решает результат "гонки".
1 ответ
Я также разместил этот вопрос в списке рассылки Erlang Questions. Как отметил Даниэль Гертцен, в Эрланге есть библиотеки пулов акцепторов, такие как ранчо и рой.
ranch работает не так, как Unicorn, таким образом, что он "принимает" только во многих процессах, а затем передает сокет какому-то рабочему процессу.
Рой работает так же, как и Единорог, в том смысле, что акцептор и работник объединены. (Спасибо Loïc Hoguin за указание) Но они немного отличаются, потому что Swarm может принимать новый сокет параллельно с обработкой принятого сокета, тогда как Unicorn принимает только после обработки принятого сокета.
Я предпочитаю стиль роя, поскольку он идеально подходит как для быстрых, так и для медленных запросов, тогда как Unicorn требует быстрых запросов.
Вместо того, чтобы пытаться эффективно обслуживать медленных клиентов, Unicorn использует буферизованный обратный прокси-сервер для эффективной работы с медленными клиентами.
Единорог подходит не для всех приложений. Unicorn оптимизирован для приложений, которые интенсивно используют процессор / память / диск и тратят мало времени на ожидание внешних ресурсов (например, сервера базы данных или внешнего API).
Unicorn крайне неэффективен для приложений Comet/reverse-HTTP/push, где HTTP-соединение тратит много времени простоя.