2015-10-08 3 views
3

У нас есть приложение, которое использует рендеринг на стороне сервера для SEO с использованием шаблонов EJS.Сервер Node.js Express: работает res.render()/ejs.render(), используя Node.js threadpool

Я хорошо разбираюсь в Node.js и знаю, что, возможно, вы можете подключиться к потоку Node.js для асинхронного ввода-вывода для любой цели, будь то хорошая идея или плохая идея. В настоящее время мне интересно, можно ли запустить ejs.render() или res.render() с потоком в threadpool вместо основного потока в Node.js?

Мы делаем много тяжелого вычислительного подъема в функциях рендеринга, и мы определенно хотим этого от основного потока, иначе мы будем платить $$$ за большее количество серверов.

+0

Мы * могли * использовать отдельный процесс Node.js для запуска рендеринга или даже webworker-thread (https://www.npmjs.com/package/webworker-threads), но я специально задаюсь вопросом, есть ли способ использовать существующий threadpool в V8 –

ответ

1

Это только то, что касается вас? Существуют и другие двигатели шаблонов, которые должны давать лучшие результаты; что рендеринг шаблона должен быть идемпотентной операцией, вы можете дополнительно распределить по кластеру.

V8 скомпилирует ваш код на сборку и, если вы не нанесете каких-либо деоптимизаций или не затормозитесь сборщиком мусора, я считаю, что вы должны находиться рядом с лимитами ввода-вывода в сети. Я бы определенно рекомендовал вам попробовать другие движки шаблонов, добавив кэш-обратный прокси-сервер с кешированием на передней панели и сначала запустив некоторые тесты.

+0

, к сожалению, на этом этапе мы не будем переписывать, используя другую библиотеку шаблонов, но да, это то, что касается меня, это очень много cpu –

+0

@AlexMills. Я все равно попытаюсь добавьте обратный прокси-сервер кэширования и запустите некоторые тесты, т. е. открыв все документы из 'robots.txt', одновременно и наугад и измеряя нагрузку. Единственное, на что можно обратить внимание, это найти собственный механизм шаблонов - я не знаю, насколько это будет повышать производительность, поскольку операции с строкой измеряются со скоростью порядка миллионов в секунду; это также заставило бы вас переписать код шаблона, поскольку EJS может содержать оценки для любого JS-кода, в то время как механизм шаблонов, реализованный в чем-то, отличном от Node.js, безусловно, не будет. –

1

EJS, как известно, является синхронным, и это не изменится, поэтому в основном это неэффективный механизм рендеринга для Node.js, поскольку он блокирует поток JS всякий раз, когда он отображает представление, что снижает общую пропускную способность, особенно если ваш рендеринг - тяжелый процессор.

Обязательно подумайте о некоторых других вариантах. Например. https://github.com/ericf/express-handlebars

Если у вас действительно есть компьютерное вычисление на вашем веб-сервере, то Node.js в любом случае определенно не подходит для работы. Есть гораздо лучшие серверы для обработки многопоточной и параллельной обработки. Вы можете просто настроить узел как контроллер и перенаправить ваши запросы на процессор к серверному сервису/серверу, который может выполнять тяжелую работу.

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

Выстукивать в токарно-пул (который обрабатывается libuv), вероятно, будет плохой идеей, но можно конечно .. просто нужно несколько ++ навыки C и uv_queue_work() метод libuv библиотеки планировать материал на рабочий поток.

+0

Какие асинхронные шаблонные двигатели вы знаете о node.js? –

+0

не будет сложно использовать отдельный процесс node.js для выполнения рендеринга, но я предполагаю, что этот вопрос первоначально пытался найти информацию о том, как получить доступ к thread.js threadpool изнутри основного потока, если это возможно , Правильно? Поскольку эти асинхронные шаблонные библиотеки, на которые вы ссылаетесь, должны делать это, если только они просто не используют потоки и не выполняют работу с основного потока. –

+0

@AlexMills Смотрите мои обновления. –

1

Я экспериментировал с созданием механизма сценариев, который запускается в разветвленном процессе (прочитайте модуль дочернего процесса узла here). Я считаю, что это привлекательное предложение для реализации механизмов рендеринга. Да, есть проблемы с передачей параметров (строки ввода/получения запроса, состояние сеанса и т. Д.), Но с ними легко справиться, особенно если вы используете опцию fork (в отличие от exec или spawn). Существуют стандартные методы обмена сообщениями между дочерним и родительским.

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

Если EJS-рендеринг блокирует поток основного узла, то это является достаточной причиной, чтобы НЕ использовать его, если вы выполняете значительные вычисления во время рендеринга.