Nginx + серверный Javascript

    … или как перейти с PHP + JavaScript на JavaScript + JavaScript


    Идея реализовать проект на сервер-сайд JavaScript была уже давно. Проблема была в отсутствии подходящего серверного программного обеспечения. Существующие открытые проекты не устраивали по разным причинам. Устанавливать дополнительный модуль для Apache было не самой хорошей идеей, потому что производительность и оптимизация использования памяти при этом были бы не на высоте. С помощью jslibs можно настроить FastCGI, но очень не хотелось оставлять ни малейших шансов «502 Bad Gateway», проект ngx_http_js_module так и остался в зачаточной стадии, а ngxv8 недостаточно развит для реализации реальных приложений. Поэтому я решил сделать собственную реализацию серверного javascript. Причем постараться сразу запрограммировать всю базовую функциональность, чтобы можно было ее тестировать в условиях, близких к реальности.

    В качестве основного веб-сервера было решено использовать nginx, в качестве «движка» javascript — TraceMonkey (javascript-движок из Mozilla Firefox, бывший SpiderMonkey), и написать модуль для nginx, который бы их «склеил». Ничего сложного, на первый взгляд, но очень хотелось иметь определенную функциональность (и это получилось!), чтобы можно было нормально работать дальше. Большинство идей заимствованы, кстати, из PHP.
    • Корректная работа в multi-thread условиях
    • Возможность выполнять скрипт, указанный в URL, а не настраивать отдельно скрипт-обработчик и функцию-обработчик для каждого location
    • Возможность вызывать include(), sleep(), alert() из скрипта, использовать __FILE__ и __LINE__
    • Ограничение памяти, выделяемой каждому скрипту, и времени работы скрипта
    • Защита открываемых скриптом файлов, указав в настройках список разрешенных папок. Примерно как open_basedir в PHP
    • Автоматический разбор данных запроса (параметров GET, POST, и, конечно же, cookies), чтобы не писать обработку данных на javascript
    • Поддержка запросов application/x-www-form-urlencoded и multipart/form-data
    • Поддержка basic-авторизации
    • Работа с базами данных (в первую очередь, MySQL и SQLite)
    • Работа с файловой системой: чтение и запись файлов, проверка существования файлов, и т.п.
    • Кэширование байт-кода скриптов, как, например, в eAccelerator
    Плюс некоторые другие возможности (инструменты для шаблонизации, для создания конфигурационных файлов, и т.п.), но их в основной список я не включил — их позволяют сделать языковые возможности TraceMonkey.

    От слов — к делу! Как скомпилировать и настроить, как протестировать и сравнить...

    Глубоко в детали сборки не вдаюсь, иначе текст получится неимоверных размеров. Пользователи, имеющие опыт «сборки» программ под Linux, будут чувствовать себя вполне комфортно, а для всех остальных могу предложить бинарную сборку и возможность пропустить процесс самостоятельной компиляции.

    Понадобятся:
    • Linux
    • Компиляторы C и C++, autoconf 2.13
    • Исходники nginx
    • TraceMonkey из репозитория
    • Библиотека NSPR
    • Наш модуль
    • MySQL и SQLite (опционально) + средства разработки
    Порядок сборки следующий.

    Сначала NSPR последней версии (на момент написания — 4.8.2):

    wget ftp://ftp.mozilla.org/pub/mozilla.org/nspr/releases/v4.8.2/src/nspr-4.8.2.tar.gz<br/>tar -xzf nspr-4.8.2.tar.gz<br/>cd nspr-4.8.2/mozilla/nsprpub<br/>./configure --prefix=/usr/local --with-pthreads<br/>make<br/>sudo make install<br/>
    Затем TraceMonkey из репозитория (на момент написания, в репозитории версия 1.8.5, а скачать файл с исходниками можно только для 1.7.0):

    hg clone http://hg.mozilla.org/tracemonkey/<br/>cd tracemonkey/js/src<br/>autoconf2.13<br/>./configure --prefix=/usr/local --with-nspr-prefix=/usr/local --with-system-nspr --with-pthreads --enable-threadsafe<br/>make<br/>sudo make install<br/>
    Этот шаг может быть проблемным по нескольким причинам. Во-первых, не у всех есть команда hg. А во-вторых, из репозитория скачиваются все исходники Mozilla Firefox. Поэтому, первую строчку кода можно заменить и скачать исходники только TraceMonkey:

    # hg clone http://hg.mozilla.org/tracemonkey/<br/>wget http://js.nnov.ru/files/tracemonkey-20100119.tar.gz<br/>tar -xzf tracemonkey-20100119.tar.gz<br/>
    И затем уже скомпилировать.

    Далее nginx (0.8.32) и модуль javascript:

    wget http://sysoev.ru/nginx/nginx-0.8.32.tar.gz<br/>tar -xzf nginx-0.8.32.tar.gz<br/>cd nginx-0.8.32/src/http/modules<br/>svn co http://nginx-javascript.googlecode.com/svn/trunk/ javascript<br/>cd ../../..<br/>./configure --prefix=/usr/local/nginx-javascript --add-module=src/http/modules/javascript<br/>make<br/>sudo make install<br/>
    Если все получилось — то переходим к настройке. Счастливые обладатели бинарной сборки обнаружат, что конфигурация уже выполнена, но лишний раз проверить не помешает. Достаточно выполнить следующие шаги:
    • Добавить в mime.types тип application/x-javascript-serverside для файлов, которые будут обрабатываться как javascript:
      # /usr/local/nginx-javascript/conf/mime.types<br/>types {<br/>    ...<br/>    application/x-javascript-serverside jsx;<br/>    ...<br/>}<br/>
      Расширение .jsx выбрано вместо стандартного .js, чтобы сервер не обрабатывал обычные java-скрипты как серверные
    • Разрешить в разделе location / файла nginx.conf обработку javascript. Заодно сменим номер порта, на котором будет работать сервер:
      # /usr/local/nginx-javascript/conf/nginx.conf<br/>...<br/>    server {<br/>        listen 8081;<br/>        ...<br/>        location / {<br/>            ...<br/>            javascript on;<br/>            ...<br/>        }<br/>    }<br/>...<br/>
    • Запустить nginx:
      /usr/local/nginx-javascript/sbin/nginx<br/>
    • Создать тестовый скрипт hello.jsx:
      // /usr/local/nginx-javascript/html/hello.jsx<br/>print("Hello, people!");<br/>
    • Проверить, что hello.jsx выглядит в браузере как надо:
      curl http://localhost:8081/hello.jsx<br/>
    Добившись того, что сервер с javascript заработал, мне стало интересно, насколько выгоднее такое решение, чем стандартное Apache + PHP. Так как вопросы внутренней оптимизации TraceMonkey и PHP меня волновали несколько меньше (например, какой интерпретатор быстрее выполняет цикл из миллиона шагов? Подозреваю, что разница небольшая), то тестировался, в первую очередь, скрипт «Hello, people!».

    В сравнении участвовали:
    • Apache/2.2.14 (prefork) + PHP/5.2.12 (модуль)
    • nginx/0.8.32 (1 рабочий процесс) + javascript
    • nginx/0.8.32 (8 рабочих процессов) + javascript
    Среда тестирования — 4-ядерный Xeon с 2ГБ оперативной памяти и Debian Etch. Весь трафик локальный. В подробности «железа» не вдаюсь, в детали конфигурации тоже — настройки более или менее стандартные.

    Сначала цикл тестов из 1000 запросов один за другим:

    # Apache 2.2.14 (prefork) + PHP 5.2.12 (module)<br/>ab -n 1000 http://localhost:8085/hello.php<br/>Time per request: 5.278 [ms] (mean, across all concurrent requests)<br/># nginx (1 worker) + javascript<br/>ab -n 1000 http://localhost:8081/hello.jsx<br/>Time per request: 1.298 [ms] (mean, across all concurrent requests)<br/># nginx (8 workers) + javascript<br/>ab -n 1000 http://localhost:8088/hello.jsx<br/>Time per request: 1.322 [ms] (mean, across all concurrent requests)<br/>
    Теперь цикл тестов из 1000 запросов при создании 100 одновременных подключений:

    # Apache 2.2 (prefork) + PHP 5.2 (module)<br/>ab -n 1000 -c 100 http://localhost:8085/hello.php<br/>Time per request: 1.648 [ms] (mean, across all concurrent requests)<br/># nginx (1 worker) + javascript<br/>ab -n 1000 -c 100 http://localhost:8081/hello.jsx<br/>Time per request: 1.277 [ms] (mean, across all concurrent requests)<br/># nginx (8 workers) + javascript<br/>ab -n 1000 -c 100 http://localhost:8088/hello.jsx<br/>Time per request: 0.544 [ms] (mean, across all concurrent requests)<br/>
    Выводы из тестирования:
    • Если запросы к серверу идут последовательно, один за другим, nginx+javascript работает значительно быстрее (у нас примерно в 3 раза). При этом nginx с одним рабочим процессом работает даже чуть-чуть быстрее. В реальности такая ситуация практически никогда не происходит: чаще много клиентов открывают одновременно разные страницы
    • Если запросы к серверу отправляются одновременно, скорость работы apache+php увеличивается (у нас они показали почти такую же скорость, как nginx+javascript с одним рабочим процессом). Но и скорость работы nginx+javascript с несколькими рабочими процессами тоже возрастает (у нас — более, чем в 2 раза). А nginx+javascript с одним рабочим процессом осталась практически неизменной
    Кроме того, что такая реализация серверного javascript позволяет добиться увеличения производительности по сравнению с традиционным PHP, javascript позволяет использовать достаточно хитрые языковые конструкции.

    // Выводит параметры id запросов GET, POST и cookies:<br/>print($request.get['id'], " ", $request.post['id'], " ", $request.cookie['id']);<br/>// Отправляет заголовок Content-Type:<br/>$result.headers.push("Content-Type: text/html; charset=UTF-8");<br/>// Открывает базу данных, выполняет запрос SELECT с параметром, переданным в GET, и забирает одну строку результата:<br/>var row = (new SQLite("database")).query("SELECT * FROM `table` WHERE `id`=?", $request.get['id']).fetch();<br/>// Читает файл:<br/>print(File.open("index.html").getChars());<br/>// Выводит IP-адрес клиента, открывашего страницу:<br/>print({$server.remoteAddr});<br/>
    В последнем примере нет ошибки синтаксиса, XML-документы действительно можно использовать внутри скриптов. При этом в них можно вставлять обращения к переменным и вызовы функций, заключая их в фигурные скобки. Эту технологию, E4X, очень удобно применять для создания шаблонов. Еще ряд примеров можно найти на http://js.nnov.ru/nginx/examples.html.

    Конечно, есть еще ряд проблем, которые нужно постепенно решить:
    • Поддержка загрузки файлов (coming soon!)
    • Поддержка cURL и GD, без которых очень сложно жить
    • Оптимизация системных вызовов stat(), которые сейчас используются для определения определения реального пути к файлу
    Но, в общем и целом, можно пользоваться. Кстати, небольшой сайт http://js.nnov.ru сделан на JavaScript. Просьба жестких тестов на отказоустойчивость пока не проводить :-)

    З.Ы.> Отдельное спасибо FTM за инвайт, благодаря которому топик уже не в песочнице
    UPD> Сразу бы опубликовал в тематическом, но были проблемы с кармой. Спасибо всем участвующим!

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 95

      +22
      Мсье знает толк в извращениях…
      • UFO just landed and posted this here
          0
          Уже грядет, прямо с интегрированной средой разработки.
            +2
            Не могу не согласиться, что определенный набор модулей действительно необходим.
            Но, на самом деле, нужно осознавать, что 90% (или сколько?) задач решаются с помощью очень небольшого количества модулей. Я их попытался перечислить в статье.
            Ну например, часто ли вы используете работу с shared memory или mssql? А XMLRPC? Так стоит ли заморачиваться этими модулями? А из сисколов — вот, например, popen() или exec() — на очень многих хостингах тупо закрыты.
            И, кстати, будучи в поисках серверной реализации Javascript я не нашел сколь-нибудь приемлемой реализации разбора строки запроса или POST-данных. А, на мой взгляд, с этого следовало начать (я, впрочем, может быть пропустил чего?)
              0
              В Ноде можно использовать модуль querystring. Посмотрите, может для вашего случая его можно портировать.
          +14
          Даже странно, что не используется NodeJS или Narwhal.
            +9
            Большую часть того, что вы делаете, уже реализовано. Поскольку вы не разу не упомянули CommonJS или Narwhal, я советую вам с ними ознакомиться.
              +1
              Действительно, досадное упущение…
              Во время поисков, самым удачным мне показался проект jslibs. Он действительно содержит многое из того, что хотелось бы иметь для standard library (разные базы данных, работа с файлами, и т.п.) А вот перечисленных вами проектов не находил, спасибо за ссылки.
              Я правильно понимаю, что они тоже позволяют (в разной степени) создавать и использовать стандартные библиотеки, а также создавать приложения (fastcgi и другие)?
                +4
                Вот тут собрал несколько статей про node: nodejs
                  +4
                  Node.js, я так понял, вообще классная вещь. Сейчас читаю и пытаюсь осозднать :-)
                    0
                    Я тоже у себя в блоге пост написал, думаю будет интересно:
                    www.componentix.com/blog/9

                    Там реализована загрузка файлов только по настоящему, с сохранением в файл потому что это тоже вообщем-то не тривиально с event-based I/O
                      0
                      Здорово!
                      Еще одна тема для «подумать» — интересно, Node.js, у которого разбор request body написан на Javascript, будет ли сравним по скорости с кодом на Си? С учетом того, что виртуальная машина v8 очень и очень даже быстрая — может быть, и не имеет смысла усилия тратить на низкоуровневое программирование правда :-)
                        +1
                        Очень даже сравнима. 500 Мб/сек без проблем — www.debuggable.com/posts/parsing-file-uploads-at-500-mb-s-with-node-js:4c03862e-351c-4faa-bb67-4365cbdd56cb

                        Вообщем-то на Си еще надо тоже уметь эффективно реализовать.
                          0
                          Мне там нравятся события для файлов. Если присылают 5 файлов одним пакетом, их можно обрабатывать по мере прибытия, не дожидаясь загрузки всего multipart-запроса.
                            0
                            Та вообще Node.js радует все больше и больше.
              +1
              Офигеть! Обязательно затестим.
                +2
                А можно взглянуть на скрипты, скорость которых собственно измеряли?
                  0
                  Скрипты, которые тестировались — это обычные «Hello, World!» на PHP и на Javascript (каждый из одной команды). Я не стал сравнивать более сложные программы, потому что тогда на скорость работы влияли бы еще другие факторы: внутренняя реализация арифметики, циклов, функций, работы с памятью, и т.д. в PHP и Javascript. Это, согласитесь, тема отдельного обсуждения (не менее интересная, впрочем).
                    0
                    В таком случае интересно взглянуть на аргументы ./configure при компиляции PHP. Его скорость крайне от них зависит. Чем больше лишнего (не нужного для Hello World страницы) вы туда засунете, тем медленнее будет его работа.
                  +11
                  И еще вопрос… Почему вы сравниваете nginx+js с apache+php, а не с nginx+php?
                    –11
                    Вот вы зануда!!! Челоек ночамине спал, в товрем якогда все делают велосипеды, он изобретал смокат.
                    А вы его тролите такими деталями.
                      –2
                      мой личный граммар-наци негодует!
                        +1
                        Детали всегда интересны :-)
                        А потом, качественно сделанный самокат с возможностью доработки до чего-то более цивильного — он ведь может и получше китайского велосипеда. Метафора, ессно…
                        +1
                        nginx+php я видел в двух вариантах: apache+php+nginx в качестве reverse-proxy (самые простые мои тесты показали, что минимальные скрипты в такой реализации работают в несколько раз медленнее, чем просто apache+php, что и понятно — тесты были на локальном компьютере, без учета скорости сети), и nginx+php как fastcgi. Сравнить действительно было бы интересно (и, скорее всего, я даже этим займусь), но вот некоторое предубеждение против php, установленного как fastcgi, у меня есть. Неспроста я упомянул про 502 ошибку сервера, которая возникает при сбоях в fastcgi-процессах.
                        Хотя, не исключаю, что мои знания в этой области уже устарели, и сейчас все используют fastcgi без особых проблем.
                          +3
                          Устарели, покопайте в сторону php-fpm.
                        0
                        > Корректная работа в multi-thread условиях
                        Может ли рабочий процесс иметь одновременно несколько тредов, в каждом из которых выполняется скрипт?
                          0
                          Нгинкс этого ведь не умеет.
                            0
                            Практика показала, что нет :-(. Если 10 клиентов одновременно запрашивают страницу со скриптом sleep(1), то один из них обязательно увидит страницу после 10 секунд.
                            Почему так — я не очень понял (в API nginx не до конца разобрался пока что, поэтому тестировал «по-колхозному»). Но основной обработчик запрограммирован не так, как в perl-модуле, без глобальной блокировки.
                            Что действительно успешно получается — так это одновременная отправка данных из выполненных скриптов нескольким «медленным» клиентам (одним рабочим процессом). Правда, это не совсем то, что хотелось бы получить в идеале (и не то, о чем был вопрос, это я понимаю :-) )
                              +1
                              Потому что смысл nginx в асинхронной природе, а вы в него синхронные скрипты тащите. Преимуществ перед php вы скорее всего не добьетесь.
                                +1
                                Потому что такова архитектура nginx. Это по сути конечный автомат, и все вызовы должны быть асинхронными, чтобы не создавать блокировок.

                                Посмотрите, например, libevent. Nginx устроен аналогичным образом.

                                В качестве решения можно предложить реализовать собственный thread pool для обработки js, но если не ограничиваться одним воркером, то придется скорее всего еще и решать проблемы взаимодействия между воркерами. Еще один вариант — отдельный процесс для обработки js, с которым «обычные» nginx-воркеры будут общаться через pipes/sockets, но тогда уж проще реализовать fastcgi и не мучаться. :)
                                  0
                                  Думаю для связки с NGinx идеально использовать модель реализованную Node.js, там ведь тоже все вызовы асинхронные.
                                    0
                                    Насколько я понимаю, node.js это такой «либевент для javascript». Тут, собственно, и nginx не нужен, там первым же примером веб-сервер. :) А вот если мне захочется работать с СУБД — придется реализовывать для node.js протокол mysql | postgresql | etc — либо допиливанием самого node.js, либо реализовывать протокол на его tcp client-е. С async disk i/o тоже вопрос.

                                    В общем и целом, эта вся затея, на мой взгляд, имеет смысл не более, чем ровно такой же, как nginx embedded perl — со всеми его ограничениями — то есть для небольших компактных обработчиков (я, например, использовал embedded perl для расширенного аналога модуля secure link); полноценные же приложения проще запускать отдельными процессами. По крайней мере, до тех пор, пока не появятся асинхронные библиотеки для удобной работы с СУБД и прочим (в идеале — вообще виртуальная машина а-ля parrot, организующая свой event loop и «асинхронизирующая» все вызовы)… но это я размечтался, ага.
                                      0
                                      mysql / postrgresql вроде реализованы уже (mysql через web обертку).

                                      Большинство NoSQL баз данных имеют довольно простой протокол, думаю с ними Node.js будет использовать приятно, да и приспособлены они обычно лучше к асинхронной работе.
                                        0
                                        >> через web обертку

                                        Что-то наподобие Amazon SimpleDB? Вариант, конечно, если нужны только простые одиночные запросы. Но с транзакциями получается облом.

                                        NoSQL — согласен, тем более, что их легко инкапсулировать в http.

                                        Пожалуй, действительно тогда уже в таком виде node.js удобен для ряда задач (тот же веб-чат). Но смысла ембеддить это дело в nginx я так и не вижу никакого.
                                          0
                                          Такая есть обертка:
                                          code.nytimes.com/projects/dbslayer/

                                          Ембеддить в nginx особо смысла действительно не видно, ведь можно просто использовать его как прокси и роздавать статику. Я лишь о том что если уж ембеддить яваскрипт, то использовать событийную модель как и nginx.
                              0
                              А еще было бы интересно сравнить с jsp.
                                0
                                и asp.net
                                  0
                                    0
                                    ну DLR все же еще в бете и кроме того сильно медленнее CLR по определению. но все равно спасибо.
                              • UFO just landed and posted this here
                                  0
                                  Время всегда есть. Надо лишь умело им управлять.
                                  +6
                                  Почему тестируется Apache + PHP против nginx + javascript? Если уж по правильному, то nginx + PHP vs nginx + javascript.
                                    0
                                    Вот-вот. Сравнивать Apache + PHP некорректно уже просто потому, что nginx + php будет уже производительнее, следовательно даже если javascript равен по производительности php, все равно выиграет в тестировании.
                                      0
                                      А зачем их сравнивать только по скорости? Для меня таки фишка в самом Javascript, будь он хоть в три раза медленней PHP.
                                        0
                                        Присоединяюсь :-) Несмотря на то, что объектно-ориентированную модель Javascript многие ругают, мне очень нравится программировать на Javascript. Возможность создавать inline-функции без особых забот, использовать или не использовать $ в именах переменных, и, в общем, круто все делать — и при этом никаких обязанностей, как в Java, где обязательно создавать подо все классы и постоянно new'кать :-)
                                      0
                                      А не пробовали — ли вы сЭмулировать window object с помощью какого либо интерфейса Java — web — browser'a?
                                        0
                                        Нет… Манипуляция с текстом страницы, который клиент получит все равно статичным, и использование для этого сложных интерфейсов и компонентов — опасная штука, на мой взгляд…
                                          0
                                          тут проблема интереснее: повторить на сервере все действия, которые на клиенте происходят. А без window это не получится
                                            +1
                                            Согласен, это интересная задача. Но когда я думаю о том, какой это необъятный объем работы — у меня прямо руки опускаются… И все «бонусы» теряют свою привлекательность :-)
                                      +2
                                      Я делаю на Node.js + nginx + Tokyo Tyrant. На самом деле очень интересная штука — серверный Javascript :)
                                        0
                                        Кстати, если использовать CouchDB, там можно писать запросы (фильтры) на Javascript :) Будет вообще красиво :)
                                        0
                                        А каким образом вы подключили JS к nginx? Модулем или FastCGI?
                                          0
                                          Модулем. FastCGI при некоторых условиях теряет стабильность (я упомянул про 502 ошибку, очень распространенную на сайтах с FastCGI) и работает, все-таки, несколько медленнее.
                                            +2
                                            > я упомянул про 502 ошибку, очень распространенную на сайтах с FastCGI
                                            И виноват в этом, конечно, FastCGI…
                                              0
                                              Виноват, конечно же, не FastCGI, понимаю вашу иронию.
                                              Виновата чаще всего реализация fastcgi-сервера. Ну сами подумайте: люди разрабатывают веб-серверы, которые оптимизированы, и проверены, и т.п. (пример тому — и Apache — не смейтесь, и nginx).
                                              И тут появляется идея FastCGI, все ее одобряют (идея действительно супер), но оказывается, что вся логика веб-сервера должна быть и в FastCGI-демоне (или в модуле, который стартует FastCGI): слежение за сбойными процессами, автоматический запуск, если FastCGI сломался, и т.п. И, по всей вероятности, в случае с PHP разработчики так до конца и не определились, кто должен эти действия выполнять: веб-сервер или fastcgi-процесс. Оттуда и ошибки были…
                                              Не спорю, что при правильной реализации FastCGI все будет просто здорово.
                                                0
                                                кстати, в Вашем случае возможен следующий подводный камень: [цитата]
                                                Когда обрабатывается один сокет одним из рабочих процессов, все остальные сокеты этого рабочего процесса продолжают ожидать обработки. Если обработка одного сокета затягивается, то остальные сокеты начинают испытывать «голод»: приходящие данные скапливаются во входных буферах сокетов, а готовые к записи сокеты не получают новых данных. На клиентской стороне подобная ситуация выглядит как «зависание». Для предотвращения голодания сокетов сервер и компоненты сервера должны быть реализованы с использованием следующих принципов
                                                — Избегать длительных вычислительных процессов;
                                                — Минимизировать число синхронизаций с другими процессами;
                                                — Избегать блокирующих системных вызовов.
                                                Из-за описанных выше ограничений полномасштабные веб-приложения сложно реализовать исключительно в модулях nginx.

                                          +3
                                          перенесите в тематический блог. пост достоин главной.
                                            +2
                                            Эксперимент интересный. Но просто «js на сервере» — не очень ново, тот же jaxer уже давно с нами. Да и переписывать кучу всего на другой язык без ощутимой выгоды — занятие не очень оправданное.

                                            Если собираетесь что-нибудь делать все-таки на js, присмотритесь лучше к node.js — там асинхронность всего и вся, вот это на самом деле имеет практическую выгоду даже с учетом новизны технологии.
                                              +3
                                              можно вопрос? а почему TraceMonkey? почему не v8? насколько я знаю, последний значительно быстрее. Я ошибаюсь?
                                                0
                                                дополню, что SquirrelFish Extreme по-моему «рвет его на куски»
                                                  –1
                                                  SquirrelFish не получилось собрать под Linux :-(
                                                  +1
                                                  v8 действительно быстрее (хотя все зависит, конечно от задач) — я пробовал тестировать скрипты в javascript shell, вот только результаты в виде красивых графиков пока не оформил.
                                                  TraceMonkey же выбрал по следующим причинам:
                                                  — По сравнению с v8, можно писать на чистом Си (хотя TraceMonkey написана на C++)
                                                  — Не нашел явного указания на то, что v8 является thread-safe. Хоть он и слинкован с libpthread по умолчанию, но делать большой проект, а потом прекращать его из-за проблем с потокобезопасностью не очень хотелось…
                                                    0
                                                    V8 was designed to in single-threaded environment. So there is no locks
                                                    around commondata structures such as heaps and accessing static variables.
                                                    We thought adding locks
                                                    around these data structures can slow down allocations.
                                                    V8 api has a Locker class that can be used to protect V8. Application can
                                                    embed V8 in
                                                    a multi-threading program by using Locker around V8 api calls.
                                                      0
                                                      возможно, все-таки попробовать squirrelfish? они примерно одинаковы по производительности(первый даже немного лучше)
                                                        0
                                                        О, спасибо, очень точно! Я подозревал что-то подобное…
                                                        Вообще, выбор виртуальной машины для реализации проекта — это вещь, над которой нужно очень хорошенько думать…
                                                      0
                                                      А нафига вообще эти потоки нужны? Сейчас модно event loop (node.js, ngnix) + процессы для разнесения нагрузки по ядрам процессора.
                                                    –1
                                                    А в чем смысл использовать яваскрипт на стороне сервера? С его кривым ООП, где публичные методы класса не имеют доступа к приватным свойствам и методам класса… И в стандарте ECMA script 5 (который вышел в декабре) это осталось, вот в следующей версии стандарта вроде бы собираются сделать уже нормальное ООП.
                                                      0
                                                      ECMA стандарты имеют крайне слабое отношение к TraceMonkey.
                                                        0
                                                        На самом деле, вопрос «кривости» ООП — это тот еще вопрос :-).
                                                        Раньше мне нравился PHP (когда он был еще 4). Потому что все трюки, которые можно было сделать в плане ООП — они все документированы официально. Потом появился PHP 5 и он показался мне еще более продвинутым. Но когда я увидел ООП в других языках…
                                                        — Java — хрестоматийный пример, все объектно-ориентировано, люди очень хорошо думают над дизайном классов. Но, блин, писать небольшие скриптики и постоянно думать, а не слишком ли фигово я классы назвал — это ж кошмар!
                                                        — Python — все супер, огромная standard library, но ведь тоже что-то не устраивает! А тут еще и переход на Python 3…
                                                        — Ruby — это просто ООП будущего, отличный язык… Но тут мне попадается на глаза вот эта статья, и мне как-то страшно на этом языке писать реальные программы…
                                                        — Javascript — всего по минимуму, но, в то же время, ощущение легкости и полноты. А тут еще оказывается, что server-side javascript появился относительно недавно, и есть над чим поработать…
                                                        — C++ не рассматриваю для веб-программирования уж :-)
                                                        Ну и, по сравнению со всем этим разнообразием, попытки PHP обновить свой язык, добавить в него (наконец-то!) юникод, нормальные inline-функции, и т.п., выглядят просто (извините) жалкими. А вы говорите про кривой Javascript :-)
                                                          0
                                                          «что-то» — это что? Меня в питоне все устраивает (:
                                                        +1
                                                        Меня радует тот факт, что все больше людей пытаются использовать JS на сервере т.к. это (теоретически) может дать определенные бонусы при разработке серверной части web приложений, однако мало заставить работать JS на сервере, нужно так же подготовить нормальную инфраструктуру классов для выполнения рутины, но при этом достаточно трудно будет множеству разработчиков договориться и сделать что-то одно и достаточно мощное (как это обычно происходит) и скорее всего можно будет наблюдать множество «фреймворков», из которых останутся самые мощные/удобные/легко изучаемые/широко используемые/хорошо оптимизированные.
                                                        И быстродействие — оно сильно важно и явно придется делать что-то для увеличения скорости.
                                                          0
                                                          Согласен с вами. Причем множество фреймворков уже наблюдается :-)
                                                          Единственное что — многие написаны на C++ (а не на C) и/или используют свою систему работы с памятью. Не всегда оптимальную, кстати (по сравнению с nginx, который использует не malloc, а выделение памяти из pool'а.
                                                          Поэтому «прикрутить» что-нибудь к проекту пока не удалось…
                                                          0
                                                          Ваш код можно сделать быстрее, если:
                                                          * Использовать пул контекстов
                                                          * Использовать рантайм на тред, а не контескт на тред + общий рантайм.
                                                          * Поиграться с JIT в tracemonkey
                                                          * Вообще не линковаться с NSPR, не использовать --enable-threadsafe (+ пофиксить уже те пару багов которые упоминает Брендан Айх в официальном мейл-листе.)
                                                            0
                                                            Ваши советы точны и по существу, приятно, что вы заглянули в исходники.
                                                            Тогда у меня к вам встречный вопрос. Не знаете ли вы, как можно реализовать асинхронный handler в nginx? А то из nginx я знаю только Игоря Сысоева, но не лично и не по переписке (кто ж его не знает). У Emiller'а — два притопа — три прихлопа, для новичков, правда, в самый раз…
                                                            Вот как бы так сделать, чтобы handler, описанный в модуле, не блокировал весь процесс, а стартовал отдельный thread и возвращал, например, NGX_AGAIN, а thread тем временем бы выполнял скриптик, вызывал бы фильтры, и т.п.
                                                            Потому что как сейчас сделано — мне самому не нравится. И, если сделать одновременное выполнение многих скриптов в одном worker-процессе — тогда, согласитесь, и thread-safe нужен.
                                                              0
                                                              думаю это сделать будет проблематично,
                                                              могу посоветовать обратится на Сысоевский форум,
                                                              там Макс даст исчерпывающий ответ.
                                                              я, просто боюсь, что посоветую не правильно

                                                              а, вообще у Вас интересное решение.
                                                            0
                                                            Интересная идея, но у JS, надо признать, есть много недостатков: нестрогость, позволяющая использовать необъявленные переменные и обращаться к необъявленным свойствам, бедность функций для работы с массивами/хешами, отсутствие банального foreach() для массивов, отсутсвие наследования объектов и т.д. Понятно, что язык можно расширить через prototype, но хотелось бы, чтобы такие методы были на Си, нативными а не на яваскрипте.
                                                              0
                                                              > нестрогость, позволяющая использовать необъявленные переменные и обращаться к необъявленным свойствам
                                                              Это всё-таки скриптовый язык, а при желании и на других языках можно такого нагородить, что никакие языковые проверки не помогут…

                                                              > отсутствие банального foreach() для массивов
                                                              for(var x in arr)alert(arr[x]);

                                                              > отсутсвие наследования объектов
                                                              Есть наследование, но не «классическое».
                                                                0
                                                                > Есть наследование, но не «классическое».

                                                                В том-то и дело, там нет классов, а руками в цикле копировать свойства — ну это вообще ад какой-то и подрывает производительность (а Hash.merge() там нет). Нет private/public и вообще, все плохо :(

                                                                Кстати, у for (...) есть подвох, он по моему может для Hash левые свойства из прототипа выдавать, там надо еще добавлять проверку hasOwnProperty() или как-то так.

                                                                Насчет строгости — это важно, чем строже и однозначнее синтаксис, тем меньше вероятность дурацких ошибок из-за опечаток.

                                                                  +1
                                                                  >> Насчет строгости — это важно, чем строже и однозначнее синтаксис, тем меньше вероятность дурацких ошибок из-за опечаток.

                                                                  И тем больше рутины, к сожалению.
                                                                    0
                                                                    В принципе, да, со строгостью так. Но, с другой стороны, это обычно ловится в юнит-тестах, дает доп. бонусы в скорости разработки, да и вообще побуждает эти юнит-тесты писать, от чего тоже одни плюсы)
                                                                      0
                                                                      private/public как раз есть, но не «классические» а через замыкания. См. например: phrogz.net/js/Classes/OOPinJS.html. Главная кривизна такой реализации в том, что публичные методы не имеют доступа к приватным свойствам и методам.
                                                                    0
                                                                    Насчет скудности функций и foreach() не согласен совершенно. У массивов есть и .map, и .filter, и .forEach (.each), что еще нужно, вместе с лямбда-функциями-то? Все это на C реализовано в современных движках, а от старых можно абстрагироваться с помощью какой-нибудь библиотеки (к примеру, mootools), которая бы добавляла реализацию на js, если нативной реализации нет. На сервере, наверное, даже прослойка не нужна, т.к. интерпретатор выбираешь сам.
                                                                      0
                                                                      JS нормальный полноценный скриптовый язык
                                                                    +1
                                                                    Давайте уже смотреть в сторону Jaxer
                                                                      0
                                                                      Желаю вам удачи!
                                                                      Проект чертовски интересный!
                                                                      :)
                                                                        0
                                                                        Спасибо :-) Сил бы хватило только
                                                                        +1
                                                                        Во-первых, почему вы взяли унылый tracemonkey вместо быстрого V8?
                                                                        node.js же
                                                                        habrahabr.ru/blogs/javascript/71858/

                                                                        Во-вторых, написание _внутреннего_ модуля nginx для сервер-сайд скриптинга это тупиковый путь, потому что nginx — асинхронная FSM, а не тредовое приложение, как апач, поэтому если у вас в коде начнутся длинные локи типа обращения в БД, весь воркер nginx встанет и будет ждать их окончания, что катастрофически скажется на производительности.

                                                                        В nginx уже есть встроенный perl, про который в официальной документации сказано вот что:

                                                                        sysoev.ru/nginx/docs/http/ngx_http_perl_module.html

                                                                        «Если perl'овый модуль выполняет длительную операцию, например, определяет адрес по имени, соединяется с другим сервером, делает запрос к базе данных, то на это время все остальные запросы данного рабочего процесса не будут обрабатываться. Поэтому рекомендуется ограничиться операциями, время исполнения которых короткое и предсказуемое, например, обращение к локальной файловой системе.»

                                                                        По этой же причине кстати для nginx нет промышленного wsgi-модуля для запуска питонокода и много чего ещё.

                                                                        Странно, что люди, прежде чем бросаться писать модули для nginx, не изучают в минимальном объеме то, как эта штука работает.

                                                                        Тут нужно всего-навсего использовать fastcgi и всё сразу станет хорошо.

                                                                          +1
                                                                          У Perl не все хорошо с потокобезопасностью. Как и у v8, кстати. А вот у TraceMonkey все в порядке. И поэтому мне, в идеале, хотелось бы создать модуль с асинхронным handler'ом, который на время выполнения скрипта не блокировал бы рабочий процесс, а спокойно выполнялся бы в отдельном потоке. И я предвижу, что вы скажете, что потоки — это зло, а вот event loop и все такое — это круто… Но, в то же время, вынужден признать, что пока идея с несколькими Javascript-thread'ами — всего лишь идея, и пока она не реализована — уныние мы еще не победили :-)
                                                                            +2
                                                                            Посмотрел на код модуля, несмотря на то, что Си знаю со словарём, проникся.
                                                                            Негоже такой годный проект закопать.

                                                                            Чем не нравится fastcgi?

                                                                            Передербанить его на fastcgi, чтобы был отдельный демон да и пусть живет хоть тредами, хоть процессами — и работать будет как с nginx, так и с любым другим поддерживающим стандарт веб-сервером, апачем например.
                                                                          0
                                                                          почему-то нет сравнения nginx-phpfpm
                                                                          все знают что аппач еще тот тормоз

                                                                          Only users with full accounts can post comments. Log in, please.