Pull to refresh

Comments 32

проверим вечерком, чего же там такого получилось :) давно еще заглядывал проект был сыроват, да и я про ноду только из далека слышал, сейчас и опыта чуток появилось и желание с http поработать.
Тимур, может ли приложение на Impress быть развернуто в облачном окружении? Например в Windows Azure, как описано тут?
Только в случае, если зада стоит не «развернуть Impress везде», а «развернуть все на Azure» ) Это будет последнее, что я захочу протестировать, там множество вещей, которые не понятно будут ли работать, например, как могут быть пересобраны бинарные библиотеки для BSON и ZeroMQ, как будет работать IPC и слежение за файловой системой, есть большие сомнения. Для Азура оптимально писать на .NET, а для Impress оптимально использовать физические машины.
Это все пошло от шедевра импрессионизма, одной из вариаций картины Клода Моне «Дама с зонтиком», но т.к. у нас сервер приложений тоталитарный, то решено было заменить невнятную даму, внушительным изображением Энакина Скайуокер в преклонных годах, а с ним юный падаван, изучающий Node.js с темной стороны. Вообще, импрессионизм, как художественное направление, полностью соответствует тому «Аахх...», который вызывает нода у новообращенных. Не только Моне уловил это, иллюстрацию из Дега я уже постал однажды.
я правильно понял, что у вас два способа взаимодействия — ZeroMQ и IPC?
Между серверами ZeroMQ, а между master-ом и worker-ами в рамках одного сервера используется IPC.
надеюсь, IPC через ZeroMQ то? в этом был вопрос
IPC через child_process, ZeroMQ внутри сервера ни чем не ускоряет работу, только дополнительные вызовы. Кроме того, благодаря этому, на одном сервере Impress может работать без ZeroMQ.
что мешало тогда уже и межмашинную коммуникацию сделать через сокеты? Раз используете мощь ZMQ так зачем пренебрегать ее возможностями и поддерживать два апи
Между машинами ZMQ работает быстрее, а в пределах одного сервера IPC через child_process быстрре. Разница в использовании API — 10 строк кода, мы не за красоту концепций боремся, а за скорость.
ясно, ясно :) То есть, даже ZMQ не используется на полную, а просто замена BSD-сокеты. Ок.
Используется два паттерна pub/bub (однонаправленный широковещательный, для трансляции событий в воркеры) и req/rep (вдунаправленный, для отправки событий в контроллер кластера). А на полную это как, просветите может?
Ну вот я, собственно, не очень понимаю, как можно хоть бы эти два паттерна заменить на 10 строк своего кода и IPC.

кстати, какая версия zmq?

на полную — это значит использовать (если конечно надо, но мне моя практика буквально сегодняшняя, подсказывает, что зачастую облегчает очень) и другие паттерны (а их там много). Хотя, возможно это так с моей колокольни, применительно в этому проекту, может ничего остального не надо конечно
Задача такая, транслировать глобальные события на все инстансы Impress, чтобы на них можно было подписываться в любом инстансе и отправлять в любом инстансе. Одной пары паттернов для этого не достаточно, потому, что pub/sub подходит для распространения событий через подписку, но он однонаправленный и нужно держать открытым еще один сокет для отправки события из воркера в «контроллер облака». IPC же в рамках одного сервера все равно открыт и он сразу двунаправленный, т.е. кода с использованием ZMQ больше, чем с IPC. Но для взаимодействия в рамках одного сервера ZMQ просто оборачивает IPC, и только замедляет процесс. Поэтому IPC используется там, где он быстрее, а ZMQ там, где он быстрее. Версия ZMQ 3.2.2. Другие паттерны в данном случае не нужны, паттернов в «The Guide» описано много, а вот базовых типов сокетов очень мало (req, rep, xreq, xrep, pub, sub, push, pull, pair) и гораздо проще оперировать именно ими, собирая конкретные паттерны уже под задачу.
кстати, а есть паблик тесты на счет сильного замедления? очень интересно (я сознательно отбрасываю крайние случаи оптимизаций, где борьба идет за десятки наносекунд, а вот чтобы быть быстрее в сервере общего назначения — это должны быть десятки и десятки %).
Не совсем понял, тесты чего и сильного земедления чего? Мы разные варианты тестировали от случая к случаю, не для получения красивой статистики, а для принятия решений, и оформлять это в приличный вид не стали.
Вы утверждаете, что IPC через ZMQ существенно медленнее, чем через child_process. Вот мне и интересно, насколько. И интересно, реально ли увидеть эту разницу (не по факту что вот профайлер столько-то наносекунд показывает). Так как раз проектируем большую и ответственную систему с похожей архитектурой.
А, ну такой тест не сложно сделать, я думал сравнение разных паттернов для трансляции событий. Будет время — сделаем, чтобы не возникало сомнений. ZMQ вместо IPC может быть полезен только в плане унификации кода, у нас тоже были сторонники такого подхода, которые уже всю голову продолбили.
вы считаете, что унификация плохо? ;) да, она может стоить чего-то, и тут вопрос насколько сильно она дорога. потому и спросил про тесты скорости
Ну я еще причисляю к преимуществам, что в Impress есть режим, когда на одном сервере кластеризация происходит без ZMQ, а доставка событий в браузеры без WebSocket, на своей реализации SSE, чтобы можно было не тянуть много тяжелых и сложных в сборке зависимостей. Сейчас минимальный размер зависимостей 10Мб, а максимальный 74Мб. Библиотека ZMQ для Node.js требует установки Python, node-gyp, GCC, а для винды еще и Visual Studio, это не каждый выдержит. А так, конечно проще вынести это в настройки и тестировать будет удобнее.
Impress использует каждый инстанс nodejs для всех приложений? У v8 производительность резко падала раньше при размерах хипа > ~1.5гб. С этим проблем не будет у impress?
Это конфигурируемо, если в /config/cluster.js:strategy == «specialization», то для каждого приложения создается отдельный процесс, но эффективнее создавать сэндбоксы виртуальной машины внутри одного процесса, иначе, при большом количестве приложений будет уходить много процессорного времени. Каждый сендбокс полностью экранирован в плане выделения памяти (они имеют разный global), позволяет ли это уйти от ограничения на размер хипа — не знаю, пока не тестировали этого, хотя, нужно бы. В любом случае, есть экономия памяти в случае нескольких приложений в одном процессе, все подгруженные библиотеки лежат в памяти один раз для всех приложений, это не смотря на разделение памяти, т.е. если библиотека что-то поместит в глобальный контекст, то оно будет один раз лежать (например, кеш больших таблиц geoip), а вот если библиотека при вызове из сэндбокса приложения сделает замыкания, то они уже попадут в сэндбокс. То есть, от количества приложений память будет зависеть только если эти приложения будут ее активно тратить, размещать в ней свои структуры данных, кеш, состояние. Кроме того, в режиме «sticky», пользователи прилипают к своим процессам и дальше уже все их запросы идут только через один процесс, поэтому, состояние, относящееся к пользователю будет лежать только внутри его родного процесса. В общем, вопрос этот правильной, важный, чтобы его раскрыть, я могу отдельную статью на 10 страниц написать, но он еще требует глубокого изучения и дополнительных тестов.
Эм, я прямо впечатался презентацией, в первую очередь простотой конфигурации и масштабируемостью. Я как раз занялся вопросом поиска удобного менеджера приложений для node который бы подходил под эти требования:
1. Приложения автоматически стартовали при рестарте сервера.
2. Приложения автоматически стартовали после падения
3. Была возможность перегрузить приложение вручную.
4. Разные вкусности, типа отдельных логов на приложение и т.п.
5. Просто добавлять новые приложения.
И с первого взгляда Impress, это то что мне нужно, но меня смущает подход к модулям нетипичный для node.js. Смогу ли я удобно использовать пакеты из npm через require()? работает ли подход когда для каждого приложения создается свой package.json со своими зависимостями? Или мне стоит ограничится например supervisor для этой сферы использования?
Impress написан не для приложений Express/Connect и вообще не для приложений, созданных в стиле цепочек мидлвеаров. Приложения для Impress запускаются только в среде запуска Impress. Что касается require и внешних модулей, то сколько душе угодно. Модули Вы можете устанавливать через npm install из корня сервера приложений, чтобы они попадали в общий «node_modules», а потом в /applications/yourappname/config можете сделать файл yourModuleConfig.js в котором require и инициализация нужного модуля. Далее, во всех обработчиках этот модуль будет доступен. Например так можно написать файл инициализации и конфигурации модуля:
// file: /applications/example/config/passport.js
var p = require('passport'),
	pGoogle = require('passport-google-oauth');
	p.serializeUser(function(user, done) { done(null, user); });
	p.deserializeUser(function(user, done) { done(null, user); });
	module.exports = {
		lib: p,
		strategies: {
		    google: {
		        param: {
	    	        clientID: 'ID-HERE',
		            clientSecret: 'SECTET-HERE',
		            callbackURL: '/api/auth/google/callback'
		        },
		        strategy: pGoogle.OAuth2Strategy,
		        authenticate: function(req, token, refreshToken, profile, done) {...},
				successRedirect: '/', failureRedirect: '/'
			}
		}
	};
}

Все файлы из /config загружаются автоматически, сначала те, о которых система знает, а потом и все остальные.
Обработчки, использующие модули, например, паспорт, будут выглядеть так:
// file: /applications/example/app/api/auth/google/signIn/get.js
module.exports = function(client, callback) {
	client.passport.init(function () {
		client.passport.strategies.google.authenticate(client.req, client.res, callback);
	}, callback);
};
// file: /applications/example/app/api/auth/google/callback/get.js
module.exports = function(client, callback) {
	client.passport.init(function () {
		client.passport.strategies.google.authenticateCallback(client.req, client.res, callback);
	}, callback);
};

В данном случае, кстати, показано, как обернуть модуль паспорт, написанный для Express/Connect так, чтобы он думал, что все ок и он запускается в среде мидлверов в Express.
Пока механизм поддержки экспресовых модулей не универсальный, но во-первых, не вся нода это экспрес, а во-вторых, мы работаем над улучшением эмуляции экспреса и коннекта, насколько это позволит сделать архитектура. Ведь архитектура импреса — это отказ от цепочек вызовов мидлваров, что и есть одним из его преимуществ по скорости.
А то что impress требует права root для запуска сервера даже при установке через npm install impress в домашний каталог это нормально или у меня что-то пошло не так? Если да, то объясните пожалуйста с чем это связано и как лучше разворачивать impress на этапе отладки приложения. Песочница?
Права рута нужны только если в /config/servers.js есть хоть один port меньше 1024. Там после установки идет 80 порт. Можете установить через npm install impress, потом зайти и поправить конфиг.
Спасибо, сменил порт на 8080, полегчало)
А существует ли более последовательная и подробная документация чем в nmpjs.org? А то, несмотря на все статьи и пример, непонятно с какой стороны подступиться.
Sign up to leave a comment.

Articles