Пользователь
0,4
рейтинг
9 июня 2010 в 11:29

Разработка → Установка node.js на Linux, FreeBSD, Windows

node.js — серверный асинхронный Javascript, превосходный инструмент для создания серверной части COMET приложений, в частности, для игрушек, чатов, и других высоконагруженных проектов, использующий синтаксис Javascript, прекомпилируемый в машинный код, работающий на скорости, сравнимой с кодом на C++, очень быстрый, способный держать 10 — 12 тысяч подключений, и не создающий отдельного процесса/не интерпретирующий себя заново/не запускающий процесс при каждом новом клиенте. Использует в качестве основы V8 — движок Javascript от Google. Удобные возможности, можно установить значение переменной при одном посетителе, и считать это значение при ответе другому.
Обращаю внимание на то, что если вы не программировали, например, на Python или Ruby, только на PHP, не обходите его стороной, это не ещё один незнакомый язык. И в этом его преимущество — Javascript — знакомый язык, особенно для тех, кто программировал на PHP+Javascript, но PHP не позволял очень многих вещей, особенно в связке с Apache, например, аплоад файлов с полосой загрузки (без Flash), возможность низкоуровневого управления сетью (возможность написать, например, клиента или сервер Mysql или прокси-сервер вроде nginx).
О гибкости языка говорит тот факт, что расширения для работы с MySQL, например, написаны на самом Javascript.
Я планировал написать статью с описанием этой замечательной системы, с примерами, но на момент чтения читателю хорошо бы иметь под рукой установленную версию node.js. Поэтому этот пост о том, как установить node.js, в том числе и на Windows, что актуально в связи с недавним появлением порта под cygwin. (Да, есть информация о том, где скачать node.exe)

Важное замечание.


В первую очередь хочу обратить внимание на то, что с развитием node.js его синтаксис менялся, порой несколько раз. В связи с этим, категорически не рекомендую использовать старые версии node, проскальзывающий недавно node.NET, и подобные сборки. Идеально — версия 0.1.90 или новее. По той же причине будьте внимательны при нахождениии в сети туториалов по установке. Те, что начинаются с wget http://s3.amazonaws… загрузят устаревшую версию.
Перед установкой убедитесь в том, что python установлен, он нужен для конфигурации и сборки с помощью make (актуально для всего, кроме Windows в некоторых случаях).

GNU/Linux


Под Linux node.js ставится проще всего.
Заходим на nodejs.org
Копируем ссылку на исходники
wget http://nodejs.org/dist/node-v0.1.97.tar.gz
tar -xvf node-v0.1.97.tar.gz
//либо делаем так
git clone git://github.com/ry/node.git (если git есть)
cd node*
./configure
make
make install

Хабрахабр советует в коментариях:
Programmer
Лучше было бы собрать как минимум при помощи checkinstall
checkinstall --fstrans=no --install=no --pkgname=node.js --pkgversion "0.1.97" --default

Логика подсказывает, что под MacOS установка будет аналогичной, проверить не могу. Разработчики тестируют своё детище на MacOS, работать должно без проблем.

FreeBSD


У меня VDS на FreeBSD, и поэтому для меня эта система наиболее актуальная. Вместе с тем, разработчики не тестируют node.js на FreeBSD, поэтому возможны некоторые проблемы.
Перед установкой необходимо убедиться в наличии libexecinfo. Ставится он так:
cd /usr/ports/devel/libexecinfo
make install

Так же подсказали,
hilobok:
На FreeBSD чтобы не собирать libexecinfo из портов достаточно сделать:
pkg_add -r libexecinfo

Итак, классический способ#1
cd /usr/ports/www/node
make
make install

Тот, что доктор прописал, рекомендуется всем. Тем, кто не знал о том, что node присутствует в портах — знайте.
Способ#2
Если у портах node отсутствует, можно попытаться установить с помощью классического способа, описанного выше (под Linux): wget или git clone; tar -xvf; configure; make и т.д.
Но, судя по всему, таким способом не выйдет установить node на 64-битную систему.
Способ#3
Если возникли какие-либо проблемы (а у меня возникали), есть очередной способ.
Заходим на страницу www.freebsd.org/cgi/query-pr.cgi?pr=145641
Скачиваем файл node-0.1.90.shar
Или создаём файл node-0.1.90.shar и заполняем его содержимое вручную (для тех, у кого wget споткнётся о знак амперсанда в url, и не хочется разбираться, в чём дело).
Говорим:
sh node-0.1.90.shar
cd node
make
make install

Подобные файлы (.shar), ежели они будут появляться впоследствии, можно будет найти тут: b23.ru/exxw
Способ от AterCattus
При сборке под FreeBSD 8.0_RELEASE amd64 с первого раза не собралось:
...obj/release/cpu-profiler.o(.text._ZN2v88internal23ProfilerEventsProcessor19FunctionCreateEventEPhS2_i+0x81): In function `v8::internal::ProfilerEventsProcessor::FunctionCreateEvent(unsigned char*, unsigned char*, int)':
: undefined reference to `v8::internal::OS::ReleaseStore(long volatile*, long)'
obj/release/cpu-profiler.o(.text._ZN2v88internal23ProfilerEventsProcessor15CodeCreateEventENS0_6Logger16LogEventsAndTagsEiPhj+0xa3): more undefined references to `v8::internal::OS::ReleaseStore(long volatile*, long)' follow
scons: *** [obj/release/mksnapshot] Error 1
scons: building terminated because of errors.
Waf: Leaving directory `/home/atercattus/node.js/node-v0.1.97/build'
Build failed: -> task failed (err #2):
{task: libv8.a SConstruct -> libv8.a}
*** Error code 1

Помогла эта ссылка: code.google.com/p/v8/issues/detail?id=726.
Там все просто, в v8/src/platform-freebsd.cc добавляется между int OS::ActivationFrameAlignment() и const char* OS::LocalTimezone(double time) реализация недостающей функции:
void OS::ReleaseStore(volatile AtomicWord* ptr, AtomicWord value) {
__asm__ __volatile__(""::: «memory»);
*ptr = value;
}

Может кому поможет.

Обновление на момент 11 июня
Вышеприведённый патч не актуален для последней версии из git — само прекрасно компилится под freebsd-amd64

Установка под Windows


Забудьте про .NET версию, по крайней мере, до появления порта версии 0.1.90 (см. примечание выше). Придётся использовать Cygwin. Тут есть два способа — находите, качаете, ставите Cygwin, добавляете python, g++, другие зависимости, возможно правите ручками исходники node… Если есть время и желание — пожалуйста, в таком случае Cygwin-совместимый порт брать тут.
Я предлагаю более простой вариант:
Скачиваем архив с прекомпилированным node.exe: drop.io/2dwcadi или dl.dropbox.com/u/626643/node-cygwinx86.zip — зеркало на dropbox. Это последняя версия, доступная для Cygwin (0.1.95), кроме того, для неё cygwin и не нужен (она portable). Распаковываем.
Есть еще один запасной вариант, через colinux: bit.ly/9hCjHO
Примечание:
azproduction:
Для пользователей windows (если у вас node.exe и server.js лежат в разных местах) команда для запуска из-под Cygwin версии будет:
node.exe /cygdrive/буква_диска/путь/до/скрипта/server.js
относительные пути не понимает, windows пути с любыми слэшами тоже не понимает.

Также небольшой апдейт — на данный момент (11 июня) из-под cygwin можно собирать оригинальный node.js, скачав его с помощью git.

Тест — драйв


Для запуска создаём файл, например, server.js. Содержимое-образец можно взять на nodejs.org.
В cmd переходим в распакованную папку и говорим:
node.exe server.js
В *nix аналогично, переходим в распакованную папку и говорим:
node server.js
Обращаю внимание, что тормоз в две секунды в примере — это не тормоз, а специальная отсрочка отдачи, реализованная через setTimeout, просто в качестве демонстрации возможностей.
Мой любимый пример немного другой:
var sys = require('sys'),
http = require('http');
var i=0;
http.createServer(function (req, res) {
i++;
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('Hello World'+i+'\n');
res.end();
}).listen(8000);
sys.puts('Server running at 127.0.0.1:8000/');

Обратите внимание на инкремент переменной при обновлении страницы.
Чтобы выключить сервер/перезагрузить с другим скриптом, нажмите Ctrl+C (и заново запустите node). Обратите внимание, что если вы запустите node через putty, например, то при закрытии консоли node выключится. Я думаю, разобраться в этом несложно, самый простой вариант — запускать screen, либо демонизировать процесс, добавив node в /etc/init.d, выключая при помощи команды stop или killall node. Подробнее о такой установке (на английском) тут.
Это всё.

Настройка nginx


Далее, ваш сервер, скорее всего, будет работать на 80 порту, а node, например, на 8000. Чтобы было удобнее писать скрипты с красивыми адресами, настраиваем nginx, прописывая в конфиге:
location /ajax/ {
proxy_pass http://127.0.0.1:8000/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Как замечено в комментариях, эта конструкция не подходит для настоящих проектов, и надо настраивать Timeout, размеры сообщений, и т.д. кроме того, всё равно придётся настраивать количество одновременнызх подключений в самой системе. Т. е. эта конструкция подходит для ознакомления и для тестирования.
Теперь при запросе example.com/ajax содержимое отдаст node.js.
Обратите внимание, скрипт, запущенный в node в таком случае определит url не как равным '/ajax/', а именно как '/'.
На этом можно остановиться, получив рабочий node.js, можно начинать его трогать ручками. Эта штука — действительно замечательна. Напоследок несколько ссылок:
nodejs.org/api.html Документация
kuroikaze85.wordpress.com/all-node-js-entries — Сборник статей о node хабрачеловека Сергея Широкова (kurokikaze).
howtonode.org — статьи и заметки на английском Тима Касвелла (Tim Caswell aka creationix).
Дамир aka ainu @ainu
карма
407,3
рейтинг 0,4
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (48)

  • +2
    Спасибо. Это руководство надо добавить на nodejs.ru
    • +2
      Хорошо, добавлю, с учетом замечаний, если они будут.
  • +1
    и опять make install
    • +1
      Лучше было бы собрать как минимум при помощи checkinstall
      checkinstall --fstrans=no --install=no --pkgname=node.js --pkgversion «0.1.97» --default
      • 0
        А расскажите почему эта жуть:

        checkinstall --fstrans=no --install=no --pkgname=node.js --pkgversion «0.1.97» --default

        лучше

        make install

        ?
        • +3
          Лучше она тем, что в итоге получится deb пакет который потом можно еще и удалить безболезненно.
          • 0
            Спасибо, буду знать.
  • +4
    самый простой вариант — запускать screen, либо запускать с амперсандом в конце, выключая при помощи команды killall node.


    Если запускать с ампресандом в конце — то при выходе из консоли он всеравно закроется. Есть такая команда nohup

    А еще есть утилита start-stop-daemon
  • 0
    под линуксом лучше таки собрать пакет и поставить его средствами пакетного менеджера. а не превращать систему в слаку. сборка пакета довольно проста. для deb-based дистрибутивов, например, можно использовать checkinstall. т.е.

    make
    sudo checkinstall -D make install

    аналогично, его можно использовать для сборки rpm-пакета.
    • 0
      Для дебианов debuild есть.
  • +1
    Надо заметить у автора не самый удачный конфиг для Nginx.
    Дело в том, что node.js часто используют для всяких долгоживущих соединений.
    Поэтому, как минимум, стоит выключить вот эту опццию
    Более удачные конфигурации для node.js можно найти здесь
  • +1
    А можно ли где-то найти описание преимуществ node,js перед другими решениями по пунктам? Мне показалось немного искусственной вся эта конструкция. Рад буду ошибиться.
    • +2
      Один язык для клиента и сервера — это естественно ;)
    • +1
      Во-первых, для серверных COMET решений преимущества для тех, кто никогда не использовал Ruby или Python — node очень прост в изучении, это знакомый javascript.
      Во-вторых, скорость, она великолепна.
    • 0
      Основных преимуществ два — скорость + память.
      Основной недостаток — количество вспомогательных библиотек, молодость решения.

      Более конкретно о преимуществах и недостатках можно говорить, в зависимости от того, с каким другим решением осуществляется сравнение.

      Не последнюю роль здесь играют личные предпочтения разработчиков и уже существующий серверный фреймворк, если он есть.

      Скажем, у меня CRM на django — так почему бы не взять Tornado/Twisted?
      Или система на Java — естественное решение cometD / Jetty / Grizzly.
      Можно везде использовать одну и ту же модель, это очень удобно.

  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      А обработка файлов в мультизагрузке по мере их поступления? :)
      • 0
        очереди? Zend_Qeueu
  • 0
    На FreeBSD чтобы не собирать libexecinfo из портов достаточно сделать:
    pkg_add -r libexecinfo
  • +1
    Для пользователей windows (если у вас node.exe и server.js лежат в разных местах) команда для запуска из-под Cygwin версии будет:
    node.exe /cygdrive/буква_диска/путь/до/скрипта/server.js
    относительные пути не понимает, windows пути с любыми слэшами тоже не понимает.
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Это специально для Вас: habrahabr.ru/blogs/webdev/95972/ :)
      • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          Есть концепция сообщений (Web Workers API).
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Node.JS вообще-то очень далек от стабильной версии. ;)

              Да, это master.
            • –1
              Оно работает на многих production серверах. Ему можно доверять.
              В любом случае, сервер node надёжнее аналогичного, написанного на php и сокетах.
              • +3
                Работать оно работает, но это не стабильная версия. Самое важное, — пока ещё возможны серьёзные изменения интерфейсов.

                Недавно как раз вырезали Promises, к примеру.

                Хотя, конечно, многие из нас привыкли работать на Edge-версиях, когда это оправдано.

                Лично я уже подсел на Node :)
    • 0
      А как насчет Nginx upstream backend?
      Рано или поздно всеравно придется задуматься о масштабируемости
      • НЛО прилетело и опубликовало эту надпись здесь
        • +1
          Честно говоря, на ум ничего не приходит. Но всеравно непонятно зачем это нужно.
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Простейший вариант — мастер-скрипт, запускающий отдельные процессы, может элементарно общаться с ними, событийно и асинхронно.
              Вот пример общения с командой ls
              Example of running ls -lh /usr, capturing stdout, stderr, and the exit code:
              var sys = require('sys'),
              spawn = require('child_process').spawn,
              ls = spawn('ls', ['-lh', '/usr']);

              ls.stdout.addListener('data', function (data) {
              sys.print('stdout: ' + data);
              });

              ls.stderr.addListener('data', function (data) {
              sys.print('stderr: ' + data);
              });

              ls.addListener('exit', function (code) {
              sys.puts('child process exited with code ' + code);
              });
        • +1
          Есть, если процессы свои.
    • 0
      Асинхронная архитектура отлично справляется с теми задачами, для которых предусмотрено асинхронное решение на всех этапах процесса обработки. Таким образом решается задача concurrency.

      Например, операция отсылки содержимого файла на уровне OS асинхронна, сетевые операции асинхронны. Основной поток просто перепоручает задачу дальше и переходит к следующему запросу. В результате — multiuser concurrency.

      Это работает не всегда. Точнее, не работает там, где асинхронность на некотором звене отсутствует.
      Как должно быть? Вася поручил Маше, она поручила Паше, Паша получил Даше, Даша сказала ок — сделаю позвоню. И затем в обратную сторону.
      Если на каком-то звене проблема, например, Даша решила сделать «пряма щас» (синхронно) — то Паша ждет ответа Даши, Маша ждет ответа Паши. Все курят.

      В случае с node.js (not only) это происходит, например, с MySQL, для которой нет открытого асинхронного API. В этом случае для concurrency используются потоки.

      Это отлично работает до тех пор, пока 1 процессор справляется с нагрузкой основного процесса. В 95% приложений так оно и есть, все в порядке.

      Multiple CPU concurrency в оставшихся 5% (цифра приблизительная), и решается запуском нескольких процессов. При этом архитектура принципиально меняется, т.к. разные процессы имеют раздельное адресное пространство.
      Как правило, стараются все равно хранить всех подключенных юзеров в одном массиве одного процесса, а детали зависят от того, откуда вообще берется 100% загруз CPU.

      Вот, вкратце, все детали concurrency для Node.JS и других решений подобного рода, включая EventMachine (Ruby), Tornado/Twisted (Python), POE (Perl) и т.п.

  • 0
    Это хорошо. Статья полезная.
    Но у меня сразу возник вопрос о перезапуске приложений. Тоесть допустим зарелизили версию приложения, она работает например как сервер для онлайн игры. Нужно в релизе поправить пару багофиксов или сменить игровой баланс настроить. Как тогда это делается? Есть ли какие-то средства он-аир изменений? Или стоп-старт в любом случае необходим.
    Интересна именно потенциальная возможность. Понятно что в реальном проекте это делается балансировщиками и проксирующими серверами, но допустим их нету (архи-хреновая архитектура)
    • +3
      У вышеупомянутого kurokikaze есть статья: Горячая замена кода в node.js
      А так — да, придется перезагружать (это быстро, доли секунды, но переменные сбрасываются).
      Можно переписать под себя — есть замечательная конструкция script:
      var sys = require('sys'),
      localVar = 123,
      usingscript, evaled,
      script = process.binding('evals').script;

      usingscript = script.runInThisContext('localVar = 1;',
      'myfile.js');
      sys.puts('localVar: ' + localVar + ', usingscript: ' +
      usingscript);

      В двух словах — объект script может брать откуда-нибудь код скрипта, eval-ить его в машинный код (прекомпилировать), и затем многократно запускать.
      • 0
        Или вот так
        scriptObj = new script('globalVar += 1', 'myfile.js');

        for (i = 0; i < 1000 ; i += 1) {
        scriptObj.runInThisContext();
        }

        Один раз скомпилили, 1000 раз запустили.
    • +1
      Есть несколько подходов для горячей замены.

      К примеру, github.com/isaacs/node-supervisor

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

      Новые функции и классы заменят старые, для новых объектов.
  • +1
    При сборке под FreeBSD 8.0_RELEASE amd64 с первого раза не собралось:
    ...obj/release/cpu-profiler.o(.text._ZN2v88internal23ProfilerEventsProcessor19FunctionCreateEventEPhS2_i+0x81): In function `v8::internal::ProfilerEventsProcessor::FunctionCreateEvent(unsigned char*, unsigned char*, int)':
    : undefined reference to `v8::internal::OS::ReleaseStore(long volatile*, long)'
    obj/release/cpu-profiler.o(.text._ZN2v88internal23ProfilerEventsProcessor15CodeCreateEventENS0_6Logger16LogEventsAndTagsEiPhj+0xa3): more undefined references to `v8::internal::OS::ReleaseStore(long volatile*, long)' follow
    scons: *** [obj/release/mksnapshot] Error 1
    scons: building terminated because of errors.
    Waf: Leaving directory `/home/atercattus/node.js/node-v0.1.97/build'
    Build failed: -> task failed (err #2):
    {task: libv8.a SConstruct -> libv8.a}
    *** Error code 1


    Помогла эта ссылка: http://code.google.com/p/v8/issues/detail?id=726.
    Там все просто, в v8/src/platform-freebsd.cc добавляется между int OS::ActivationFrameAlignment() и const char* OS::LocalTimezone(double time) реализация недостающей функции:

    void OS::ReleaseStore(volatile AtomicWord* ptr, AtomicWord value) {
    __asm__ __volatile__(""::: «memory»);
    *ptr = value;
    }


    Может кому поможет.
    • 0
      Золотой комментарий, золотая информация, большое спасибо.
      Сам был вынужден использовать 0.1.90, потому что такая версия в портах последняя, следовательно некоторые либы не работают, например, mysq-node.
  • 0
    У меня так и не получилось запустить Node.js на Windows 7 по вашей инструкции. Вот тут нашёл более рабочий вариант www.lazycoder.com/weblog/2010/03/18/getting-started-with-node-js-on-windows/
    • 0
      Так это не под виндовс, а в виртуальной машине. С таким же успехом вы можете там запустить любой линух-юних-мак.
      • 0
        Да, но других рабочих решений установки Node.js под Windows я так и не нашёл.
        • +1
          я скачал по ссылке из статьи скомпилированный вариант и все работает под Вин7
          • 0
            Я извиняюсь. Перепроверил, оказывается node.exe просто не понимает вызова вида:
            node.exe d:/server/home/localhost/www/server.js

            Работает только если server.js находится в папке с node.exe и вызывается:
            node.exe server.js

            Кто-нибудь заминусуйте мой коммент
            TedBeer, спасибо!

  • 0
    Лично меня заинтересовал этот язык.
    Попробую покопать в сторону сокетов, чтобы онлайн соединения между пользователями осуществлять.
    Спасибо

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.