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

Там реализована загрузка файлов только по настоящему, с сохранением в файл потому что это тоже вообщем-то не тривиально с event-based I/O
0
Здорово!
Еще одна тема для «подумать» — интересно, Node.js, у которого разбор request body написан на Javascript, будет ли сравним по скорости с кодом на Си? С учетом того, что виртуальная машина v8 очень и очень даже быстрая — может быть, и не имеет смысла усилия тратить на низкоуровневое программирование правда :-)
0
Мне там нравятся события для файлов. Если присылают 5 файлов одним пакетом, их можно обрабатывать по мере прибытия, не дожидаясь загрузки всего multipart-запроса.
+2
А можно взглянуть на скрипты, скорость которых собственно измеряли?
0
Скрипты, которые тестировались — это обычные «Hello, World!» на PHP и на Javascript (каждый из одной команды). Я не стал сравнивать более сложные программы, потому что тогда на скорость работы влияли бы еще другие факторы: внутренняя реализация арифметики, циклов, функций, работы с памятью, и т.д. в PHP и Javascript. Это, согласитесь, тема отдельного обсуждения (не менее интересная, впрочем).
0
В таком случае интересно взглянуть на аргументы ./configure при компиляции PHP. Его скорость крайне от них зависит. Чем больше лишнего (не нужного для Hello World страницы) вы туда засунете, тем медленнее будет его работа.
+11
И еще вопрос… Почему вы сравниваете nginx+js с apache+php, а не с nginx+php?
-11
Вот вы зануда!!! Челоек ночамине спал, в товрем якогда все делают велосипеды, он изобретал смокат.
А вы его тролите такими деталями.
+1
Детали всегда интересны :-)
А потом, качественно сделанный самокат с возможностью доработки до чего-то более цивильного — он ведь может и получше китайского велосипеда. Метафора, ессно…
+1
nginx+php я видел в двух вариантах: apache+php+nginx в качестве reverse-proxy (самые простые мои тесты показали, что минимальные скрипты в такой реализации работают в несколько раз медленнее, чем просто apache+php, что и понятно — тесты были на локальном компьютере, без учета скорости сети), и nginx+php как fastcgi. Сравнить действительно было бы интересно (и, скорее всего, я даже этим займусь), но вот некоторое предубеждение против php, установленного как fastcgi, у меня есть. Неспроста я упомянул про 502 ошибку сервера, которая возникает при сбоях в fastcgi-процессах.
Хотя, не исключаю, что мои знания в этой области уже устарели, и сейчас все используют fastcgi без особых проблем.
0
> Корректная работа в multi-thread условиях
Может ли рабочий процесс иметь одновременно несколько тредов, в каждом из которых выполняется скрипт?
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
ну DLR все же еще в бете и кроме того сильно медленнее CLR по определению. но все равно спасибо.
UFO landed and left these words here
+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
Согласен, это интересная задача. Но когда я думаю о том, какой это необъятный объем работы — у меня прямо руки опускаются… И все «бонусы» теряют свою привлекательность :-)
0
Кстати, если использовать CouchDB, там можно писать запросы (фильтры) на Javascript :) Будет вообще красиво :)
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? насколько я знаю, последний значительно быстрее. Я ошибаюсь?
+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
На самом деле, вопрос «кривости» ООП — это тот еще вопрос :-).
Раньше мне нравился PHP (когда он был еще 4). Потому что все трюки, которые можно было сделать в плане ООП — они все документированы официально. Потом появился PHP 5 и он показался мне еще более продвинутым. Но когда я увидел ООП в других языках…
— Java — хрестоматийный пример, все объектно-ориентировано, люди очень хорошо думают над дизайном классов. Но, блин, писать небольшие скриптики и постоянно думать, а не слишком ли фигово я классы назвал — это ж кошмар!
— Python — все супер, огромная standard library, но ведь тоже что-то не устраивает! А тут еще и переход на Python 3…
— Ruby — это просто ООП будущего, отличный язык… Но тут мне попадается на глаза вот эта статья, и мне как-то страшно на этом языке писать реальные программы…
— Javascript — всего по минимуму, но, в то же время, ощущение легкости и полноты. А тут еще оказывается, что server-side javascript появился относительно недавно, и есть над чим поработать…
— C++ не рассматриваю для веб-программирования уж :-)
Ну и, по сравнению со всем этим разнообразием, попытки PHP обновить свой язык, добавить в него (наконец-то!) юникод, нормальные inline-функции, и т.п., выглядят просто (извините) жалкими. А вы говорите про кривой Javascript :-)
+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, если нативной реализации нет. На сервере, наверное, даже прослойка не нужна, т.к. интерпретатор выбираешь сам.
+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 those users with full accounts are able to leave comments.  , please.