Pull to refresh
4
0

User

Send message
Уже который комментарий пишу, и все забываю сказать. Через socket.io есть возможность передавать данные в формате BSON, который в отличии от синхронного JSON, имеет асинхронный по-блоковый алгоритм генерации и парсинга. Другими словами, умеет ReadableStream и WritableStream, прямо как SAX у XML.
У ноды только один рабочий поток

Об этом я в курсе. В моем примере с VK, парсинг страницы, разумеется происходит гораздо быстрее, чем ее закачка. Во время закачки CPU простаивает. При этом процесс остается запущенным, данные для работы уже загружены в память. Было бы глупо скачивать VK в 1 поток/процесс. В разное время ситуация со скоростью доступа к VK меняется. Необходимо контролировать несколько параметров, вызывать события контроля чисел потоков/процессов при пробивании min-max-лимитов.

Я не утверждаю, что socket.io будет магически-быстрее или менее затратным по ресурсам. Можно же просто следить за пулами процессов, чтобы они не перегружали друг друга и при этом работали на максимуме своих возможностей?

Пишу комментарии для того, чтобы выяснить сколько % профита принесло Вам ваше решение.
Во времена пиратского Delphi 7, помню целые dvd-диски с компонентами к нему. Никто не заставлял использовать VCL. Причем, было все равно, на чем был написан распространяемый уже откомпилированным модуль/компонент. Если это .obj, то для использования хватит и заголовочника .h. А если .dll, структура модуля хранится уже в самом .dll.

Я начинал изучать программирование с C. С появлением на моем компьютере Windows 95, стал изучать CBuilder3. — Вот это была жесть! Позже, года через 3, в институте освоил Delphi. Так до сих пор жалею, что не пересел на него раньше. Ну, а после института купил iBook G4, и на этом моя работа с продуктами Borland завершилась.

Pascal — отличный для обучения язык. Должны же существовать языки с низким порогом вхождения. Сейчас и так тяжело найти нормального программиста на C++. Если всех новичков обучать с C++, — это, грубо говоря, понижает среднестатистический IQ общества программистов C++. И вы думаете, будет принципиально больше специалистов? Думаете, станет легче найти сеньоров С++? Как по мне, так станет еще сложнее.
Откуда такое негодование к популярному Pascal?

Понятное дело, что раз его изучают новички, на этом ЯП по статистике всегда будет максимальное количество говнокода.
Но! Это не проблема самого Pascal. Вполне лаконичный ЯП.

Существует и активно-развиваемый Free Pascal.

И вы можете использовать любые компоненты от VCL и .NET до любых кросс-платформенных. Какие компоненты вы используете — не зависит от ЯП.

Есть еще свободное подобие Delphi — Lazarus.

PS Я на Pascal давно ничего не программирую. Но я никогда не отговаривал новичков от этого славного ЯП.

Вы поймите, если все будут изучать программирование с таких ЯП как C++, JavaScript, Python, Java, сразу же весь говнокод из Паскаля и Delphi перетечёт в говнокод C++, JavaScript, Python, Java. — Кто от этого выиграет непонятно: работник или работодатель?
Да, еще одно замечание автору. Не совсем по теме статьи, но я посчитал полезным и оставлю здесь.

В исполняемом скрипте SailsJS app.js Вы обернули код в конструкцию:
(function(){
})()

Данность явно указывает на то, что javascript вы знаете по front-end-у.

Такая конструкция уместна для изоляции переменных и прочего кода в браузерах, так как все скрипты работают с одной областью видимости window.
В Node.JS каждый модуль запускается в собственной области видимости module. Такая обертка у чисто серверного скрипта выглядит весьма странно.

Гораздо большего эффекта можно добиться, например, от strict-режима, чего в ваших скриптах не наблюдается:
'use strict';
Кэширование тоже бывает разным.

Платформы тоже могут быть по-разному настроены. В NodeJS есть возможность загрузить какие-то данные в память один раз и пользоваться этими данными при выдаче каждой страницы. В php такое возможно лишь с использованием memcached и их аналогов. Существует также LRU-cache — это как кэш кэша. Значения наиболее популярных блоков памяти хранятся в одном массиве для наиболее быстрого доступа к ним.
Также, результаты могут отличаться как в лучшую, так и в худшую стороны, если php будет запускаться с какими-нибудь ioncube, zend optimizer, eAccelerator.
Для сравнительных тестов NodeJS, Ruby и PHP было бы справедливо суммировать затраченную память и CPU-time всех PHP-процессов и всех процессов вебсервера — Apache или Nginx или что-то еще (вы не указали).
Советую проводить нагрузочные тесты вот этой утилитой:
httpd.apache.org/docs/2.0/programs/ab.html
Загляните в исходники тестов, там имелся в виду тест простого алгоритма вычисления pi.
Конечно, M_PI и Math.PI это константы, и никто не собирался их рассчитывать в продакшене.
Суть в том, чтобы запустить один и тот же алгоритм на разных языках/платформах.
Всё тестировалось без кэширования. При включенном кэшировании данные, конечно же, несколько другие, но картины не меняют.

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

Столбик Memory consumption во второй таблице немного непонятен.
В случае с Laravel и Yii, как я понимаю, показывает heap процесса после отработанной генерации одной странички.
А в случае с Rails и SailsJS Вы показываете heap всего сервера.
Что из этого следует? Если, например, запустить одновременно 10 потоков генерации странички Laravel, то объем общей занятой памяти на тестируемый момент будет 19.32 × 10 = 193.2Mb. В этих же условиях, не факт что Rails и SailsJS принципиально увеличат объем занятой памяти.
В вопросе о web-виджетах нет однозначного ответа, что лучше использовать: Canvas или CSS Transforms.
Вопрос можно ставить на стадии проектирования. Тут предлагают реализацию. А почему сделано так, а не иначе — можно рассуждать бесконечно.
Мне тоже ближе CSS Transforms. Но лет 20 назад писал подобное на QBASIC. Там как раз для отрисовки использовал все формулы как автор один-в-один.
Дело в том, что сам по себе socket.io обещал давать неплохие результаты при использовании тысяч различных постоянных соединений.
В основном, речь идет о клиентах как браузеров. Но, как я понимаю, ваша проблема проявлялась в виде блокировок event-loop в процессе сервера.
Ну, и не даром в minimum-rpc используют socket.io вместо, например, стандартных http или process.send().

Интересно было бы посмотреть на сравнительные результаты.

Возможно, также проблема решения со 100 процессами и process.send() могла заключаться в том, что каждый процесс выполнял слишком мало задач и сразу завершался. Из статьи неизвестно, как организован пулл процессов. Вы запускали 100 процессов и потом раздавали им задачи, или Вы организовывали пулл, который запускает 100 одновременных процессов, и каждый процесс выполнял одну или несколько задач и завершался, а на месте завершенного процесса пуллом запускался новый?

По моему скромному мнению, второй способ предпочтительнее, более защищен от утечек, защищен от различных необработанных исключений. Но тут надо понимать, что каждый новый процесс кушает при запуске довольно много CPU-time, и нужно соблюдать пропорцию, хотя бы:
Runtime_CPU_time * Proc_count < Execute_CPU_time, где:
  • Runtime_CPU_time — это количество затраченного CPU-time для запуска процесса;
  • Execute_CPU_time — это сумма затраченного CPU-time для выполнения всех задач порученных одному процессу;
  • Proc_count — количество одновременно запущенных процессов.

Если проблема 100 процессов заключалась в I/O, то тут необходимы испытания на разных версиях ядер ОС. Пробовали ли Вы запускать тесты на FreeBSD? Сомневаюсь, что проблема производительности process.send() упирается в I/O. Всегда есть вариант разгрузить количество (частоту) использования process.send() и объем информации, передаваемой через process.send(), в пользу самостоятельной загрузки данных процессом и последующим самостоятельным сохранением результатов.

Сколько раз сам использовал process.send(), с Вашими трудностями я не сталкивался. Правда, в последний раз это было давно, так я использовал для запуска тех скриптов NodeJS версий 0.6.x (если мне не изменяет память).

Как-то, в свое время, мне необходимо было написать парсер VK для расчетов различных статистических данных. На самом деле, действие происходило чуть позднее новости о том, что Яндекс стал индексировать VK. Необходимо было использовать максимум доступных ресурсов для обработки максимального объема информации за ограниченное время. На тот момент, располагали тремя арендованными в ЦОД серверами с различными характеристиками.

Я использовал комбинированный подход, то есть, master-процесс запускал несколько worker-процессов, каждый из которых выполнял задачи в несколько потоков. Причем, для использования максимума свободных ресурсов, master-процесс в процессе выполнения руководил количеством одновременно запущенных процессов и количеством потоков в каждом worker-процессе. Master-процесс различал несколько состояний ОС: если весь chain процессов превышал общий Memory_limit, master-процесс уменьшал количество процессов и увеличивал количество потоков; если worker-процессы превышали CPU_limit, он увеличивал количество процессов и уменьшал количество потоков в каждом процессе. Также master-процесс останавливал перегруженные и idle процессы.

Для реализации использовал простые инструменты:
  • для запуска worker-процессов использовал child_process.spawn() (позднее появился Cluster);
  • для передачи данных между процессами использовал process.send();
  • для выполнения задач в несколько потоков использовал async.queue() модуля async.

Возможно, последние версии NodeJS перегружены функционалом. В те времена V8 умел использовать только 32-битную архитектуру ОС. Опять же, если мне не изменяет память, свеже-запущенный процесс node занимал 1.8Мб оперативной памяти, а процесс с запущенным парсером html-страниц занимал памяти около 15Мб и точно не более 32Мб (был индивидуальный heap-лимит, превышая который, процесс считался зависшим и перезапускался).
Довольно поздно прочитал Вашу статью.
Хотелось бы уточнить, пробовали ли что-нибудь наподобие https://github.com/plaidev/minimum-rpc?
Нашел модуль с очень компактный код. Там поднимается WebSocket-сервер на основе socket.io, ну, и, соответственно, используется WebSocket-клиент.
Хотелось бы, попросить Вас провести бенчмарк того же minimum-rpc с условиями бенчмарков, которые вы описывали в статье.
Две версии call в одном namespace сделать просто не получится, выдаст ошибку.
У JS нет как таковых типов данных, переменные могут менять типы данных по ходу выполнения программы.

Если мы можем создать несколько методов call в JAVA или C++:
void B::call(int year)
void B::call(String year)

в JS мы можем создать один метод или просто функцию
call(year);

Например для простоты эксперимента:
function call(year){
   if(typeof year == 'string') {
      year = parseInt(year);
   }
   return year;
}


Тогда:
call(2016); // вернет => 2016
call("2016"); // также => 2016
call(); // теперь => undefined
call(2005, 2016); // и опять => 2005

При этом все вызовы с точки зрения JS верны.
На Yii в node.js похож фреймворк Keystone.
3 минуты на генерацию сайта. Накидать модели и шаблоны jade. — не больше 2 часов освоения.
Хотелось бы обратиться к автору.
Этих magnet-хостингов вагон и тележка тысячи онлайном по всему миру. Все заблокировать в РФ не получится. И попросить удалить раздачу, например, с китайского трекера сложно, там местный админ не понимает ни русский ни английский.
На вашем месте, я бы потратил часть новогодних каникул на изучение node.js.
О Popcorn уже не раз писалось на хабре.
Если вам не все равно, адаптируйте пожалуйста туда нормальное отображение описания видео и рейтингов или даже поиск по рейтингам.
Поисковые провайдеры туда вроде как подключаются легко.
Я считаю, что mysql для этого избыточна.

Для такой задачи и PHP избыточен. Дожили. Чтобы найти что-нибудь на rutracker, надо научиться поднимать LAMP. Решение с PHP непрактично ни в каком виде. А так, пользуюсь поиском по DHT прямо в клиенте qBittorrent, оттуда же начинаю воспроизведение видео потоком. Не знаю, ищет ли qBittorrent конкретно раздачи rutracker, но все популярное и почти все непопулярное (например, пиратские копии баз maxmind или пиратский КонсультантПлюс).
Я не делаю никаких реклам, просто привожу пример как «непопулярных» раздач.
Он доступен, но не в виде перегруженной функции, если вызывать так:
newYearGreeter.doGreeting(123)

мы попадем в тот же самый метод, и сколько будет передано параметров, разницы нет никакой, т.к. в теле метода аргументы не обрабатываются.
По идее, метод c параметром доступен как-то так:
newYearGreeter.prototype.prototype.doGreeting.call(newYearGreeter, 2016);

Проверять некогда, улетаю.
Еще, чтобы на смарт-тв работало. И воспроизводило видео без полной загрузки. Прямо как в Popcorntime
В JS с этим есть кое-какая свобода. Нет интерфейсов (как в Java), которые необходимо соблюдать. Ровно как и типов данных при определении классов или функций, если критичен тип значения, проверяется вручную в теле функции.
В JS еще и не такое возможно. У NewYearGreeter#doGreeting() здесь нет параметров, но мог бы быть, например, один, но совсем другого назначения, либо даже два или, вообще, переменное множество.
Greeter#doGreeting() объявлен с параметром.
NewYearGreeter наследуется от Greeter и является дочерним по отношению к нему.
NewYearGreeter#doGreeting() объявлен без параметров.

Внутри собственного кода NewYearGreeter#doGreeting() вызывает Greeter#doGreeting() вот этой строкой super.doGreeting(newYearMsg); — вызов с параметром.

Еще что непонятно?

Information

Rating
Does not participate
Registered
Activity