Ответ 1
Подъемный подход к масштабируемости находится в пределах одной машины. Масштабирование по машинам - это более сложная тема. Короткий ответ: Scala и Lift не делают ничего, чтобы помочь или затруднить горизонтальное масштабирование.
Что касается участников внутри одной машины, то Lift достигает лучшей масштабируемости, поскольку один экземпляр может обрабатывать более параллельные запросы, чем большинство других серверов. Чтобы объяснить, я сначала должен указать на недостатки в классической модели обработки запросов на запрос. Потерпите меня, это потребует некоторого объяснения.
Типичная структура использует поток для обслуживания запроса страницы. Когда клиент подключается, инфраструктура назначает поток из пула. Затем этот поток выполняет три функции: он считывает запрос из сокета; он выполняет некоторые вычисления (потенциально связанные с I/O в базе данных); и он отправляет ответ на сокет. Почти на каждом шаге поток в конечном итоге будет блокироваться. При чтении запроса он может блокироваться в ожидании сети. При выполнении вычислений он может блокировать диск или сетевой ввод-вывод. Он также может блокироваться в ожидании базы данных. Наконец, при отправке ответа он может блокировать, если клиент медленно принимает данные, а окна TCP заполняются. В целом, поток может потратить 30 - 90% времени блокировки. Тем не менее, он тратит 100% своего времени на этот запрос.
JVM может поддерживать только столько потоков, прежде чем он действительно замедлит работу. Планирование потоков, конкуренция для объектов с общей памятью (например, пулов соединений и мониторов) и ограничений на собственную ОС ограничивают все ограничения на количество потоков, которые может создавать JVM.
Хорошо, если JVM ограничена в своем максимальном количестве потоков, а количество потоков определяет, сколько параллельных запросов сервер может обрабатывать, то количество одновременных запросов будет определяться количеством потоков.
(Есть и другие проблемы, которые могут налагать более низкие ограничения - например, GC-хребет. Нитки - фундаментальный ограничивающий фактор, но не единственный!)
Подъем отделяет поток от запросов. В лифте запрос не связывает нить. Скорее, поток выполняет действие (например, чтение запроса), а затем отправляет сообщение актеру. Актеры - важная часть истории, потому что они запланированы через "легкие" потоки. Пул потоков используется для обработки сообщений внутри участников. Важно избегать блокировки операций внутри участников, поэтому эти потоки быстро возвращаются в пул. (Обратите внимание, что этот пул не отображается в приложении, он является частью поддержки Scala для участников). Например, запрос, который в настоящее время заблокирован на базе данных или на дисковый ввод-вывод, не поддерживает обработку потока запросов, Поток обработки запросов доступен почти сразу, чтобы получать больше соединений.
Этот метод для развязывания запросов из потоков позволяет серверу Lift иметь гораздо больше параллельных запросов, чем сервер потока за запрос. (Я также хотел бы отметить, что библиотека Grizzly поддерживает аналогичный подход без участников.) Дополнительные параллельные запросы означают, что один сервер Lift может поддерживать больше пользователей, чем обычный Java EE-сервер.