2 заметки с тегом

Apache

rtorrent + ruTorrent + HTTPRPC + scgi_local

11 июля 2014, 15:47

На домашнем сервере запилил себе rtorrent+ruTorrent. Сначала делал по старинке — через mod_scgi. Потом обнаружил, что ruTorrent периодически жалуется, что, дескать, «rtorrent не отвечает». В интернетах утверждают, что связаны эти грабли с тем, что для mod_scgi нынешние скорости закачки (а следовательно, и обновления информации) зело велики и оно не справляется. Не то что бы это сильно влияло на функционал, но ведь косячок-с налицо. Поэтому решил с этим побороться. Для борьбы рекомендуется использовать специальный плагин для ruTorrent, который называется HTTPRPC.

Установка плагина нехитрая — нужно просто скопировать папку плагина в подкаталог plugins внутри каталога ruTorrent. После этого можно отключить в конфигах апача модуль mod_scgi (ежели был подключён) и убрать строку

SCGIMount /RPC2 127.0.0.1:5000

Я решил пойти ещё дальше. Вычитал, что работа через сетевой сокет (даже если он висит на localhost) — это «несекурненько». И есть возможность организовать обмен информацией между rtorrent и ruTorrent через файловый сокет. Для этого требуется в конфиге rtorrent вписать такое:

scgi_local = /mnt/storage0/sys/tmp/rtorrent-rpc.socket

Где /mnt/storage0/sys/tmp/rtorrent-rpc.socket — путь к файлу сокета.

После перезапуска rtorrent будет создан файл /mnt/storage0/sys/tmp/rtorrent-rpc.socket

Чтобы ruTorrent вкурил, что ему теперь надо работать не через сетевой сокет, а через файловый, нужно в конфиге config.php от ruTorrent изобразить следующее:

$scgi_port = 0;
$scgi_host = "unix:///mnt/storage0/sys/tmp/rtorrent-rpc.socket";

Строчку

$XMLRPCMountPoint = "/RPC2";

ОСТАВЛЯЕМ КАК ЕСТЬ. То есть, её не трогаем.

После этого запускаем rtorrent, перезапускаем апач (если вносились изменения в его конфиг) и наслаждаемся.

У меня ещё возникли грабли с тем, что права на создаваемый сокет не позволяли туда писать пользователю www, от которого работает апач. Пришлось немного доработать скрипт запуска rtorrent.

Добавил в rc.conf переменную rtorrent_socket:

rtorrent_socket="/mnt/storage0/sys/tmp/rtorrent-rpc.socket"

А в скрипте запуска добавил проверку на существование сокета при запуске rtorrent, и если сокет существует, то меняем ему владельца на rtorrent:www. В целом скрипт запуска rtorrent выглядит так (нужные строки, относящиеся к правам на файловый сокет выделены красным):

#!/bin/sh

# PROVIDE: rtorrent
# REQUIRE: NETWORKING SERVERS
# BEFORE: DAEMON
# KEYWORD: shutdown

#
# Add the following lines to /etc/rc.conf to enable rtorrent at startup
# rtorrent (bool): Set to "NO" by default.
#                Set it to "YES" to enable rtorrent
# rtorrent_user (str): Set to user running rtorrent
#                    (default 'p2p')
# rtorrent_home (str): Set to home directory of user running rtorrent
#                    (default /home/${rtorrent_user})

. /etc/rc.subr

name="rtorrent"
rcvar=rtorrent_enable

load_rc_config $name

rtorrent_enable=${rtorrent_enable:-"NO"}
rtorrent_user=${rtorrent_user:-"rtorrent"}
rtorrent_home=${rtorrent_home:-"/home/$rtorrent_user"}
rtorrent_socket=${rtorrent_socket:-"/tmp/rtorrent-rpc.socket"}

required_dirs=${rtorrent_home}
required_files="${rtorrent_home}/.rtorrent.rc"

start_cmd="${name}_start"
stop_cmd="${name}_stop"

rtorrent_start()
{
  if [ ! -f /var/run/${name}.run ]
  then
    cd ${rtorrent_home}
    su ${rtorrent_user} -c "/usr/local/bin/screen -dmS rtorrent_init /usr/local/bin/rtorrent"
    touch /var/run/${name}.run
    echo "Started ${name}."
  else
    echo "${name} seems to be already running — remove /var/run/${name}.run manually if needed."
  fi
  sleep 3
  if [ -e ${rtorrent_socket} ]
  then
    chown rtorrent:www ${rtorrent_socket}
  fi
}

rtorrent_stop()
{
  if [ -f /var/run/${name}.run ]
  then
    kill -SIGINT `ps -xa| awk '/rtorrent/ && ! /rtorrent_init/ && ! /stop/ { print $1 }'`
    rm -f /var/run/${name}.run
    echo "Stopped ${name}."
  else
    echo "${name} doesn't seem to be running — create /var/run/${name}.run if needed."
  fi
}

run_rc_command "$1"

sleep 3 добавлен, чтобы дать возможность rtorrent запуститься и создать сокет. У меня в роли сервера комп слабенький, система стоит на флэшке, поэтому иногда процесс создания сокета требует секунду-другую.

Apache   FreeBSD   Torrent

Бьётся файл при передаче по http

23 октября 2012, 20:51
Мерял тут скорость внутри конторских VPN-каналов, путём передачи 100-мегабайтного файла по http, с Apache22 на FreeBSD. Обнаружил необъяснимое — при передаче файла на винду качается кусок файла случайного размера (от 2.5 до 18 мегабайт) и потом передача рвётся. Клиент считает, что файл скачан полностью, в логах апача никаких ошибок. При этом перед началом закачки размер файла определяется правильно.

Начал рыть. Включение максимально подробных логов показало, что в момент обрыва передачи появляется запись:

[Thu Sep 27 12:31:48 2012] [info] [client 10.0.7.1] (12)Cannot allocate memory: core_output_filter: writing data to the network

Беглый поиск привёл на сайт Apache, где нашёлся такой текст:

Invalid argument: core_output_filter: writing data to the network
Apache uses the sendfile syscall on platforms where it is available in order to speed sending of responses. Unfortunately, on some systems, Apache will detect the presence of sendfile at compile-time, even when it does not work properly. This happens most frequently when using network or other non-standard file-system.

Symptoms of this problem include the above message in the error log and zero-length responses to non-zero-sized files. The problem generally occurs only for static files, since dynamic content usually does not make use of sendfile.

To fix this problem, simply use the EnableSendfile directive to disable sendfile for all or part of your server. Also see the EnableMMAP, which can help with similar problems.


Что в переводе означает, что Apache используется системный вызов sendfile на тех платформах, где он доступен, чтобы увеличить скорость ответа клиенту. К сожалению, на некоторых система апач определяет наличие этого вызова во время компиляции (т. е. сборки самого апача) даже если этот вызов в системе реально не работает надлежащим образом. Обычно это происходит при использовании сетевых или иных нестандартных файловых систем. Симптомы этой проблемы включают в себя вышеприведённый текст в логах и нулевой ответ на запрос файлов ненулевой длины. Проблема обычно возникает при передаче статических файлов, динамический контент не использует sendfile. Чтобы решить эту проблему, используйте директиву EnableSendfile, чтобы выключить использование вызова SendFile. Также почитайте про EnableMMAP, которая может помочь при сходных проблемах.

Выключил в итоге в конфиге апача EnableSendfile и EnableMMAP. Это помогло, но осадочек остался... Потому как файло лежит на обычном локальном разделе диска. Или UFS считается для апача недостаточно стандартной?