UMGUM.COM (лучше) 

Wget ( Зеркалируем HTTP и FTP контент с помощью Wget. )

26 октября 2010  (обновлено 31 января 2015)

OS: Linux Debian Lenny.

Подготовим конфигурацию и реализуем непосредственно зеркалирование.

Добавим в систему пользователя, от имени которого будем запускать скрипты зеркалирования ресурсов:

# groupadd mirrorer
# useradd --shell /bin/sh --home-dir /var/lib/mirrorer --gid mirrorer mirrorer

Создадим ему место жительства:

# mkdir -p /var/lib/mirrorer
# chown -R mirrorer:mirrorer /var/lib/mirrorer

# mkdir -p /var/www/mirror.local
# chown -R mirrorer:mirrorer /var/www/mirror.local

# mkdir -p /var/log/mirrorer
# chown -R mirrorer:mirrorer /var/log/mirrorer

Инсталлируем утилиты:

# aptitude install wget psmisc


Пишем скрипт зеркалирования:

# mkdir -p /etc/custom/mirrorer
# touch /etc/custom/mirrorer/mirror.sh
# chmod ugo+x /etc/custom/mirrorer/mirror.sh

# cat /etc/custom/mirrorer/mirror.sh

#!/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin

# Формируем командную строку с общими для всех запускаемых экземпляров опциями
PROG="wget --background --tries=25 --timestamping --timeout=60 --wait=2 --random-wait --no-parent --force-directories --recursive --level=7 --directory-prefix=/var/www/mirror.local"

# По простому выгружаем все запущенные экземпляры Wget, не успевшие завершить свою работу с момента предыдущего запуска
killall --signal SIGKILL wget

# Обновляем зеркало ftp://ftp.salyk.kz/
LOG="--append-output=/var/log/mirrorer/ftp.salyk.kz.log"
SITE="ftp://ftp.salyk.kz/"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"

# Обновляем зеркало ftp://rcpi.kz/
LOG="--append-output=/var/log/mirrorer/rcpi.kz.log"
SITE="ftp://rcpikz_files:12345@rcpi.kz/"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"

# Обновляем зеркало антивирусной утилиты "drweb-cureit.exe"
LOG="--append-output=/var/log/mirrorer/download.geo.drweb.com.pub.drweb.cureit.drweb-cureit.log"
SITE="http://download.geo.drweb.com/pub/drweb/cureit/drweb-cureit.exe"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"

# Обновляем зеркало баз антивируса DrWeb
LOG="--append-output=/var/log/mirrorer/download.geo.drweb.com.pub.drweb.bases.log"
SITE="http://download.geo.drweb.com/pub/drweb/bases/"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"

# Обновляем зеркало антивирусной утилиты "avz4.exe"
LOG="--append-output=/var/log/mirrorer/z-oleg.com.avz4.zip.log"
SITE="http://z-oleg.com/avz4.zip"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"

# Обновляем зеркало баз антивирусной утилиты "avz4.exe"
LOG="--append-output=/var/log/mirrorer/z-oleg.com.secur.avz_up.avzbase.zip.log"
SITE="http://z-oleg.com/secur/avz_up/avzbase.zip"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"

exit 0

Где, опции Wget в скрипте зеркалирования:

"--background"        - Переводим приложение в фоновый режим после запуска;
"--timestamping"      - Включаем проверку актуальности файлов по дате их создания;
"--timeout=seconds"   - Указываем время ожидания ответа сервера в секундах (по умолчанию время ожидания равно 900 секундам; 0 - отменяет проверку времени ожидания);
"--wait=seconds"      - Устанавливаем длительность паузы в секундах между несколькими загрузками для снижения загруженности зеркалируемого сервера (в минутах    - "m", в часах - "h", в днях - "d" после значения);
"--random-wait"       - Указываем применить специальную методику псевдослучайного вычисления времени задержек между загрузками при рекурсивном обходе для маскировки Wget под обычное приложение (некоторые серверы контента, совершая формирование файлов журналов с паузами запросов файлов, могут определить рекурсивную загрузку файлов и заблокировать отдачу);
"--force-directories" - Указываем создавать структуру папок, начиная с корня запрашиваемого ресурса;
"--recursive"         - Включаем рекурсивную загрузку;
"--level=depth"       - Уточняем максимальную глубину уровней рекурсивной загрузки (по умолчанию значение равно 5).

Солянку из опций "--timeout", "--wait" и "--random-wait" приходится применять специально для более или менее корректного отрабатывания с FTP серверами, настроенными нашими отечественными криворукими "админами". Много странного и забавного приходится наблюдать, объяснения далеко не всему находится; шедевр администраторов сайта "ftp://rcpi.kz", применивших для анонимного доступа публикуемый нестандартный логин и пароль - тому пример.

Автоматизируем запуск скрипта с помощью Crontab. Думаю, что две актуализации в течении суток зеркала для сети из сотен пользователей не будет сочтено DDoS атакой на серверы контента.

....
1 */12 * * * root /etc/custom/mirrorer/mirror.sh &
....

Wget прост и незатейлив - как "колун". Упомянутое орудие труда дровосека весьма эффективно, но не всегда удобно для человека, не ночевавшего в яме под корнями дерева на подстилке из "лапника". Так и Wget, имеет ряд недостатков, на некоторые из которых можно закрыть глаза, а какие то обойти с помощью сторонних приложений.
В частности, одно из неудобств, которое проще проигнорировать, чем устранять - создание директорий с текущей датой и временем сервера, а не той датой и временем, с которой таковые были созданы на зеркалируемом ресурсе; это при том, что с файлами такого не происходит, там всё, как положено.

Ещё одно неудобство, вред от которого следует минимизировать - невозможность явно разделить ещё закачиваемый и уже закачанный файл по имени. Со стороны определить это можно только по непрерывно изменяющемуся размеру и времени создания и модификации. Непременно случится так, что пользователь запросит себе файл, который Wget ещё докачивает, а, учитывая то, что "человеко воспринимаемых" признаков различия нет - он получит "битый" файл. Я вижу два пути решения этой проблемы. Первый, примитивный и не наш - зеркалировать ресурсы в отдельную директорию и только после завершения процесса копировать все файлы в место, доступное пользователям. Второй и более изящный - проверка состояния файла перед его выдачей пользователю и уведомления о неоконченной загрузке, буде такое обнаружиться.


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )