2000 часов в одиночестве, или как был сделан RSS reader / Я робокоп

    I. Am. Robocop.Всем привет,

    Собираюсь поделиться с вами технической стороной того, как я за 16 недель сделал новый вебовый rss ридер, и чуть не сошел с ума.
    Отходя от долгой предыстории, будем считать, что все началось в феврале этого года, когда мы с Дэвидом (dmiloshev, UI-дизайнер) решили сделать прототип нашего детища вдвоем.
    «В одиночестве» — потому, что не было никаких скрамов, совещаний, «коллективного разума», а всю техническую часть, довелось делать самому.

    Если бы меня попросили описать всю статью в одном предложении, то получилось бы:
    No-SQL, mongodb, node.js, фак мой мозг, Evented I/O, очереди, выводы, git, nginx, memcached, Google Reader, Atom, TTL, PHP, ZF, jQuery, выводы.

    I. Технологии


    1. PHP/ZendFramework + кое-что еще
    Все, что я имел с самого начала, это небольшой каркас, делающий работу с zf слегка удобней. В нем Dependency Injection, Table Data Gateway, Transfer Object, более удобная работа с конфигами, настроенный Phing с уже прописанными тасками почти на все случаи жизни. В общем, работать с этим всем весьма приятно.

    Архитектурно php приложение состоит из следующих слоев:
    1. Routing/Controller/View — понятно..
    2. Service — тут ACL, валидация, кэширование, логгинг. К нему можно спокойно прикрутить REST и будет отличный API.
    3. Gateway — тело бизнес-логики. У каждой сущности в системе свой gateway. Абсолютно абстрагирован от БД.
    4. Mapper — тут, собственно, прямая работа с базой.
    Еще несколько моментов, о которых я старался помнить при проектировании:
    • KISS
    • Без велосипедов
    • Любая логическая часть системы должна иметь возможность масштабироваться горизонтально
    • Все процедуры, имеющие дело с внешними источниками, должны выполняться в фоновом режиме и не морозить пользователю интерфейс
    • Любой хай-лоад должен упираться в очередь, процессорную мощность и таймауты, а не в количество процессов, либо открытых соединений
    • Любые данные можно восстановить
    • Протоколировать нужно абсолютно все, не только ошибки
    • «Это можно закэшировать»
    • Дэвид: «Нужно, чтобы эта плашка была на 1 пиксель левее..» =)

    2. nginx без комментариев

    3. git Когда-то дал понять, что я не такой умный, как мне казалось.

    4. Mongodb
    Ранее мы использовали его на продакшн в другом проекте, но весьма осторожно, поэтому так и не удалось его опробовать по полной. В последнее время особо сильно развивается мода No-SQL, шардинга, map-reduce и No-SPOF. Решил я, пора уже вылазить из своих детских штанишек. По крайней мере, это очень сильно разбавило общую рутину и слегка меня встряхнуло.
    Документация у ребят очень подробная, по этому вникнуть во всю глубину mongodb получилось за первые две недели. Пришлось слегка вывернуть на изнанку свой мозг после лет работы с реляционными бд. Но все нетривиальные задачи получалось решать самостоятельно, не прибегая к задаванию вопросов на форумах.
    Слегка побаиваюсь его запуска на продакшн. Чтобы быть в курсе возможных проблем, регулярно читаю группы, изучаю вопросы, с которыми сталкиваются другие люди.
    На данный момент, он настроен как master-master, который поддерживается не полноценно, но в нашем случае должен работать как надо. В дальнейшем будем шардить, и это будет однозначно легче, чем с той же mysql.

    5. Memcached
    Нечего тут сказать. Простой как дверь. Разве что, в дальнейшем хочу его попробовать на UDP… просто по приколу.

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

    7. node.js
    Вот это, наверное, самое интересное, что со мной произошло за эти четыре месяца. Серверный Evented I/O очень возбуждает, даже больше чем дифференциал. Сразу захотелось под настроение весь php переписать на ruby. Вот такие у меня мечты.
    Дело в том, что я ее обнаружил совсем недавно и совсем случайно. После чего довольно много вещей стали на свои места, как в самой системе, так и у меня в голове. Переписать пришлось довольно много, зато результат очень радует душу, и, надеюсь, порадует будущих пользователей.
    Выкурил до фильтра вот эту страницу, на данный момент использую: mongoose, kiwi, step, memcache, streamlogger, hashlib, consolelog, eyes, daemon
    Из своих библиотек написал jsonsocket, который, по моему, говорит сам за себя. Руки не доходят его github-нуть. И вот уже мечтаю из него сделать bsonsocket. Конечно же, пришлось написать штуки для работы с очередями, и прослойку для работы с Gateway слоем в php (об этом потом).
    Еще добавил prowl, теперь бекграунд шлет мне push сообщением на телефон случайные цитаты из башорга раз в час (заодно и небольшую статистику в виде memory usage, etc.)
    Многие библиотеки (модули) очень сырые, по этому, иногда приходилось править руками прямо в чужом коде (времени нет патчи делать). А уважаемые господа node.js какали на backward-compatibility, по этому, можно часто встретить просто не работающие библиотеки.

    8. jQuery
    Для меня это уже почти синоним клиентсайдового javascript.
    Используемые плагины: blockUI, validate, form, tooltip, hotkeys, easing, scrollTo, text-overflow и еще парочку мелких.

    II. Разработка


    Не буду углубляться в специфику самого сервиса, технически, это почти Google Reader (GR).
    Пока Дэвид «водил» серыми квадратиками по фотошопу, думая о бизнес-логике, я начал с базового моделирования, после чего сразу перешел к системе выкачки фидов.

    1. Feed Pull

    Казалось бы, тут все просто — дергаем адрес, выкачиваем xml, парсим, пишем в базу. Но есть нюансы.
    • Каждый фид нужно уникально идентифицировать, чтобы иметь возможность сохранить его в системе
    • Так же, нужно идентифицировать каждую запись, чтобы избежать дубликатов
    • Поддержка таких вещей, как if-modified-since и etag
    • Обработка редиректов
    • Разные версии RSS/Atom
    • Расширения различных сервисов, например gr:date-published
    • HTML внутри каждой записи нужно чистить, но не полностью, оставляя хорошие теги, фильтруя всякую ересь
    • Поиск и обработка иконки оказалось не самым приятным занятием… например, livejournal не отдает content-type, приходится использовать magic.mime
    • Спецификацию, по всей видимости, мало кто читает, по этому xml может быть не валидным, или СОВСЕМ не валидным
    Выводы:
    Внешние источники очень разные, многие просто плевали на стандарты. А еще им нельзя доверять — валидация контента должна быть такая же строгая, как и при взаимодействии с пользователем.
    Идеальный код не получился. Он оброс множеством условий и исключений.
    Каждый пункт отнял немало времени. Больше, чем может показаться с первого взгляда.

    2. Обновлялка

    Теперь хотелось бы, чтобы все существующие потоки обновлялись автоматически. При чем, желательно, чтобы учитывался TTL (частота обновления) каждого отдельного потока. А еще хотелось бы этот TTL размазать по времени суток. Полагаться на в протоколе я не стал, поскольку по моим исследованиям — либо его нет вовсе, либо он не соответствует действительности. Так или иначе, его не достаточно.

    Начал думать над собственной системой определения частоты обновления потоков, и вот, что получилось:
    • TTL — среднее временное расстояние в секундах между записями в потоке в течение часа (минимум 2 минуты, максимум 1 час)
    • Каждый поток имеет список средних TTL на каждый из 24 часов за последние 10 дней
    • На основе фактических данных за последние 10 дней, формируется прогноз на следующий день, который представляет средние значения TTL на каждый час
    • При каждом обновлении потока, система пересчитывает его средний фактический TTL за текущий час (0-23)
    Итак, допустим, чтобы система обновляла некий поток в обеденное время каждые 2 минуты, ему нужно в течение 10 дней регулярно именно в этот промежуток времени делать соответствующие обновления. До этого момента, система будет плавно адаптироваться и обновлять его все чаще и чаще. А, например, в ночное время, этот поток будет обновляться раз в час.

    Собственно, сама процедура обновления — это ранее описанный Feed Pull, которому, как бэ все равно, что обновлять.
    И тут мы плавно понимаем, что хотелось бы все это натянуть на очередь. Но про их организацию я расскажу чуть позже.

    Кстати, в планах прикрутить PubSub, а так же, запустить свой хаб.

    3. Discovery

    Однозначно, в список умений удобного rss ридера должен входить поиск rss/atom фидов на любой html странице. Когда пользователь просто вбивает адрес сайта (например, www.pravda.ru), система должна пойти и поискать там, собственно, фиды, на которые можно его подписать.

    Но эта процедура усложняется тем, что такие вещи нельзя делать прямо в запросе пользователя, поскольку это вовсе не задача веб-сервера — это нужно делать асинхронно. По запросу пользователя, мы сначала проверяем напрямую, существует ли такой поток в базе, потом смотрим в discovery кеш (который живет 2 часа), и если ничего не нашли, то кладем это дело в очередь и ждем максимум 5 секунд (о том, как именно ждем, расскажу позже). Если в течение этого времени задача не успела выполниться, мы завершаем сценарий, возвращая json в стиле {wait:true}. После чего, через некоторый таймаут, клиентсайд обращается с тем же запросом на сервер. Как только задача будет доделана на бекграунде, ее результат окажется в discovery кеше.

    Несколько нюансов, связанных с данной процедурой:
    • Разные кодировки — иногда кодировка не указана ни в заголовках, ни в шапке… приходится определять ее побайтово (что не всегда работает)
    • На одной странице может быть два идентичных фида, один RSS другой Atom — в такой ситуации нужно выбрать один из них
    • Нужно дополнительно запрашивать каждый из фидов, дабы убедиться, что он работает, и взять истинный его title и description
    • Редиректы
    • Иконки (те же проблемы)
    • Стандарты и валидность (the same)
    Вот эту часть я считаю довольно сырой, поскольку мы пытаемся сделать сервис для людей, которые не обязаны знать, что такое RSS или Atom. Например, если я, как самый обычный пользователь, вдруг захочу подписаться на мой любимый и единственный vkontakte.ru, то увижу я дулю с черничным вареньем. Как минимум, в дальнейшем хотим реализовать что-то а ля gr generated feed. Как больше, чем минимум, сделаем удобный, человеческий поиск.
    Кстати, нередко встречается, что конкретно на данной странице нету alternate-ов, а где-то на других страницах этого же сайта — есть. Появилась мысль написать бекргаундный crawler, который будет себе тихонько искать rss/atom потоки на тех сайтах, которые часто вводятся пользователями.

    Выводы:
    Когда имеешь дело со внешними источниками разного типа, такое ощущение, что копаешься в гигантской мусорке в поисках случайно выброшенного документа.
    Требует конкретной доработки. С точки зрения юзабилити, простого поиска alternate-ов на данной странице не достаточно. Нужно делать нечто более универсальное.

    4. Интерфейс

    Следующее, чего очень захотелось, это увидеть интерфейс, где я мог бы подписаться на какой-нибудь поток, добавить его как закладку в левую колонку, клацать и читать его содержимое.
    Не буду углубляться в детали реализации интерфейсов, хочу только сказать, что всю верстку и ui делал сам. Это было очень не рентабельно и отвлекало от других задач. Зато jquery сэкономил время.
    На читалку и общий интерфейс я потратил, в общей сложности, две недели (это если не считать довольно напряжных доработок и переделок в дальнейшем). После чего, мы получили уже довольно милую игрушку, которая засветилась на наших мониторах, радуя глаза и душу.

    Папки
    Мы, конечно, минимальные ребята, но без папок я не могу себе представить работу с ридером. И, извините господа, в Google Reader их юзабилити оставляет желать лучшего. Постарались их реализовать максимально доступно и просто.
    Но уж не думал, что технически это может оказаться такой проблемой. Интерфейс интерфейсом, а на сервер-сайде мне пришлось довольно сильно поднапрячься, чтобы это работало так как надо — см. следующий пункт.

    По возможности старался использовать css спрайты (там, где получалось).
    Весь js и css собираются в один файл, минифицируется и сжимается gzip-ом. Средняя страница (со всей статикой) весит 300кб. С кешем — 100кб.
    А для ie6 у нас есть специальная страница.

    Выводы:
    Сам интерфейс выглядит очень легко, но я бы не сказал то же самое про его реализацию.
    В конечном итоге, когда все сжато и выключен firebug, работает шустро.
    Всего я насчитал 28 экранов на данный момент, и миллион usecase-ов.

    5. Прочитанные / непрочитанные записи

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

    Для каждого пользователя хранится дата последнего обновления его счетчиков — для всех потоков, на которые он подписан.
    При обновлении пользователем страницы, система находит количество новых записей по каждому потоку, которые появились позже, чем эта дата, и добавляет его к количеству непрочитанных (простой инкремент). При прочтении пользователем любой записи, происходит простой декремент.

    Выборка непрочитанных записей по отдельному потоку тоже весьма простая.

    Но вот выбрать только непрочитанное в папке — это уже проблема. Не хочу уточнять нюансы, но это связано с тем, что join-ов в mongodb попросту нет. Простым запросом или несколькими — это нельзя решить, только через CodeWScope. Индексировать это невозможно, масштабировать — m/r. На данный момент это потенциально узкое место.

    5.1. Непрочитанное сверху

    Если кто-то из вас пользовался Google Reader, то наверняка знаете о функции «смотреть только непрочитанное». Так вот, если в потоке не остается записей, которые вы не читали — вы смотрите на пустую страницу. Сначала мы тоже сделали именно так, но тестирование показало, что пользователи даже не догадываются, что у них включена эта функция. Они не понимают, почему поток пустой, почему на нем нет записей, и куда они деваются.
    Дэвид предложил очень интересное решение, где непрочитанные записи просто оказываются сверху, а прочитанные уходят вниз. И это стоило мне нескольких дней ломания мозга над тем, как это оптимально реализовать, именно в папках.

    Выводы:
    No-SQL хорош с точки зрения скорости и масштабируемости. Но некоторые, казалось бы, тривиальные вещи, с ним оказалось сделать довольно сложно.
    Денормализация это добро. Не нужно считать проблемой то, что собьется какой-нибудь счетчик. Но на любые денормализованные данные нужно иметь функцию полного пересчета (на бекграунде, естественно).
    M/R в mongodb еще сырой для продакшна. После небольшого тестирования оказалось, что он блокирует все к чертям во время работы. В версии 1.6 разработчики обещают его улучшить. Пока что обошелся без него.
    Schema-less решает.

    8. Sharing

    Это функция, позволяющая зашейрить любую запись из читаемого потока на свою страницу. Коротко, это означает, что любой авторитетный парень А, читая разные фиды, мгновенно может сохранять конкретные записи (конечно, самые интересные и полезные) в свой поток(и) — похоже на Shared Items в GR. А у других пользователей есть возможность прямой подписки на его «Shared Items» поток, так же, как и на любой фид.

    Одна из основных концепций нашего сервиса — удобное распространение информации. Довольно интересной с технической точки зрения задачей для меня было реализовать построение цепочек шейринга. Очень помог mongodb с его schema-less свойствами.

    Интересный момент:
    Недавно Google анонсировал новую фичу ReShare в Buzz. Так вот в этой статье (по ссылке), там где «A little more background», я наткнулся на пункты, которые мы с Дэвидом плотно обсуждали 4 месяца назад, при чем, пришли к тем же выводам. Наша реализация шейринга очень близка.

    9. Node.js, background, очереди

    Изначально демоны были написаны на PHP, при чем, весьма криво. И, не считая mongodb, это было самым стремным для меня местом в приложении, поскольку эрэнэр не предназначен для таких вещей.
    Но когда я наткнулся на node.js (это было всего две недели назад), моя душа запела, и я снова смог «неспать» спокойно. Но делема заключалась в том, что переписывать на него весь бекграундный код, который уже был реализован на PHP (feed-pull, discovery, feed-info) — было совсем не время.
    Весьма недолгое ковыряние в возможностях node меня привело к компромиссному решению — child-process.

    9.1. Queue Manager

    Это первый node демон. Его задача — читать очереди, раздавать задачи воркерам и отслеживать процесс их работы.
    • Один менеджер может обслуживать много очередей
    • Менеджеров в системе может быть запущено сколько угодно, по одному на сервер
    • Каждый может быть сконфигурирован по своему, например, разные менеджеры могут работать с разным набором очередей
    • Конфигурация очередей может отличаться и имеет следующие параметры
      • Максимальное количество одновременно работающих воркеров (фактическое количество регулируется в зависимости от нагрузки)
      • Размер буфера задач (нужно настраивать в зависимости от типа задачи и количества воркеров)
      • Максимальное время простоя воркера (автоматически убивает и освобождает память в случае простоя)
      • Максимальное время жизни воркера (если это php-cli, не стоит ему жить долго, лучше иногда перезапускать)
      • Максимальный memory usage у воркера (как только превышает, убиваем)
      • Таймаут на выполнение задачи (если воркер залип во время выполнения задачи, убиваем его, возвращаем задачу в очередь)
      • Количество раз, которое задача может сфейлиться
    • Когда задача выбирается из очереди, на нее ставится Lock (для блокировок используется memcache)
    • Если задача имеет результат, он будет сохранен в memcache
    • Для каждой очереди есть свой worker, это должен быть js класс с определенным интерфейсом
      • На данный момент работает только один такой — import (про него дальше будет)
    • Так же, существует WorkerPhp.js, который запускает php-cli как child-process и общается с ним на json
      • Жизнь такого воркера (процесса) не заканчивается на выполнении одной задачи — он может из выполнять поочередно, пока менеджер не увидит, что тот заметно «растолстел» и не уволит его
      • На практике, больше чем 4 php процесса на очередь одновременно не запускается
    • Понимает POSIX сигналы
    • В случае корректного завершения (не kill -9) аккуратно возвращает все выполняемые задачи из памяти обратно в очередь
    • Каждый менеджер открывает порт с REPL интерфейсом, на него можно зайти и спросить, как дела. Так же, можно без перезагрузки на лету менять его конфигурацию.
    Кстати, любой uncaught exception ложит только один поток, но не весь процесс, что не может не радовать.
    И все это — 500 строк кода (с комментариями).

    Выводы:
    Evented I/O — то, как обязаны работать большинство серверных приложений. Блокировка должна быть только там, где она действительно необходима.
    Проксирование php через node показало хорошие результаты и сэкономило время.
    Кучу работы обслуживает всего один процесс (не считая php-cli). JS воркеры работают там же, асинхронно и очень резко.

    9.2. Controller — Publish/Subscribe hub

    Часто бывает, что нужно выполнить балк задач (например, 100) параллельно, да еще и асинхронно. Но очередь — это черная дыра. Отправить туда 100 задач… и даже раз в секунду обращаться в memcache за результатами — накладно.
    Можно еще в обход очереди можно было по сокету обращаться напрямую к менеджеру и просить его выполнить эти задачи, дожидаясь ответа в этом же соединении. Но этот вариант не подходит, так как менеджеров может быть десяток, и мы не знаем, к кому из них можно обратиться… короче, это неправильно.

    И создал я Контроллер (node). Он вообще один на всю систему, при этом, простой как табуретка:
    • Все менеджеры открывают с контроллером постоянное соединение
    • В случае какого-либо результата или фейла любой задачи, менеджер детально сообщает об этом контроллеру
    • К нему можно подключиться «с другой стороны» и подписаться на конкретную задачу или список задач
    • По мере поступления информации о задачах, контроллер оповещает всех подписчиков
    • Если подписчик ожидает много задач, контроллер оповещает его по мере их поступления
    • Есть клиент для PHP (блокирующий)
    • Garbage Collection
    Собственно, именно в процедуре «discovery», которую я описывал выше, PHP сценарий как раз обращается к контроллеру и ожидает результат задачи в течение 5 секунд, после чего, возвращает пользователя в интерфейс.

    Выводы:
    Publish/Subscribe схема очень эффективна в неблокирующих окружениях.
    Стопроцентный результат не обязателен. Если в итоге 5 задач из 100 не выполнились по каким-то причинам, как правило, это не страшно и мы продолжаем работать.

    9.3. Feed-updater (фоновая обновлялка)

    Node процесс, один на всю систему. Периодически обращается в базу, получая список фидов, которые нужно обновить (используя данные TTL), и скидывает их в очередь.

    9.4. Очереди

    Чтобы избежать race-conditions, для каждой задачи формируется уникальный md5 идентификатор. Именно этот идентификатор кладется в очередь, а сами данные этой задачи — в memcached. Потому, что практически все задачи имеют нефиксированный размер, а memcacheq с этим не дружит — и не должна. Когда менеджер берет задачу, он ставит на нее lock, что является тоже записью в memcached. Это позволяет избежать повторного попадания в очередь одинаковых задач непосредственно во время их выполнения.
    Планирую рассмотреть Redis, как альтернативу всему этому, потому что memcached в данном случае используется не по назначению. Если он упадет — потеряется вся очередь.

    Так же, разделил очереди на две группы: юзерские и системные. Первые — в приоритете.
    Это просто привело к добавлению «feed-pull-sys», которая используется фоновой обновлялкой, не мешаясь при этом с пользовательскими задачами.

    Выводы:
    Данная реализация еще очень сырая.
    Очередь должна быть восстанавливаемой при любом падении.
    Нужно использовать более продвинутую систему блокировок — mutex?
    Пользовательские и фоновые процессы должны иметь разный приоритет.

    10. Импорт/Экспорт

    Вот еще один интересный момент, о котором хочется рассказать. Все порядочные ридеры обязаны поддерживать импорт/экспорт в формате OPML. Но дело в том, что некоторые пользователи могут загрузить свой opml с сотней фидов, которых еще нет в нашей системе. И тогда ему придется подождать, пока они все загрузятся. А еще, таких желающих может вполне оказаться десяток одновременно.

    Node спасает. Появился новый воркер под названием «import» (на данный момент может работать до 10 одновременно). После загрузки и валидации opml файлика, php кидает в очередь задачу и возвращает пользователя в интерфейс, к прогресс-бару. Тем временем, «import» подхватывает и разбрасывает более мелкие задачи в очередь «feed-pull», после чего ждет их выполнения от контроллера, параллельно обновляя счетчик. А пользователь видит плавно ползущий прогресс-бар. При чем, он может уйти с этой страницы, погулять, а потом вернуться. Это приятно.

    III. Выводы

    • Не делайте велосипедов. Практически на любую задачу уже существует готовое решение, которое просто нужно слегка адаптировать.
    • Чем проще продукт для пользователя в конечном итоге, тем сложнее его реализация. Потребитель, в прочем, вряд ли это заметит.
    • Не переоценивайте себя. Самостоятельно сделать взрослый продукт «за неделю» не возможно (хотя, не люблю я это слово).
    • Мотивация, все же, временами делает невозможное.
    • Продукт никогда не будет идеален. Работающее приложение — это всегда компромисс между временем и качеством.
    • Если работаешь сам, очень не хватает brainstorminga в команде. Стоит использовать коллективный разум при любой возможности.
    • На переключение контекста тратится много времени. Значительно эффективней, когда один разработчик занимается более однотипными задачами.
    • Если намерены делать свой стартап и продвинуться дальше идеи, забудьте про личную жизнь и пятничное пиво.
    Это только начало, а впереди еще очень много запланированной работы. Включая то, что мы можем назвать инновациями — не побоюсь этого слова. Поэтому, to be continued…

    Параллельно хочу анонсировать полузакрытый запуск на следующей неделе.
    О самом проекте будет написано моим коллегой в другой статье на днях.

    Буду благодарен любым техническим комментариям, советам и конструктивной критике.
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

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

    Комментарии 173

      +14
      Столько информации, много очевидного, мало деталей интересных реализаций. Лучше было бы по частям описывать интересные загогулины и как вы их обошли, и на какие грабли наступили. Но доходчиво. А то галопом по Европам.

      Ну и это… зарекламили статью как презентацию ридера. И где он?
        +4
        Изначально так и начал писать, но получилось слишком растянуто.
        Особо детально описал работу бекграунда и очередей, поскольку считаю это более интересным.

        А вообще, так и хотелось — передать все в общих чертах, не углубляясь сильно в детали. Слишком много для одной статьи.

        Я же сказал, что презентация будет потом, а эта статья несет чисто технический характер…
          +13
          Эта статья несет мало технически интересного. Я использовал strreplace и Smarty, пришлось помучаться с юникодом
            –3
            А Вы до пункта 9 дошли?
        +2
        Прочитал, все, весь текст, облизывался на новый ридер и правда, где он?
          +6
          На следующей неделе анонсируем его на хабре.
            0
            Ждем! Было бы круто, если бы в анонсе описали чем он круче 2 ридер-монстров этого времени — Гугл Ридер и Нетвайбс.
              +2
              Мы очень хорошо изучили рынок, прежде чем делать что-либо (да и во время разработки). Есть еще bloglines, который тоже имеет не маленькую аудиторию с США.

              Опишем.
              • НЛО прилетело и опубликовало эту надпись здесь
                  +37
                  Так я на нем все делал!
                    0
                    Не надо! Уверен — Дениска сделает ридер гораздо-более-лучше.
                    Прямо ждать терпения не хватает =)
                    • НЛО прилетело и опубликовало эту надпись здесь
                0
                Я бы добавил в список Feedly. Для меня это идеал ридера.
                  0
                  Спасибо, обязательно изучим. Выглядит интересно.
                0
                Ждете выходных? :)
            • НЛО прилетело и опубликовало эту надпись здесь
                0
                Поправил, спасибо.
                  0
                  Да, тут зависаешь )
                  +1
                  привет робокопу от Кира ;)
                    +3
                    Привет, Кир!
                      –10
                      От Киры? О_о
                      *Подпись: Петросян*
                      +2
                      Вы прочитали мои мысли и избавили меня от тяжкого бремени делать ридер самому.
                      Впрочем, я бы немного изменил систему подсчета TTL на следующий день, учитывая паттерн, сложившийся на завтрашний день недели и за прошлый месяц.
                      Еще одна очень нужная фишка — генерация RSS из всех фидов в данной папке, этакий миксер потоков.
                      И, пожалуй, как завершение, как вишенка на пирожном, нужна кнопка на любом сайте «добавить RSS-поток с этого сайта в читалку». Маленькая иконка, которая сэкономит время.
                        +1
                        Спасибо.
                        Генерация фида из папки уже работает.

                        По поводу кнопки:
                        Мы будем делать удобный букмарклет. И постараемся, чтобы даже домохозяйка смогла им воспользоваться. Позже.
                        0
                        А про монетизацию использования приложения статья будет? Интересно было бы почитать.
                          +1
                          Про монетизацию мы, скорее всего, писать не будем.
                          Могу сказать, что она будет несколько необычной и очень лояльной к пользователю.
                            +3
                            Ну тогда вдвойне заинтригован :)
                              –1
                              Если сервис бесплатный — то это реклама. Что необычного?)
                                +1
                                Скажите, когда появилась контекстная реклама, она была необычной?
                            +8
                            Скажите, вам не становится страшно когда вы думаете как поддерживать такой зоопарк технологий?
                              +7
                              Становится. Страшно.
                                0
                                Ну что же — удачи! :-)
                                  0
                                  почему было не использовать эрланг? зоопарк действительно дикий, вы бы сэкономили массу времени и сил, при этом система у вас еще сырая, по вашим же словам…
                                    +3
                                    А Вы использовали?
                                      +3
                                      да, оно идеально ложится как раз на связанное с очередями, воркерами, интерактивной отладкой, масштабированием и прочим
                                      кстати, например, для монго есть библиотека
                                      интегрируется с другими языками через безопасные «порты»
                                      я писал кравлер, и после это писать такого рода сервера на чем-лтбо еще видится мне садомазохизмом )
                                        0
                                        Мое знакомство с эрлангом… в общем, мы с ним не подружились.
                                        Слишком неведомое.
                                          –1
                                          Дак приступайте, станете «неспать» спокойно
                                            0
                                            Чем конкретно erlang превосходит node?
                                            (учтите, что у меня уже все на нем реализовано)
                                +2
                                Название конфликтует с лозунгом «Без велосипедов».
                                  +1
                                  Это не копикат. Обоснуем в релизе.
                                  +24
                                  Топик с Того Хабра [х]
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                      0
                                      Ну, по поводу заголовка и велосипедов очень четко подмечено.

                                      Говоря «Rss ридер» я имею ввиду техническую характеристику, а вовсе не специфику проекта. Ведь это разные вещи, верно?
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                        • НЛО прилетело и опубликовало эту надпись здесь
                                          0
                                          Аггрегатор и ридер совсем разные программы. Тут явно много времени было уделено интерфейсу. Но 2000 ч.часов это сильно да. 250 рабочих дней по 8 часов. Если не ошибаюсь Торвальдс ядро линукса быстрее написал
                                            0
                                            Я так понимаю, у Вас за спиной — десяток таких проектов…
                                              0
                                              Это вам у Линуса лучше спросить. Я всего лишь сравнил
                                                0
                                                Ядро линукса и веб приложение совсем разные программы.
                                      0
                                      А как же eventr?
                                        +1
                                        А это мы его замаскировали под rss reader
                                        +2
                                        Когда задача выбирается из очереди, на нее ставится Lock (для блокировок используется memcache)

                                        вот он FAIL
                                          +1
                                          Посоветуйте
                                            +1
                                            Например ново-модный Redis, он поддерживает транзакци
                                              +1
                                              Спасибо, ковырну
                                                0
                                                а это вы не рассматривали? nodejs.ru/362
                                                  +1
                                                  Почитал, очень интересно и просто… и поздно :)
                                                  Спасибо, буду иметь ввиду.

                                                  Очереди переделаю на Redis.
                                                    0
                                                    Почему бы не заточенными решениями типа RabbitMQ (или ZeroMQ если гарантия доставки не важна)?
                                                      0
                                                      AMQP/RabbitMQ — по мне так хорошее решение для очередей.

                                                      Очень надёжное и быстрое, используем много где.

                                                      Кстати, есть github.com/ry/node-amqp
                                                        0
                                                        Уже переделал все на Redis:
                                                        lists, distributed Locks, pub/sub

                                                        Очень удобно все получилось.
                                                          0
                                                          Анонс то когда?
                                                            0
                                                            Послезавтра.

                                                            Тяжко деплоимся :)
                                                              0
                                                              Ждём с нетерпением! Удачи!
                                                  0
                                                  Только это не привычные по rdbms транзакции, а скорее балковое исполнение команд.
                                                    +1
                                                    Как раз то, что нужно
                                                    0
                                                    code.google.com/p/redis/wiki/PublishSubscribe

                                                    Это случайно не заменит мой node controller?
                                                      0
                                                      Как сервер сообщений можно использвать.
                                                +4
                                                В свое время 5 лет назад на заре расцвета AJAX писал RSS-ридер для нашего портала — rss.i.ua
                                                Поэтому проблемы с тем, что приходит в RSS-потоке и в каком виде — нуууу очень понимаю :)))) Костылей там приходится очень много повставлять.
                                                  0
                                                  мне больше всего в вашем сообщении понравился домен i.ua :-)
                                                    +1
                                                    Спасибо. Видно, понимаете, о чем шла речь :)
                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                        +1
                                                        По этому поводу у нас в фан-клубе есть футболка с высказыванием Зигмунда Фрейда:

                                                        +2
                                                        Прочитал домен со второго раза. Первый раз прочитал как «russia»:-)
                                                        –13
                                                        меня напрягает такое обилие слэнга (зачастую сугубо индивидуального, видимо) — это добавляет неоправданной сложности. часто это является следствием того, что желание похвастаться довлеет над желанием поделиться знанием.

                                                        а так ниче. раскрыты некоторые грабли которые нас ждут при использовании новомодных штучек.)
                                                          –35
                                                          многа букаф, ниасилил
                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                            0
                                                            Не нужно считать проблемой то, что собьется какой-нибудь счетчик.

                                                            Поддерживаемые MongoDB атомарные функции решают эту проблему. Пример: {$inc:{counter:1}}

                                                            А вообще довольно объёмная работа. Мне кажется, что вам помог бы нескольконедельный отдых после такой дикой нагрузки, ну там Карелия с байдарками, или ещё какие-нибудь прелести активного отдыха далеко от дома.

                                                            Удачи!
                                                              +2
                                                              {$inc:{counter:1}}
                                                              так и происходит

                                                              Спасибо!
                                                              +2
                                                              Мобильную версию (Android, iPhone, iPad) не делали?
                                                                +2
                                                                Будем делать, но не в ближайшем времени.
                                                                  0
                                                                  С этого могли начать. Из всего разнообразия ридеров под android не один мне не подошел. Пользуюсь gr mobile.
                                                                0
                                                                А переписать mongomapper на js это велосипед? я вот тут начал ввиде плагина к express писать, только там проблема возникла пока с jspec либой. Проект еще сырой документации нету, но вот написать mongomapperjs очень хочется.
                                                                  +2
                                                                  Посмотрите mongoose, он имеет вполне достаточный минимум для работы с моделью. Мне пока хватает.
                                                                    0
                                                                    О спасибо. Как раз то, что нужно. Когда искал не нашел такого.
                                                                      0
                                                                      Если делать только ридер — да, я с Вами согласен.

                                                                      Но мы делаем не ридер.
                                                                  –5
                                                                  >Без велосипедов
                                                                  это вычеркниет. ведь ваш рсс-ридер — сам по себе велосипед.
                                                                    +3
                                                                    В данном случае он более близок Лунапарку
                                                                      +4
                                                                      Кажется, я уже отвечал на подобный комментарий…
                                                                      0
                                                                      Такой объем лучше по частям. А на ридер я бы с удовольствием взглянул:)
                                                                        +3
                                                                        Так это, как бы, часть :)
                                                                        +1
                                                                        > backward-capability
                                                                        Всётаки backward-compatibility
                                                                          +1
                                                                          поправил
                                                                          0
                                                                          Очень вкусно описал процесс, спасибо.
                                                                          Где бы теперь подписаться на анонс ридера, чтоб не пропустить ненароком?
                                                                            +3
                                                                            Анонс появится либо в разделе «Стартапы».
                                                                            Называется Eventr.

                                                                            Спасибо.
                                                                              0
                                                                                0
                                                                                Он.

                                                                                Но то, что там написано, уже слегка устарело… :)
                                                                            –3
                                                                            this is fucking awesome
                                                                              0
                                                                              Вот это да!

                                                                              Я и сам недавно заморачивался многим из вышеперечисленного (и сейчас заморачиваюсь) — node.js, MongoDB, сервер очередей написал тоже, правда более примитивный. На этом действительно можно делать очень интересные вещи ))
                                                                                0
                                                                                Вот сейчас к этому всему добавится Redis и стает еще интересней :)
                                                                                  0
                                                                                  Да, Redis и MongoDB, на мой взгляд, самые подходящие кандидаты на роль «стандартного» хранилища данных в пару к Node.js. Riak тоже выглядит интересно, но с запросами там сложновато )
                                                                                    0
                                                                                    Riak я поздно заметил, решил уже не ковыряться… но говорят о нем действительно позитивно.
                                                                                      0
                                                                                      А я как раз ковыряюсь. Ему бы интерфейс для простых запросов как у Монго — цены б ему не было )
                                                                                +11
                                                                                Вы очень крутой! А еще перфекционист.
                                                                                Жаль, что подобный подход к работе конфликтует с личной жизнью и всякими увлечениями.
                                                                                Расскажите, что вас мотивирует?
                                                                                  0
                                                                                  По поводу перфекционизма, меня очень сильно впечатлил вот этот доклад:
                                                                                  vimeo.com/10922497

                                                                                  Мотивирует, наверное, то же, что мотивировало дядечку Эйнштейна, и еще другую тысячу психов по всей планете.
                                                                                  +1
                                                                                  Результат бы посмотреть.
                                                                                    +3
                                                                                    Заметил перфекциониста — и это офигенно похвально! Таких весьма совсем не очень. Сам сейчас пишу биллинг на Nodejs и mongodb, плюс API на стороне ZF. И мне нравится серверный JS!

                                                                                    Народ, включайтесь в группу Nodejs и остальные похожие по теме группы на гугле — русских там 1.5 человека пока.
                                                                                      0
                                                                                      Знакомые лица :)
                                                                                        0
                                                                                        Включаюсь!
                                                                                          0
                                                                                          Подключился!!! Сам только сегодня начал ковырять и в восторге!!!
                                                                                          0
                                                                                          по поводу велосипедов
                                                                                          что конкретно может заставить пользователей уйти с Google Reader?
                                                                                            0
                                                                                            Смотря каких. Их там много.
                                                                                            В другой статье все расскажем.
                                                                                              0
                                                                                              Могу посоветовать добавить поддержку Digest-авторизации, этого так не хватает в GR для чтения подзамочных записей ЖЖ.
                                                                                                0
                                                                                                в жж подзамок можно читать через user:pass@livejournal…
                                                                                                  0
                                                                                                  На хабре где-то была тема про подзамки и gr.
                                                                                                  Люди не хотят свои пароли светить сторонним сервисам. И это правильно.

                                                                                                  Пришло время OAuth.
                                                                                            +1
                                                                                            Чем обоснован отказан от реляционных баз данных в пользу монго? Ридер проектируется с расчетом на гигантские нагрузки или вы просто поддались модному тренду «noSQL»? :)
                                                                                              +1
                                                                                              Повелся на модный тренд. Но если будут гигантские нагрузки — буду только рад :)

                                                                                              А Вы лучше скажите, зачем использовать реляционную бд, если ее «реляционность», в итоге, используется на 10%? (в нашем случае)

                                                                                              + schema-less
                                                                                              + легкие миграции
                                                                                              + data-driven queries (очень нравится)
                                                                                              + нативный шардинг, в случае чего
                                                                                              +… можно перечислять
                                                                                                0
                                                                                                Почитайте тут
                                                                                                zabivator.livejournal.com/412053.html
                                                                                                  0
                                                                                                  Спасибо, прочел.

                                                                                                  «Те, что НЕ владеют DB-разработкой НАДЕЯТСЯ на NoSQL.» — про меня
                                                                                                  «Ниша NoSQL — высоконагруженные сайты, вырастающие из стартапов.» — надеюсь, про наш стартап

                                                                                                  А Вы, в свою очередь, посмотрите вот этот доклад:
                                                                                                  www.infoq.com/presentations/Facebook-Software-Stack

                                                                                                  И оцените, как фейсбуку приходится использовать MySQL.
                                                                                                    0
                                                                                                    Чото вы мелко сравниваете — фейсбук…
                                                                                                    Давайте сразу на примере гугла, выш стартап ведь, вы надеетесь, не меньше нагружен будет.
                                                                                                      0
                                                                                                      Вот когда ребята начинали делать фейсбук, думали так, как Вы. Либо вообще не думали.
                                                                                                        0
                                                                                                        Откуда вы знаете, что они думали?
                                                                                                        Не иначе — вы думаете, что они так думали :)
                                                                                                          0
                                                                                                          Да, следовало бы вставить слово «наверное» :)
                                                                                              +2
                                                                                              ето просто прекрасно! (с)

                                                                                              а для распределения нагрузки gearman были идеи использовать?
                                                                                              для redis вродь наиболее оптимальным решением сейчас есть libredis с поддержкой ketama, нескольких серверов и batch-запросов. или есть какие-нить другие идеи?
                                                                                                0
                                                                                                Спасибо, посмотрю.

                                                                                                Буду колупать Redis на днях. Скорее всего, прикручу его к node и на этом пока остановлюсь.
                                                                                                  0
                                                                                                  мы вот сделали такую систему на базе Gearmand и Zend_Reader — работает все отлично, уже в продакшине почти полгода. Единственная проблема — всякая фигня непридсказуемая в лентах. Например, многие ленты по особенному трактуют поле даты новости и она часто неверно понимается парсером.
                                                                                                    0
                                                                                                    Zend_Reader пришлось хорошенько дописать :)
                                                                                                  +6
                                                                                                  вот читаю такие посты и понимаю что я очень много еще не знаю мягко говоря.
                                                                                                  Ждем читалку
                                                                                                    0
                                                                                                    Очень хотелось бы взглянуть на ваш карказ над ZF.
                                                                                                      +1
                                                                                                      Простите, «каркас» конечно же. конец недели…
                                                                                                        0
                                                                                                        Даже не знаю, как Вам его показать…
                                                                                                        Что именно интересует?
                                                                                                          0
                                                                                                          о, можете показать какой-то gateway и mapper для mongodb? также на entity для етого.
                                                                                                          на использование acl внутри сервиса тоже интересно взгянуть б (интересно как, вот).
                                                                                                            0
                                                                                                            Скиньте email в личку
                                                                                                      +1
                                                                                                      Описание контроллера и менеджеров — один-в-один supervision tree из Erlang'a (gen_supervisor, gen_server) Это не упрек в велосипедности :) Просто показатель того, что рано или поздно разработчики приходят к похожим архитектурным решениям.

                                                                                                      По поводу ридера главный вопрос — HTTP Digest Authentication, которая есть, например, в livejournal'е Ни один онлайн сервис, насколько знаю, не поддерживает ее, а хотелось бы :)
                                                                                                        +1
                                                                                                        Это не сложно сделать. Находится в списке фич, которые собираемся запустить в первые месяцы.
                                                                                                          0
                                                                                                          Ура!!! :)
                                                                                                        0
                                                                                                        Спасибо, очень интересно было читать!

                                                                                                        PubSub прикручивайте — он (с точки зрения ридера) простой как сапог, зато позволяет для фидов, что его поддерживают, практически мгновенно доставлять сообщения, в обход общей очереди feed pull-а.
                                                                                                          +1
                                                                                                          собирался писать ридер для себя и очень рад, что, наверное, не придётся :)

                                                                                                          Будет ли импорт/экспорт фидов в OPML? будет ли HTTP Digest Authentication? Было бы очень неплохо
                                                                                                            0
                                                                                                            Про OPML написано в статье.
                                                                                                            Так же, планируем сделать Google Reader Connect, который, скорее всего, позволит двумя кликами сделать импорт/экспорт — без всякого opml. Но пока руки не дошли до его API.

                                                                                                            По поводу HTTP Digest Authentication, читайте пару комментов выше.
                                                                                                            0
                                                                                                            Добавьте в него IMAP.
                                                                                                              0
                                                                                                              Почтовый клиент все равно удобнее.
                                                                                                                0
                                                                                                                Не люблю. В рсс ридере было удобнее.
                                                                                                              +1
                                                                                                              Единственный удобный для меня ридер — это версия Google Reader для айфона, по адресу google.com/reader/i/, она и легкая, и удобная, и не перегружена ничем лишним.
                                                                                                                0
                                                                                                                +1 тоже им пользуюсь
                                                                                                                  +1
                                                                                                                  для айфона?) Уверены что гугл делал это специально для айфона?)
                                                                                                                  0
                                                                                                                  насколько кртитичная информация хранится в очереди memcacheq? я имею ввиду — что будет, если вдруг случайно очередь потеряется?
                                                                                                                    0
                                                                                                                    В основном — действия пользователей в виде подписок на потоки и импорт за последние 1-5 минут максимум.
                                                                                                                    Плюс, могут устареть слегка сами потоки.

                                                                                                                    Сейчас как раз делаю так, чтобы она не терялась (избавляюсь от memcached).
                                                                                                                    0
                                                                                                                    «Все, что я имел с самого начала, это небольшой каркас, делающий работу с zf слегка удобней. » А каркас ваш или это какое-то общедоступное решение?
                                                                                                                      0
                                                                                                                      Этот каркас достался по наследству с другого проекта, который побывал на продакшн. Делался он «коллективным разумом», пережил довольно много usecase-ов.

                                                                                                                      Кстати, работа с zf мне вообще не напрягает мозг. Как-то так все с ним очень просто получается.
                                                                                                                      0
                                                                                                                      а зачем PHP здесь?
                                                                                                                      что мешает все-все-все на node.js сделать?
                                                                                                                        0
                                                                                                                        Отсутствие машины времени.
                                                                                                                          0
                                                                                                                          На Erlang'е! :)
                                                                                                                          0
                                                                                                                          Экспорт данных в FB2 или LRF будет?
                                                                                                                            0
                                                                                                                            присоединяюсь к вопросу, нужен эксапорт в fb2
                                                                                                                              0
                                                                                                                              Какие версии нужно поддерживать?
                                                                                                                            0
                                                                                                                            года два назад делал свой ридер. Все мечты разбились когда увидел fav.or.it(который загнулся по неизвестным причинам) и обомлел. А вы имея перед глазами gr и netvibes работали почти год, поэтому мой вам поклон.
                                                                                                                              0
                                                                                                                              На самом деле, живем этой идеей уже полтора года.

                                                                                                                              Спасибо.
                                                                                                                              0
                                                                                                                              Спасибо за статью и всем за коменты!!! Теперь точно не высплюсь (( Пошел ковырять node.
                                                                                                                              Каркас для ZF псмотреть бы… (скромно)
                                                                                                                                0
                                                                                                                                «Так же, существует WorkerPhp.js, который запускает php-cli как child-process и общается с ним на json»
                                                                                                                                объясните пожалуйста, а как вы держите эти PHP не закрытыми? черех php-fpm?
                                                                                                                                  0
                                                                                                                                  и это наверное у вас не php-tcp сервер, я правильно понимаю?
                                                                                                                                    0
                                                                                                                                    Да, где-то так:

                                                                                                                                    while ($request = fgets($this->_stdin)) {
                                                                                                                                        $this->handleData($request);
                                                                                                                                    }
                                                                                                                                    
                                                                                                                                      0
                                                                                                                                      Т.е. все-таки воркеры в режиме tcp-серверов, открываете их на портах и общаетесь с ними?

                                                                                                                                      У меня проблема выбора или php-fpm или в качестве tcp-серверов воркеры пускать, что вы бы посоветовали?
                                                                                                                                        0
                                                                                                                                        Это не tcp, это простой std I/O. Работает замечательно, поскольку основной упор времени именно на выполнение задач, передача данных в моем случае — спички.
                                                                                                                                        Помоему, tcp необходим только в том случае, когда нужно общение между разными серверами.
                                                                                                                                          0
                                                                                                                                          Пример:

                                                                                                                                          $this->_stdin = fopen('php://stdin', 'r+');
                                                                                                                                          $this->_stdout = fopen('php://stdout', 'w+');
                                                                                                                                          
                                                                                                                                            0
                                                                                                                                            Спасибо большое, попробовал.

                                                                                                                                            К сожалению один воркер в памяти сьедает до 20 мегабайт ОЗУ. 100 воркеров сьедают 2 гигабайта(что не предел из-за динамического кол-ва воркеров и динамически-меняющегося необходимого кол-ва ОЗУ отдельно взятому воркеру).

                                                                                                                                            Справедливости ради надо сказать, воркеры в формате TCP едят не меньше, как и воркеры NODEJS в режиме child_process.spawn)

                                                                                                                                            Если не секрет, какое кол-во ОЗУ сьедает ваш PHP-воркер в среднем?
                                                                                                                                              0
                                                                                                                                              > К сожалению один воркер в памяти сьедает до 20 мегабайт ОЗУ. 100 воркеров сьедают 2 гигабайта
                                                                                                                                              Зачем Вам 100 воркеров? У меня максимум 30 воркетов на сервер, и то, это сделано ради повышения эффективности работы с блокирующим I/O в php, а вовсе не ради ресурсов. Мои воркеры гребут rss, 90% времени его работы занимает трансфер данных из внешних источников. Было бы весьма разумно реализовать это на nodejs, но на этом завязано слишком много бизнес-логики в среде php.
                                                                                                                                              Система работает эластично — если нагрузка небольшая, запущено в среднем 5 воркеров.

                                                                                                                                              > Справедливости ради надо сказать, воркеры в формате TCP едят не меньше
                                                                                                                                              Чем воркеры «в формате TCP» принципиально отличаются от воркеров «в формате I/O»? И что побужтает их кушать меньше?

                                                                                                                                              > Если не секрет, какое кол-во ОЗУ сьедает ваш PHP-воркер в среднем?
                                                                                                                                              60 MB

                                                                                                                                              Данный вопрос очень сильно связан с конкретной задачей, которую выполняют Ваши воркеры. Например, если это рэсайзинг изображений — php тут вообще не нужен.
                                                                                                                                                0
                                                                                                                                                Спасибо за ответы.

                                                                                                                                                >Зачем Вам 100 воркеров?
                                                                                                                                                Количество запросов к воркерам в часы пик более 100 в секунду (при кэшировании). Конечно нельзя назвать это «высокими нагрузками», но 1 воркер может выполнять одну задачу одновременно, где среднее время выполнение задачи(получение, парсинг страницы и проход по некоторым УРЛ страницы) — 2 секунды(до 60 секунд). Отсюда скорость системы зависит от параллельного выполнения задач.

                                                                                                                                                >Чем воркеры «в формате TCP» принципиально отличаются от воркеров «в формате I/O»? И что побужтает их кушать меньше?
                                                                                                                                                Вы правы, ничем. Это я «в поисках решения» сказал)

                                                                                                                                                >. Например, если это рэсайзинг изображений — php тут вообще не нужен.
                                                                                                                                                Нет, ресайзинга и ничего такого нет.
                                                                                                                                                  0
                                                                                                                                                  > получение, парсинг страницы и проход по некоторым УРЛ страницы
                                                                                                                                                  Это можно сделать на nodejs?
                                                                                                                                                    0
                                                                                                                                                    Да. Скорость будет больше?
                                                                                                                                                      0
                                                                                                                                                      Зависит от соотношения Network/Processor — если это 9/1 (как у меня), то будет раз в 10 быстрее (это для одного процесса).
                                                                                                                                                      Но самое главное — это память. Если грамотно написать (а в nodejs это не так легко), то процесс будет кушать не более 100 МБ. 4 ядра — 4 таких процесса. Опять же, зависит от логики самой программы. Если это краулер, тогда зависит от размера страниц и количества одновременной обработки — это можно регулировать.
                                                                                                                                                        0
                                                                                                                                                        Спасибо, попробую на nodejs переписать воркеров.

                                                                                                                                                        На простых задачах(там, где не надо проходить по ссылкам внутри страницы) NodeJS в один поток делает по скорости пхп, запущенный параллельно через spawn.child. Попробую на более сложных, в 4 потока и регулировать, как вы посоветовали.
                                                                                                                                                          0
                                                                                                                                                          не забудьте про process.nextTick

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

                                                                                                                                  Самое читаемое