программируем на JavaScript

Сайт на Node.js и Express своими руками

Вписываем название торрента, жмем Enter и в ту же секунду под списком появляются результаты. Жмем на «глобус» и начинается загрузка. Да, вы угадали: это заключительная статья из серии «Готовимся к закрытию Rutracker», в которой мы рассмотрим создание простого сайта на Node.js. Первая часть тут, вторая тут.

Делаем сайт на Node.js и Express

Начнем традиционно с вопросов и ответов.

Вопрос: зачем так много всего ради торрентов?

Ответ: торренты тут просто для примера. Я люблю осваивать новые технологии и считаю, что лучше тренироваться на чем-то реальном, нежели писать очередной бесполезный Hello World. С JavaScript я начал знакомиться 3 дня назад и эта статья — побочный продукт этого знакомства.

Вопрос: зачем нужен Apache Solr и MySQL одновременно?

Ответ: я привел примеры того, как можно организовать поиск. Solr и MySQL устанавливать параллельно не нужно. Вы можете выбрать что-то одно. Например, если у вас уже поднят MySQL, то будет логично использовать его. Если вы хотите не только искать по торрентам, но и проиндексировать содержимое своей домашней директории, то лучше использовать Solr.

Вопрос: можно ли обойтись вообще без программирования?

Ответ: можно. Solr использует библиотеку Apache Tika, которая умеет определять тип контента и извлекать данные. Вы можете просто скормить Solr всю директорию с CSV-файлами целиком, а Tika сама всё распарсит.

А теперь переходим к Node.js.

Что такое Node.js?

Как-то раз любознательные экспериментаторы выдернули из браузера Chromium движок Google V8, отвечающий за обработку JavaScript, перенесли его на сервер и попытались использовать исключительно клиентский доселе JavaScript в серверных целях, для создания сайта. Каково же было их удивление, когда получившийся сайт уделал по производительности сайты, построенные по всем остальным технологиям сайтостроительства, включая этот ваш PHP. Исследователи обрадовались, назвали свое изобретение Node.js и стали его раскручивать. В наши дни Node.js уже используют такие небезызвестные компании, как Uber, PayPal, LinkedIn, New York Times и другие.

Почему Node.js уделывает другие платформы разработки? На это есть три причины:

  1. Node работает в режиме сервера приложений. Например, сайт на PHP для сборки каждой страницы каждый раз загружает PHP-файлы, интерпретирует их, обрабатывает инклюды, каждый раз заново устанавливает соединение с базой данных и запрашивает из нее повторно объекты. Node запускается только один раз, устанавливает одно соединение (или пул соединений) с БД, инициализирует рабочие объекты и потом начинает обрабатывать входящие HTTP-запросы один за другим, не прерываясь.
  2. Вторая причина заключается в самом языке JavaScript. Он асинхронный. Это значит, что функции выполняются не последовательно, а параллельно. Таким образом, скрипт отрабатывает быстрее и Node способен обслужить больше соединений в единицу времени. Вот за что полюбили Node.js на высоконагруженных сайтах.
  3. Сам движок написан очень качественно и сильно обгоняет все остальные JS-движки.

Но довольно слов, оценим скорость Node.js на практике. Чтобы сократить объем программирования, воспользуемся замечательным фрэймворком Express. Фрэймворк сгенерирует все файлы за нас и вся работа сведется к редактированию 2 файлов: один JS-скрипт на клиентской стороне будет отсылать AJAX-запросы к БД, другой JS-скрипт на сервере будет на эти запросы отвечать. AJAX можно было бы и не использовать, но мы же ходим оценить производительность Node, поэтому работа без перезагрузки страницы будет весьма кстати.

Чтобы было интереснее, не будем создавать ни форму, ни кнопки. Только одна строка с текстовым вводом вне тега form. Не знаю, насколько это соответствует стандарту HTML5, зато стильно, модно, молодежно: юзер пишет запрос, нажимает Enter и сразу же видит результат.

Сначала клиентская часть:

var torrentDbQuery = function() {
  // Возьмем запрос из формы
  var query = $('#torrent-name').val();
  // И отправим get-запрос серверу
  $.ajax({
        method: 'get',
        url: '/ajax/search',
        dataType: 'json',
        data: { query: query }
  // Тут проявляется асинхронность. Интерпретатор не будет дожидаться получения ответа
  // от сервера и перейдет к выполнению следующих команд. Но нам-то хотело бы всё же получить
  // результат и обработать его. Запилим анонимную функцию и укажем, что ее нужно будет выполнить
  // после того, как сервер ответит.
  }).done(function(r) {
          if (r.status === 'ok') {
		// Очистим поле ввода для нового запроса
                $('#torrent-name').val('');
		// Удалим старые результаты поиска
                $('#results').empty();
		// Переберем массив, который вернул сервер и покажем результаты поиска
                r.data.forEach(function(torrent) {
                  $('#results').append('<p class="result-item">' +
                        '<a href="magnet:?xt=urn:btih:' + torrent.magnet + '">' +
                        '<span class="glyphicon glyphicon-globe"></span></a>&nbsp;&nbsp;' +
                        torrent.name +
                        '</p>');
                });
          } else if (r.status === 'fail') {
                $('#torrent-name').html('Error: ' + r.message);
          } else {
                $('#torrent-name').html('Кажется, что-то пошло не так');
          }
        });
}

Теперь серверная часть, которая обрабатывает AJAX-запрос:

router.get('/search', function(req, res, next) {
  // Что там запросил пользователь?
  var q = req.query.query;
  // Сформируем SQL-запрос
  q = q.split(' ').join("%' and name like '%");
  var query = "select name, magnet from torrents " +
        "where name like '%" + q + "%'";
  // И запросим. Вторым аргументом функции указывается анонимная функция,
  // которая будет вызвана после того, как данные будут извлечены из БД.
  // Это опять та самая асинхронность, которая дарует скорость. (Но и возможность
  // легко "прострелить себе ногу" тоже дарует).
  db.query(query, function(error, row) {
        if (error) {
          res.json({ status: 'fail', message: error });
        } else {
          res.json({ status: 'ok', data: row });
        }
  });
});

Запускаем и проверяем:

npm start

Сайт на Node.js

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

Поиск по торрентам Рутрекера

Работает. И результат появляется впечатляюще быстро. Но «впечатляюще» — это сколько в миллисекундах? Давайте посмотрим:

Node.js. Скорость работы

154 миллисекунды. И это при том, что Node был запущен в режиме отладки. Но быстрее ли это PHP? Я переписал серверную часть на PHP с использованием самого шустрого фрэймворка Slim и запустил Apache Benchmark для сравнения. Но об этом в одной из следующих статей, а то я уже немного утомился графоманствовать.

Хочу такой поиск, но не хочу программировать

Тогда можно воспользоваться готовым решением:

git clone https://github.com/pomodor/rt-magnet.git
cd rt-magnet/web
npm install
npm start

Если база не была создана ранее, скачиваем свежий архив раздач тут и запускаем скрипт import.rb из директории import.

Ваша оценка: Нет Средняя оценка: 5 (7 votes)
a

ни одного коммента, все усердно пытаются воспроизвести написанное :) Думаю пока торрент еще на плаву, еще все не так суетятся. Потом будет аврал. Спасибо автору за посты, щас я тоже начну экспериментировать.

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
11
pomodor

Да, статьи о пакостях в W10 вызывают лавину комментариев, а как только пытаешься написать что-то полезное, народ встречает апатией. Вот уж действительно, хлеба и зрелищ. :)

Но Гитхаб показывает, что 7 человек всё же клонировали проект. :)

Ваша оценка: Нет Средняя оценка: 5 (4 votes)
a

можно для чайника поподробнее...

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
11
pomodor

Конечно! Какую часть пояснить?

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
4

я тоже сижу разбираюсь с solr, первый раз о нем слышу. Установить и запустить было просто, но потом... Мне вообще такие вещи нравятся, но я тормоз, на все надо время :). В инете на русском на удивление мало инфы, на англицком хоть и читаю, помогает часто только метод научного тыка. Ваш ранний пост оказался очень полезным http://liberatum.ru/blog/solr-rss, спасибо.

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
11
pomodor

Solr быстро развивается, документация не поспевает, поэтому много неточностей.

Вот моя короткая инструкция:

1. Скачиваем и распаковываем Solr. Заходим в полученную директорию, а потом в bin.

2. Стартуем сервер:

./solr start

3. Создаем ядро. Тут есть нюанс: создать через Web-админку Solr не получится, хотя там и есть такой пункт. Создаем из терминала:

./solr create_core -c mycore

4. Теперь индексация. Для этого предназначен скрипт post из состава Solr. Им можно проиндексировать, например, содержимое своих документов или всей домашней директории. Ну, либо, директорию с csv-файлами с Рутрекера запихнуть.

./post [-c название ядра] [директория]

Всё. Теперь можно искать миллионом различных способов. Можно из своего скрипта, можно из админки Solr, можно просто воспользоваться браузером, скормив ему ссылку с запросом.

Ваша оценка: Нет Средняя оценка: 5 (2 votes)
a

какие пакеты должны быть установлены в системе ? где должна находится база торрентов ? (директория , папка). готовое решение выполняется от пользователя или от root ?

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
11
pomodor

где должна находится база торрентов?

Без разницы. После отработки скрипта import.rb файлы можно удалить.

готовое решение выполняется от пользователя или от root?

Разумеется, никакого рута. Админские полномочия потребуются только для установки зависимостей через apt-get.

какие пакеты должны быть установлены в системе?

Первым делом, git. Он нужен для загрузки исходников. Да и вообще это крайне полезная вещь.

apt-get install git-core

Но можно и отказаться. Нужно зайти на GitHub и нажать "Download ZIP".

Потом потребуется Ruby для работы скриптов:

apt-get install ruby

Потребуется MySQL:

apt-get install mysql-server mysql-client

И Node.js:

apt-get install nodejs
Ваша оценка: Нет Средняя оценка: 4.2 (5 votes)
a

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

Ваша оценка: Нет Средняя оценка: 5 (3 votes)
4

абсолютно согласен, если кто работает в ит (да и не только) такой мощьный бесплатный поисковик не может не пригодиться, знания никогда не бывают лишними. Не думаю что кто не справился, установка явы и solr вообще примитивщина. Использование поисковика было потруднее, спасибо автору за статьи и комментарии многое прояснило. Сам делаю на яве, очень интересно

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
a

просветите Уважаемые , при запуске import.rb вот такой выхлоп
./import.rb:10: invalid multibyte char (US-ASCII)
./import.rb:10: invalid multibyte char (US-ASCII)
./import.rb:10: syntax error, unexpected $end, expecting keyword_end
puts './import.rb <директория с файлами csv>'
как понимаю это что-то с кодировкой ?

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
11
pomodor

Под Windows что ли запускаете?

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
a

mint 17. на этом же диске стоит win7. может из-за этого ?

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
11
pomodor

Добавьте второй строкой в import.rb:

# encoding: utf-8

Если заработает, то у вас старая версия Ruby. Узнать номер версии можно так:

ruby -v
Ваша оценка: Нет Средняя оценка: 5 (2 votes)
Отправить комментарий
КАПЧА
Вы человек? Подсказка: зарегистрируйтесь, чтобы этот вопрос больше никогда не возникал. Кстати, анонимные ссылки запрещены.
CAPTCHA на основе изображений
Enter the characters shown in the image.
Linux I класса
Linux II класса
Linux III класса
Счетчики
  • Самый популярный сайт о Linux и Windows 10
О Либератуме

Liberatum — это новости мира дистрибутивов Linux, обзоры, сборки, блоги, а также лучший сайт об Ubuntu*.