PC_ZONEПример асинхронного веб-сервераблерный код, и переименовали в TraceMonkey — именно этот движокиспользуется в ветке 3.6 Firefox’а. В основном SpiderMonkeyиспользуют в ПО, которое написано на С/С++ и нуждается в скриптовомязыке. Из известных продуктов: Comet-сервер APE, noSQL БДCouchDB, серверная платформа Jaxer и модуль к Apache mod_js.Futhark — это движок от Opera, который, кроме браузера, используетсяв их инновационном сервисе Unite (типа встроенный серверв каждом браузере), а также на их серверах, обслуживающихмобильный браузер Opera Mini. Жаль, что движок закрыт, и егопока нигде за пределами самой Opera не применяют.V8 — движок от Google, который используется в Chrome и являетсяосновой будущей Chrome OS. Сегодня это самый крутой, быстрыйи мощный движок, в котором JS-код напрямую преобразуется вассемблер целевого процессора, что позволяет обойти по скоростивсе остальные движки. Кроме этого гугловцы используют множествоухищрений для оптимизации, хранят в памяти скомпилированныйкод, оптимизируют его на лету (например, удаляют блоки кода, которыепо решению компилятора вообще не могут быть задействованы,и т.п.). На базе этого движка построена самая популярная и быстроразвивающаясясерверная платформа — Node.JS.NODE.JSВероятно, именно после выхода Chrome разработчики смекнули,что такой быстрый движок можно успешно использовать и на сервере.Первым опытом стал проект V8cgi, который просто позволялписать серверные сценарии, работающие с любым веб-серверомпо стандартному протоколу CGI. Дальнейшие эксперименты привелик рождению проекта Node.js — полностью самостоятельнойплатформы, включающей, кроме движка, встроенный сервер (HTTPи TCP/UDP/Unix-soket) и базовый набор библиотек, а также предоставляющейполностью асинхронную работу с файлами и сетевымиустройствами.Проект развивается настолько быстро и активно, что уже сейчасготов к промышленному использованию. Это, в частности, доказываетопыт парней из Plurk (азиатский аналог твиттера), которыеполностью перенесли свой comet-сервер, изначально написанныйна Java и солидном JBoss Netty, на Node.js и, по отзывам, сократилипотребление памяти буквально на гигабайты. А масштабы у нихеще те — более сотни тысяч одновременных соединений.Запустить HTTP-сервер, способный обрабатывать асинхроннотысячи подключений — это несколько строк кода:var sys = require('sys'),http = require('http');http.createServer(function (req, res) {res.writeHead(200, {'Content-Type': 'text/plain'});res.end('Hello World\n');}).listen(80, "127.0.0.1");sys.puts('Server running at http://127.0.0.1:80/');Чтобы запустить сервер, скопируй код в файл example.js и укажиего при запуске демона node:Для последних версий Node.js есть полноценныйWindows-порт% node example.jsServer running at http://127.0.0.1:80/Маленький тест провести очень просто. Можно взять программуApache Bench — очень простую тулзу для проведения нагрузочноготестирования, и запустить ее: running «ab -n 1000 -c 100‘http://127.0.0.1:80/’». Таким образом, бенчмарк будет «обстреливать»сервер тысячами запросов, используя 100 одновременныхподключений. На моем ноутбуке сервер выдержал больше 3000запросов в секунду. Это очень много!Сам сервер написан на C++ и совсем немножко на ассемблере,однако большая часть библиотек из дистрибутива разработанана JavaScript. В состав базового набора сервера входят толькоосновные функции, остальное оставлено на плечах разработчиков,которые уже написали сотни разных библиотек и фреймворков.Впрочем, молодость проекта дает о себе знать: многих привычныхдля других решений модулей еще нет, а у многих библиотек текущаяверсия — 0.0.1, что не придает уверенности в их стабильности.Некоторые тривиальные задачи могут вообще не иметь готового кзакачке решения, но бывает и наоборот — количество реализаций,зачастую радикально разных по архитектуре, исчисляется десятками(доступ к базе MySQL, например). Хотя большинство библиотекнаписано на чистом JavaScript, есть и такие, что требуют компиляциимодуля к серверу, что обещает гораздо большую скорость —они просто расширяют стандартный API сервера.ÎÑÎÁÅÍÍÎÑÒÈ NODE.JSОсновной особенностью Node, кроме полной асинхронности,яв ляется его однопоточная модель. Другими словами, все операциивыполняются в одном и том же потоке ОС, даже если у твоегосервера тысяча одновременных пользователей. Правда, доступносоздание дочерних процессов и низкоуровневое управлениеисполнением скриптов (загрузка, компиляция, работа с ассемблернымкодом, исполнение). Для реализации многопоточности изадействования всех ядер современных процессоров рекомендуетсяпросто загружать несколько копий приложения, но можно взятьна вооружение WebWorker из стандарта HTML5 и распределитьработу приложения по нескольким дочерним процессам. Не думай,что раз нет многопоточности — это тормоз и отстой. Вспомни, чтовеб-приложение делает полезную работу очень быстро, а большуючасть времени просто ожидает чего-то (данных от базы, отmemcached'а или новомодной NoSQL-базы), либо просто держит впамяти открытые соединения для Comet'а, поэтому в одном потокеможно обработать и десяток тысяч, не прибегая к кластеризации.Второй особенностью архитектуры Node является событийность.Почти каждая операция имеет коллбэки, генерирует событие, апользователю доступен объект EventEmiter, через который можнобуквально одной строкой генерировать свои события (это несложно,ведь событие — это просто строка с названием, а также списокпараметров, которые передаются в обработчик). Сам по себе032 XÀÊÅÐ 08 /139/ 10
INFOПроект молодой, и API постоянно изменяетсяinfoБольшинство, еслине все, библиотекии проекты на Node.JS сосредоточены наGithub, поэтому еслинет какого-то модуля,нужного тебе, ищиего там.Утилита для мониторинга логовNode построен вокруг EventLoop — глобального циклаобработки событий, который на каждом тике проверяет,готовы ли данные для какого-либо из определенныхпользователем коллбэков. Если данные есть, начинаетсявыполнение кода. Если не осталось больше кода —ожидаем следующего вызова. Цикл выполняется вне JS,а в самом движке, написанном на C, вследствие чегоэто происходит очень и очень быстро (порядка сотентысяч раз в секунду). Что-то типа бесконечного цикла. Вдополнение к этому в сервер встроен очень эффективныйсборщик мусора (GC), поэтому даже тысячи подключенийне вызывают переполнения памяти и падениясервера. Node.js обладает встроенной родной системойработы с событиями.ÏÐÎÑÒÅÉØÈÉ STEAMING-ÑÅÐÂÅÐПопробуем написать простой, но в тоже время полезныйпример, который в реальном времени будет выдаватьпользователю полезную информацию без перезагрузкистраницы. Вот идея для нашего приложения — братьновые данные, которые добавляются в текстовый лог, ивыводить их в реальном времени на веб-странице:var sys = require('sys'),net = require('net'),spawn = require('child_process').spawn,http = require("http");sys.puts('\nMy process PID: ' +process.pid + '\n');var tail = spawn('tail', ['-f','/var/log/nginx/access.log']);// óêàçûâàåì íàçâàíèÿ ëîãôàéëàsys.puts("Start tailing");tail.stdout.addListener("data",function (data) {sys.puts(data);//äóáëèðóåì ñåáå íà êîíñîëü});http.createServer(function(req,res){res.sendHeader(200,{"Content-Type":"text/plain"});tail.stdout.addListener("data", function(data) { res.write(data); });}).listen(80);С помощью функции spawn() мы создаем дочерний процессутилиты tail, которая, собственно, и занимаетсятем, что считывает новые данные, которые появляютсяв логфайле. Процесс запускается только раз во времястарта сервера. Собственно, наша задача — отлавливатьмоменты, когда команда tail будет выводить новые данныеиз логфайла и транслировать вывод на веб-страницу каждомуподключившемуся клиенту. Для этого мы будем следитьза возникновением события data (появлением новыхданных) для переменной, к которой запущен процессутилиты tail, и выводить их на страницу с помощью командыwrite(). Таким образом, соединение будет оставатьсяоткрытым для каждого HTTP-запроса. Вот и все. Следитьза активностью процесса не так просто для обычноговеб-приложения, но ничего не стоит для неблокируемойархитектуры node.js и логики выполнения, основанной насобытиях. Нам остается только запустить скрипт: «nodetail.js error.log» и открыть в браузере http://localhost:80.На странице будут отображаться все сообщения, которыепоявляются в логфайле error.log.ÂÎÒ È ÑÊÀÇÎ×ÊÅ ÊÎÍÅÖСейчас, выбирая на чем бы таком написать очередноеweb 2.0 приложение, где не только красивый клиентскийкод, но и что-то надо делать на сервере, тебяпарит одна грустная мысль о том, что все уже изобрелии написали до тебя. Те же языки, что и десять летназад, те же библиотеки, протоколы и сервера. РНРуже ого сколько лет, Perl так вообще седой, Python увсех на слуху, а Ruby успел надоесть. Писать для вебастало рутиной — посмотри, как твои друзья сидят идумают, что же сделать с 25-мегабайтным монстромZend-framework. А тебе хочется что-то нового, бытьна острие прогресса, создавать то, на чем потом будутписать все, а сейчас знают только увлеченные хакерыи ищущие себя дзен-программеры? Посмотри наJavaScript в сервере, он просто создан для этого. Оченьпростой, мощный, еще не погрязший в тонне библиотеки фреймворков. Задачи, которые на РНР не решитьвообще, на базе Node.JS решаются буквально десяткомстрок. И, возможно, именно такое программирование,наконец, принесет утраченное чувство наслаждения отразработки!zHTTP://WWWlinks• Материалы поNodeJS:groups.google.com/group/nodejs• Русскоязычныйсайт и форум:forum.nodejs.ru• Информация о серверномJS:en.wikipedia.org/wiki/Server-side_JavaScript• Хороший мануалдля начинающих поNode.JS:www.slideshare.net/the_undefined/nodejs-a-quick-tour• Презентациявведениепо Node.JS:nodejs.org/jsconf.pdfXÀÊÅÐ 08 /139/ 10033