Разделение большого файла на несколько частей

Split

$ split --bytes=<размер части> <исходный файл> <префикс имени части>

Размер частей может иметь суффикс, означающий множитель.

b — 512
kB — 1000
K — 1024
MB — 1000*1000
M — 1024*1024
GB — 1000*1000*1000
G — 1024*1024*1024

и так далее для T, P, E, Z, Y.

Пример:

$ split -a 1 -d -b 100M big.iso small.iso.part

Получим много файлов по 100 Мб, с суффиксами part0, part1, part2, part3…:

small.iso.part0
small.iso.part1
small.iso.part2
small.iso.part3

и т.д.

Чтобы снова объединить все части воедино, можно использовать команду cat:

$ cat small.iso.part* > big.iso

Утилита cat соберет все файлы, начиная с small.iso.part0.

Бесплатные DNS-сервера

DNS-servers

Primary only:
primaryns.kiev.ua — доступен только для Украины

Primary and secondary:
zoneedit.com — 5 доменов, меня все устраивает
everydns.net — 20 доменов, нет email-forwarding
dnspark.com — 3 домена
soa.granitecanyon.com — доменов неограничено
domain-dns.com — доменов неограничено, нельзя создавать NS-записи
xname.org
mydomain.com — очень перегружен, очень тормознут
dns.xtremeweb.de = gratisdns.de — нету mail-forwarding
freedns.afraid.org — нет описания
editdns.net — нет описания
prosto.name — Хороший новенький русский сервис
dnsexit.com
1gb.ru
freedns.sgh.waw.pl — как xname.org
freedns.ws
namecheap.com
www.netbreeze.net/dns/ — панель на русском
help.yandex.ru/pdd/hosting.xml

Secondary only:
ns2.trifle.net
secondary.net.ua

Оперативная реакция на DDoS-атаки

DDoS-network-mapОдин из ресурсов, за которым я присматриваю, вдруг стал неожиданно популярным как у хороших пользователей, так и у плохих. Мощное, в общем-то, железо перестало справляться с нагрузкой. Софт на сервере самый обычный — Linux, Nginx, PHP-FPM (+APC), MySQL, версии — самые последние. На сайтах крутится Drupal и phpBB. Оптимизация на уровне софта (memcached, индексы в базе, где их не хватало) чуть помогла, но кардинально проблему не решила. А проблема — большое количество запросов, к статике, динамике и особенно базе. Поставил следующие лимиты в Nginx:

на соединения

limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn perip 100;

и скорость запросов на динамику (fastcgi_pass на php-fpm)

limit_req_zone $binary_remote_addr zone=dynamic:10m rate=2r/s;
limit_req zone=dynamic burst=10 nodelay;

Сильно полегчало, по логам видно, что в первую зону никто не попадает, зато вторая отрабатывает по полной.

Но плохиши продолжали долбить, и захотелось их отбрасывать раньше — на уровне фаервола, и надолго.

Сначала сам парсил логи, и особо настырных добавлял через iptables в баню. Потом парсил уже по крону каждые 5 минут. Пробовал fail2ban. Когда понял, что плохишей стало очень много, перенёс их в ipset ip hash.

Почти всё хорошо стало, но есть неприятные моменты:
— парсинг/сортировка логов тоже приличное (процессорное) время отнимает
— сервер тупит, если началась новая волна между соседними разборками (логов)

Нужно было придумать как быстро добавлять нарушителей в черный список. Сначала была идея написать/дописать модуль к Nginx + демон, который будет ipset-ы обновлять. Можно и без демона, но тогда придётся запускать Nginx от рута, что не есть красиво. Написать это реально, но понял, что нет столько времени. Ничего похожего не нашёл (может плохо искал?), и придумал вот такой алгоритм.

При привышении лимита, Nginx выбрасывает 503-юю ошибку Service Temporarily Unavailable. Вот я решил на неё и прицепиться!

Для каждого location создаём свою страничку с ошибкой

error_page 503 =429 @blacklist;

И соответствующий именованный location

location @blacklist {
    fastcgi_pass    localhost:1234;
    fastcgi_param   SCRIPT_FILENAME    /data/web/cgi/blacklist.sh;
    include         fastcgi_params;
}

Дальше интересней.

Нам нужна поддержка CGI-скриптов. Ставим, настраиваем, запускаем spawn-fcgi и fcgiwrap. У меня уже было готовое для collectd.

Сам CGI-скрипт fc

#!/bin/bash

BAN_TIME=5
DB_NAME="web_black_list"
SQLITE_DB="/data/web/cgi/${DB_NAME}.sqlite3"
CREATE_TABLE_SQL="\
CREATE TABLE $DB_NAME (\
    ip varchar(16) NOT NULL PRIMARY KEY,\
    added DATETIME NOT NULL DEFAULT (DATETIME()),\
    updated DATETIME NOT NULL DEFAULT (DATETIME()),\
    counter INTEGER NOT NULL DEFAULT 0
)"
ADD_ENTRY_SQL="INSERT OR IGNORE INTO $DB_NAME (ip) VALUES (\"$REMOTE_ADDR\")"
UPD_ENTRY_SQL="UPDATE $DB_NAME SET updated=DATETIME(), counter=(counter+1) WHERE ip=\"$REMOTE_ADDR\""
SQLITE_CMD="/usr/bin/sqlite3 $SQLITE_DB"
IPSET_CMD="/usr/sbin/ipset"

$IPSET_CMD add $DB_NAME $REMOTE_ADDR > /dev/null 2>&1

if [ ! -f $SQLITE_DB ]; then
     $SQLITE_CMD "$CREATE_TABLE_SQL"
fi

$SQLITE_CMD "$ADD_ENTRY_SQL"
$SQLITE_CMD "$UPD_ENTRY_SQL"

echo "Content-type: text/html"
echo ""

echo "<html>"
echo "<head><title>429 Too Many Requests</title></head>"
echo "<body bgcolor=\"white\">"
echo "<center><h1>429 Too Many Requests</h1></center>"
echo "<center><small><p>Your address ($REMOTE_ADDR) is blacklisted for $BAN_TIME minutes</p></small></center>"
echo "<hr><center>$SERVER_SOFTWARE</center>"
echo "</body>"
echo "</html>"

Собственно всё очевидно, кроме, разве что, SQLite. Я его добавил пока просто для статистики, но в принципе можно использовать и для удаления устаревших плохишей из черного списка. Время 5 минут пока тоже не используется.

Черный список создавался вот так

ipset create web_black_list hash:ip

Правило в iptables у каждого может быть своё, в зависимости от конфигурации и фантазии.

З.Ы.: Улыбнуло сообщение одного «хакера» на форуме, как быстро он положил сервер. Он и не догадывался, что это сервер положил на него.

Источник: http://habrahabr.ru/post/176119/

Установка Django 1.4 на хостинг NIC.RU

django-logo-positiveУстанавливаем Django:

1. Создать файл ~/.pydistutils.cfg со следующим содержимым:

[install]
prefix=/home/$USER/.python

2. Создать файл ~/.bashrc со следующим содержимым:

export PATH="${PATH}":/home/$USER/.python/bin
export PYTHONPATH="${PYTHONPATH}":/home/$USER/.python/lib/python2.6/site-packages;

3. Создаём директории:

mkdir -p /home/$USER/.python/lib/python2.6/site-packages

4. Выполняем

source ~/.bashrc

5. Загружаем и устанавливаем Django:

wget https://www.djangoproject.com/download/1.4/tarball/
tar xzvf Django-1.4.tar.gz
cd Django-1.4
python setup.py install

6. Проверяем версию

django-admin.py --version

Таким же образом мы можем ставить и любые django-python модули.

Сервер онлайн-вещаний на базе nginx

776px-Nginx-battleship.svgВведение

Привет всем! Несколько месяцев назад на Хабре была опубликована статья «Вещание онлайн-видео с помощью nginx», в которой Aecktann рассказал о своем опыте внедрения разрабатываемого мной (rarutyunyan) модуля к nginx для вещания видео — nginx-rtmp-module. С тех пор продукт активно развивался и в этой статье я более подробно расскажу о нем.

Вещатель нужен для передачи видео-потока клиенту. Речь идет либо о живом потоке, либо о вещании записанного видео (VOD, Video-on-demand). Существует большое количество технологий вещания видео. Среди них можно выделить традиционные протоколы, такие как RTMP или MPEG-TS, а также появившиеся в последнее время технологии адаптивного вещания поверх HTTP. К последним относятся HLS (Apple), HDS (Adobe), Smooth Streaming (Microsoft), MPEG-DASH. При выборе технологии основным фактором является ее поддержка на клиентской стороне. Именно поэтому вещание в формате RTMP на текущий момент является одним из самых распространенных. Протокол HLS поддерживается устройствами компании Apple, а также некоторыми версиями Android.

Сборка и настройка nginx-rtmp

Для добавления модуля nginx-rtmp к nginx нужно указать его в опции —add-module при конфигурации nginx, как и любой другой модуль.

./configure --add-module=/path/to/nginx-rtmp-module

После сборки и инсталляции нужно добавить секцию rtmp{} в файл конфигурации nginx.conf. Добавлять ее надо в корень конфига. Например:

rtmp {
    server {
        listen 1935;
        application myapp {
            live on;
        }
    }
}

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

worker_processes  1;

Чтобы иметь возможность использовать live вещания с бОльшим числом воркеров, нужно указать директиву rtmp_auto_push on (см. раздел «Воркеры и локальная ретрансляция»).

Публикация и проигрывание живого потока

Для публикации и проигрывания видео можно использовать Flash-проигрыватели (JWPlayer, FlowPlayer, Strobe и т.д.). Однако, для вещания серверных потоков и для тестирования часто используют ffmpeg (и ffplay). Начнем вещание тестового файла test.mp4 следующей командой:

ffmpeg -re -i /var/videos/test.mp4 -c copy -f flv rtmp://localhost/myapp/mystream

Тут надо учесть, что RTMP поддерживает ограниченый набор кодеков, впрочем, такие популярные кодеки, как H264 и AAC, входят в их число. Если кодеки в тестовом файле не совместимы с RTMP, потребуется перекодировка:

ffmpeg -re -i /var/videos/test.mp4 -c:v libx264 -c:a libfaac -ar 44100 -ac 2 -f flv rtmp://localhost/myapp/mystream

Вещать можно как поток из файла, так и из другого источника. Например, если предположить, что по адресу video.example.com/livechannel.ts вещается некий live MPEG-TS поток, то его также можно завернуть в rtmp:

ffmpeg -i http://video.example.com/livechannel.ts -c copy -f flv rtmp://localhost/myapp/mystream

Пример вещания с локальной веб-камеры:

ffmpeg -f video4linux2 -i /dev/video0 -c:v libx264 -an -f flv rtmp://localhost/myapp/mystream

Проиграть поток можно при помощи ffplay следующей командой:

ffplay rtmp://localhost/myapp/mystream

И, наконец, простой пример использования JWPlayer для проигрывания потока из браузера (полностью приведен в директории /test/www модуля):

<script type="text/javascript" src="/jwplayer/jwplayer.js"></script>
<div id="container">Loading the player ...</div>
    <script type="text/javascript">
        jwplayer("container").setup({
        modes: [
            {   type: "flash",
                src: "/jwplayer/player.swf",
                config: {
                    bufferlength: 1,
                    file: "mystream",
                    streamer: "rtmp://localhost/myapp",
                    provider: "rtmp",
                }
            }
        ]
});
</script>

Видео по запросу

Модуль поддерживает вещание видео-файлов в форматах mp4 и flv. Пример настройки:

application vod {
    play /var/videos;
}

При проигрывании, соответственно, надо указывать имена файлов, в остальном все аналогично живому вещанию.

ffplay rtmp://localhost/vod/movie1.mp4
ffplay rtmp://localhost/vod/movie2.flv

Ретрансляция

При построении распределенных систем важно иметь возможность ретрансляции потоков для балансировки нагрузки по большому числу серверов. Модуль реализует два типа ретрансляции: push и pull. Первый тип ретрансляции состоит в передаче на удаленный сервер локально публикуемого потока, а второй — в передаче удаленного
потока на локальный сервер. Пример push ретрансляции:

application myapp {
    live on;
    push rtmp://cdn.example.com;
}

В момент, когда начинается публикация по адресу rtmp://localhost/myapp/mystream, создается соединение с удаленным сервером и поток mystream публикуется далее на rtmp://cdn.example.com/myapp/mystream. При прекращении локальной публикации, соединение с cdn.example.com автоматически завершается.

Pull-ретрансляции выполняют обратную операцию:

application myapp {
    live on;
    pull rtmp://cdn.example.com;
}

В этом примере при появлении клиента, желающего локально проиграть поток rtmp://localhost/myapp/mystream, будет создано соединение с rtmp://cdn.example.com/myapp/mytstream и удаленный поток будет ретранслирован на локальный сервер, после чего станет доступным всем локальным клиентам. В тот момент, когда не останется ни одного клиента, соединение будет завершено.

Вещание на мобильные устройства (HLS)

Для вещания на устройста iPhone/iPad, а также на новые версии Android, используется протокол HLS (HTTP Live Streaming).

Протокол был разработан компанией Apple и представляет из себя «нарезанный» на куски MPEG-TS/H264/AAC поток, отдаваемый по HTTP. К потоку прилагается плейлист в формате m3u8. Отдавать HTTP nginx умеет отлично. Значит, надо лишь создать и обновлять плейлист и фрагменты HLS-потока, а также следить за удалением старых фрагментов. Для этого существует модуль nginx-rtmp-hls. Он находится в директории hls, однако не собирается по умолчанию т.к. требует библиотеки libavformat, входящей в пакет ffmpeg. Для сборки nginx с поддержкой HLS, надо добавить этот модуль явно при конфигурации:

./configure --add-module=/path/to/nginx-rtmp-module --add-module=/path/to/nginx-rtmp-module/hls

Так вышло, что некоторое время назад проект ffmpeg был форкнут. И теперь у нас есть два проекта — ffmpeg и avconv, а следовательно, тут же начали возникать проблемы совместимости (вернее, несовместимости) библиотек. Для сборки nginx-rtmp нужен оригинальный ffmpeg. В то же время, некоторые дистрибутивы Linux перешли на использование avconv, который для сборки не подойдет. На этот случай я написал подробнуюинструкцию.

Для генерации HLS достаточно указать следующие директивы:

application myapp {
    live on;
    hls on;
    hls_path /tmp/hls;
    hls_fragment 5s;
}

Ну и, наконец, в секции http{}, настроить отдачу всего, что связано с HLS:

location /hls {
    root /tmp;
}

Теперь публикуем поток mystream в приложение myapp, а в браузере iPhone набираем в строке адреса example.com/hls/mystream.m3u8. Кроме того, поток можно встроить в html тег video:

<video width="600" height="300" controls="1" autoplay="1" src="http://example.com/hls/mystream.m3u8"></video>

Отмечу, что для проигрывания на iPhone поток должен быть закодирован в H264 и AAC. Если исходный поток не соответствует этим условиям, необходимо настроить перекодирование.

Перекодирование

При вещании видео часто возникает необходимость перекодирования входящего потока в другое качество, либо другие кодеки. Эта задача по своей сути кардинально отличается от раздачи RTMP и, в отличие от последней, связана с высокими нагрузками на CPU, большим и активным потреблением памяти, часто опирается на использование многопоточности и является потенциально нестабильной. По этой причине она не должна включаться в основной процесс сервера, и в идеале должна выполняться отдельным процессом. Стоит отметить, что прекрасный инструмент для решения этой задачи уже существует — это все тот же ffmpeg. Он поддерживает огромное число кодеков, форматов и фильтров, позволяет использовать множество сторонних библиотек. Вместе с тем, он достаточно прост и активно поддерживается сообществом. Модуль nginx-rtmp предоставляет простой интерфейс для использования ffmpeg. Директива exec позволяет запустить внешнее приложение в момент публикации входящего потока. При завершении публикации приложение также принудительно завершается. Кроме того, поддерживается перезапуск запущенного приложения, если оно внезапно завершилось само.

application myapp {
    live on;
    exec ffmpeg -i rtmp://localhost/myapp/$name -c:v flv -c:a -s 32x32 -f flv rtmp://localhost/myapp32x32/$name;
}

application myapp32x32 {
    live on;
}

В этом примере ffmpeg используется для перекодирования входящего видео в Sorenson-H263, изменении его размера до 32х32 и публикации результата в приложение myapp32x32. Можно одновременно задать несколько директив exec, которые будут производить с потоком любые преобразования и публиковать результат в другие приложения как на локальный, так и на удаленный сервер. Директива поддерживает несколько переменных, среди которых $app (имя приложения) и $name (имя потока).

Воркеры и локальная ретрансляция

Как известно, nginx является однопоточным сервером. Для того, чтобы эффективно использовать все ядра современных процессоров, обычно он запускается в несколько воркеров. Обработка HTTP запросов как правило, происходит независимо друг от друга, и лишь в отдельных случаях (как, например, в случае с кешом), требуется осуществлять доступ к общим данным. Такие данные хранятся в разделяемой памяти.

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

rtmp_auto_push on;

Указывать ее надо в корневой секции конфигурационного файла. Отмечу, что локальные ретрансляции нужны только для живых вещаний.

Запись

Часто возникает необходимость записи на диск публикуемых потоков. Модуль позволяет записывать как отдельные данные из потока (аудио, видео, ключевые фреймы) так и поток целиком. Можно установить ограничение на размер файла, а также на число записываемых фреймов. Следующий пример включает запись первых 128К каждого потока.

record all;
record_path /tmp/rec;
record_max_size 128K;

Запись происходит в формате flv в директорию /tmp/rec.

Управлять записью можно в ручном режиме, включая и отключая ее при помощи http-запроса. Для этого используется control-модуль. Информацию о нем можно найти на сайте проекта.

Авторизация и бизнес-логика

Во многих случаях требуется ввести ограничения или учет операций публикации и проигрывания видео. Это бывает связано с логикой проекта, в котором он используется. Самый частый подобный случай — необходимость авторизации пользователя перед тем, как дать ему доступ к просмотру видео. Чтобы интегрировать бизнес-логику проекта в вещатель, в модуле реализованы HTTP-колбэки, такие как on_publish и on_play. Серверный код получает всю имеющуюся информацию о клиенте, включая его адрес, имя потока, адрес страницы и т.д. Если возвращается HTTP статус 2xx, то колбек считается завершенным успешно и работа клиента продолжается. В противном случае соединение разрывается.

on_publish http://example.com/check_publisher;
on_play http://example.com/check_player;

Статистика

В каждый момент времени к вашему серверу могут быть подсоединены тысячи клиентов. Естественно, нужен интерфейс, позвляющий увидеть их список, а также все основные характеристики публикуемых или проигрываемых ими потоков. Причем, важно, чтобы эту информацию можно быть как анализировать визуально, так и обрабатывать программно. Такой интерфейс у модуля nginx-rtmp существует. Чтобы его использовать, необходимо в http-секции nginx.conf прописать следующие директивы.

location /stat {
    rtmp_stat all;
    rtmp_stat_stylesheet stat.xsl;
}

location /stat.xsl {
    root /path/to/stat.xsl/dir/;
}

Директива rtmp_stat включает отдачу XML-документа с полным описанием live-клиентов, публикующих или проигрывающих потоки, списком приложений и серверов. Этот документ удобен для программной обработки, но для визуального анализа совершенно не годится. Чтобы иметь возможность просматривать список клиентов в браузере, директивой rtmp_stat_stylesheet задается относительный путь к таблице стилей XML (stat.xsl). Этот файл лежит в корне проекта. Надо настроить nginx на его раздачу по указанному урлу. Результат можно просматривать в браузере.

Существует возможность явно разрывать клиентские соединения. Для этого используется control-модуль, не описанный в статье.

Простое Интернет-радио

С самого начала статьи я постоянно употреблял слово «видео». Конечно, модуль может вещать не только видео, а также и аудио-потоки. Вот простой пример интернет-радиостанции на bash, вещающей mp3-файлы из /var/music. Этот поток может воспроизводить простой JWPlayer, встроенный в веб-страницу.

while true; do
    ffmpeg -re -i "`find /var/music -type f -name '*.mp3'|sort -R|head -n 1`" -vn -c:a libfaac -ar 44100 -ac 2 -f flv rtmp://localhost/myapp/mystream;
done

Совместимость

Модуль совместим со всем основным софтом, работающим с протоколом RTMP, включая FMS/FMLE, Wowza, Wirecast, протестирован с самыми распространенными флеш-проигрывателями JWPlayer, FlowPlayer, StrobeMediaPlayback, а также отлично работает с ffmpeg/avconv и rtmpdump.

Нагрузки

Модуль использует асинхронную однопоточную модель сервера nginx. Это позволяет добиться высокой производительности. Мы используем модуль на машинах Intel Xeon E5320/E5645 в режиме одного воркера. В этом режиме удается достигнуть максимальной пропускной способности имеющихся сетевых карт — 2Gbps. Пользователи модуля подтверждают сохранение этого же соотношения (2Gbps на ядро) в режиме локальной ретрансляции с несколькими воркерами. Практика показывает, что производительность вещателя обычно упирается в сеть, а не в CPU.

Прямых сравнений с другими продуктами я не проводил, однако, «тяжелые» многопоточные FMS, Wowza и Red5, будучи более функциональными, должны, в силу особенностей реализации, существенно проигрывать моему решению по числу одновременно подсоединенных клиентов и нагрузке на CPU. Это подтверждается многими пользователями, проводившими такие сравнения, в т.ч. в уже упомянутой мной статье.

Заключение

В заключение скажу, что модуль распространяется по лицензии BSD. Он собирается и работает под Linux, FreeBSD и MacOS. В статье описана лишь малая часть функционала nginx-rtmp-module. Желающие могут ознакомиться с проектом по ссылкам, приведенным ниже.

http://habrahabr.ru/post/162237/

Вещание онлайн-видео с помощью nginx

776px-Nginx-battleship.svgЧто такое онлайн-видео?

Под термином онлайн-видео я понимаю длительное вещание какого-то живого видеосигнала (к примеру, из телестудии). Традиционные средства отдачи видео (flv- и mp4-стриминг) в данном случае не работают, просто потому что файла, содержащего весь видеопоток, не существует.

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

RTMP-протокол

RTMP — Real Time Messaging Protocol (вики) — протокол, который обычно используется для раздачи живого видео- и аудиоконтента клиентам. Он удобен тем, что в AS3 есть его поддержка из коробки, требует не слишком много ресурсов на клиенте и поддерживает множество плюшек (например, трансляцию с переменными битрейтами и переключение клиентов на более высокое качество при наличии свободного канала).

NB: Помимо RTMP существует набор других протоколов вещания медиапотоков (RTSP, Apple HTTP Live Streaming и др.), но в этой статье они не рассматриваются.

Протокол RTMP — детище компании Adobe. Единственным официальным сервером, которым можно вещать RTMP-поток, является Adobe Flash Media Server. Его цена и производительность, к сожалению, оставляют желать лучшего, поэтому различными разработчиками были предприняты попытки создать более или менее совместимые альтернативные реализации протокола. К сожалению, у RTMP-протокола есть известные проблемы с лицензированием, к примеру, его официальная спецификация, если следовать ей строго, не позволяет написать работающий RTMP-сервер. Тем не менее, существует несколько реализаций:

  • Red5 — один из первых RTMP-серверов, написан на Java
  • Wowza — проприетарный RTMP-сервер, написан на Java. Помимо RTMP, поддерживает также RTSP, Apple HLS, и Smoothstreaming (Silverlight).
  • erlyvideo — свободный RTMP-сервер с отдельно распространяющимися проприетарными модулями, написан на Erlang. Проект пишется русскими программистами и активно развивается.

Java тормозит

В тестах, которые я проводил, Red5 и Wowza показали неприлично низкую производительность. При мегабитном видеопотоке Wowza при 1000 зрителей онлайн съедала уже около 300% процессорного времени (Intel Xeon E5607). Если требуется вещать хотя бы для 20000 человек онлайн, то нужно закупать 20 серверов? Это слишком дорого.

Что же делать?

Использовать неблокирующие операции. Тормоза в Wowza и Red5 следуют из-за далеко не самой оптимальной схемы обработки событий. Для реализации действительно быстрого стримингового сервера, нужно использовать эффективный метод обработки событий (для linux это epoll). Именно такую схему работы и реализовал Роман Арутюнян (блогgithub-профильrarutyunyan) в своём RTMP-сервере, реализованном как модуль к nginx.

nginx-rtmp-module

Достоинства:

  • Нереально шустрый. На том же физическом сервере, который я использовал для тестов Wowza, nginx выдержал 2500 мегабитных соединений на ядро, т.е. 10000 на весь сервер целиком.
  • Удобные конфиги :). После километровых XML-конфигов Wowza эти выглядят спасением.
  • Отзывчивость автора к фичреквестам.

Недостатки:

  • Проект молодой, наличествуют баги, которые, впрочем, оперативно исправляются.
  • Небольшая функциональность. Сервер вещает только в RTMP, перекодировка появилась буквально несколько дней назад, имеет статус экспериментальной и фактически является обёрткой над ffmpeg. UNIX-way во всей своей красе.
  • Нет многопоточности. Модуль может работать только в том случае, если nginx запускается с одним воркером. Для утилизации всех процессорных ядер нужно запускать несколько воркеров на разных IP-адресах и/или портах.

Многопоточность можно реализовать с помощью примерно такого костыля (Ubuntu):

    for ip in $(cat /etc/network/interfaces | grep address | awk '{print $2}') ; do
        touch /etc/nginx/nginx.$ip.conf
        cp /etc/nginx/nginx.conf.skel /etc/nginx/nginx.$ip.conf
        sed -i "s/%IPADDR%/${ip}/g" /etc/nginx/nginx.$ip.conf
        /usr/sbin/nginx -c /etc/nginx/nginx.$ip.conf
    done

При этом у вас должен быть написан скелет конфига с указанием %IPADDR% вместо IP-адреса. Например, такой:

worker_processes  1;

error_log   logs/error.%IPADDR%.log debug;

pid /var/run/nginx.%IPADDR%.pid;

worker_rlimit_nofile 65536;

events {
    worker_connections  16384;
}

rtmp {
        server {
                listen %IPADDR%:1935;
                chunk_size 4000;
                application live {
                        live on;
                        pull live stream %masterIP%;
                }
        }
}

http {
        server {
                listen %IPADDR%:8080;
                location /stat {
                        rtmp_stat all;
                        rtmp_stat_stylesheet stat.xsl;
                }
                location /stat.xsl {
                        root /srv/nginx/html;
                }
        }
}

Впрочем, автор обещает реализовать нормальную многопоточность в будущих релизах.

С помощью nginx-rtmp-module мне удалось полностью утилизировать 10-гигабитный канал. При этом основной проблемой стала вовсе не прожорливость самого nginx, а необходимость тюнинга сетевой карты и параметров ядра, чтобы software interrupts не съедали 100% CPU.

Ссылки по теме:

RTMP на Википедии
Wowza — официальный сайт
Erlyvideo — официальный сайт
Nginx-rtmp-module — проект на GitHub

Установка и настройка Wowza media server 2.2.4 и JW Player на Debian

wowza

Установка сервера

Топаем на оф сайт и качаем DEB версию. Пока качается ищем ключик (или покупаем…)

Установка самого сервера проста

sudo chmod +x WowzaMediaServer-2.2.4.deb.bin
sudo ./WowzaMediaServer-2.2.4.deb.bin

Т.к. требуется Java, ставим

apt-get install sun-java6-jre

Запускаем сервер

/etc/init.d/WowzaMediaServer start

 

Настройка сервера для вещания

Переходим в папку

cd /usr/local/WowzaMediaServer/content

Создаем папку для вещания, что типа плейлиста

mkdir simplevideostreaming

В папку content нужно будет класть ваше видео, либо сделать симлинк на content с вашим видео, и создать там папку simplevideostreaming.

 

Настройка плеера JW Player

Идем на оф сайт нажимаем Download JW Player, снимаем птички, ничего не заполняем, тыкаем Download Now. Плеер скачивается.

Распаковываем архив и кладем на сервер.

Пример для вещания

Кладем видео  video.flv в папку /usr/local/WowzaMediaServer/content

В папке которую мы распаковывали на сервер создаем тестовый html и вносим такие строки

<object id="player" style="display: block; margin-left: auto; margin-right: auto;" width="512" height="288" data="player.swf" type="application/x-shockwave-flash">
<param name="data" value="player.swf" />
<param name="name" value="player" />
<param name="allowfullscreen" value="true" />
<param name="allowscriptaccess" value="always" />
<param name="flashvars" value="streamer=rtmp://ВАШ_САЙТ:1935/simplevideostreaming&amp;file=video.flv&amp;image=preview.jpg&amp;provider=rtmp" />
<param name="src" value="player.swf" />
</object>

Подробнее:

streamer означает что видео будет потоковое, а не из файла

ВАШ_САЙТ — вписываем ваш URL  сайта где крутится сервер  Wowza

simplevideostreaming — это папка-плейлист который создавали в после установки сервера.

video.flv и preview.jpg — собственно видео и превью которое показывается до запуска видео.

Сохраняем и открываем, получаем такое…

jwplaeer-300x171

К плееру можно прикрутить переключение в HD, шарилку на Facebook и прочие плагины. Их можно найти тут. Если нужно бесплатно есть на трекерах.

 

P.S. Суть установки Wowza media server для меня была в перемотки длинных видео, т.к приходилось ждать пока все видео прогрузится. Здесь же промотка происходит как на YouTube с любого места.

Базовые стили и полезные CSS-сниппеты

6b42d35a44d89ccc7bfd12c089003c05В этой статье собраны полезные  и «правильные» стили и сниппеты, которые помогут ускорить процесс разработки сайта, а также оптимизировать верстку.

1. Базовая HTML5 конструкция

Основной код любой страницы, которому многие разработчики уделяют недостаточно внимания. Подключены jQuery 1.8.2 и HTML5shiv для корректного отображения в старых браузерах.

<!doctype html>
<html lang="en-US">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Default Page Title</title>
  <link rel="shortcut icon" href="favicon.ico">
  <link rel="icon" href="favicon.ico">
  <link rel="stylesheet" type="text/css" href="styles.css">
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<!--[if lt IE 9]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>

<body>

</body>
</html>

2. Сброс стандартных стилей браузеров

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

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
  outline: none;
}
html { height: 101%; } /* always display scrollbars */
body { font-size: 62.5%; line-height: 1; font-family: Arial, Tahoma, Verdana, sans-serif; }

article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }
ol, ul { list-style: none; }

blockquote, q { quotes: none; }
blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
strong { font-weight: bold; } 

input { outline: none; }

table { border-collapse: collapse; border-spacing: 0; }
img { border: 0; max-width: 100%; }

a { text-decoration: none; }
a:hover { text-decoration: underline; }

3. CSS3 градиенты

Представленный ниже код поможет кроссбраузерно отображать CSS-градиенты. Добавляется в нужный селектор, можно использовать rgba() для прозрачности.

background-color: #000;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#bbb', endColorstr='#000');
background-image: -webkit-gradient(linear, left top, left bottom, from(#bbb), to(#000));
background-image: -webkit-linear-gradient(top, #bbb, #000);
background-image: -moz-linear-gradient(top, #bbb, #000);
background-image: -ms-linear-gradient(top, #bbb, #000);
background-image: -o-linear-gradient(top, #bbb, #000);
background-image: linear-gradient(top, #bbb, #000);

4. CSS3 Transform

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

-webkit-transform: perspective(250) rotateX(45deg);
-moz-transform: perspective(250) rotateX(45deg);
-ms-transform: perspective(250) rotateX(45deg);
-o-transform: perspective(250) rotateX(45deg);
transform: perspective(250) rotateX(45deg);

5. Свой @font-face

Позволяет добавить собственные шрифты на страницу. Для конвертации в различные форматы полезно использовать сервис Font2Web.

@font-face{ 
  font-family: 'MyFont';
  src: url('myfont.eot');
  src: url('myfont.eot?#iefix') format('embedded-opentype'),
    url('myfont.woff') format('woff'),
    url('myfont.ttf') format('truetype'),
    url('myfont.svg#webfont') format('svg');
}

h1 { font-family: 'MyFont', sans-serif; }

6.  Мета-теги адаптивной верстки

Важные мета-теги для корректной работы адаптивного макета

<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="HandheldFriendly" content="true">

7. HTML5-медиа Конструкция подгрузки нескольких форматов видео и аудио для универсальной работы медиа-контента (убрать пробел в «s ource»)

<video poster="images/preview.png" width="1280" height="720" controls="controls" preload="none"> 
  <s_ource src="media/video.mp4" type="video/mp4"></s_ource> 
  <s_ource src="media/video.webm" type="video/webm"></s_ource> 
  <s_ource src="media/video.ogg" type="video/ogg"></s_ource>
</video>
<audio controls="controls" preload="none">
  <s_ource src="music.ogg" type="audio/ogg"></s_ource>
  <s_ource src="music.mp3" type="audio/mpeg"></s_ource>
</audio>

8.  Классы для упрощения верстки

Следующие сниппеты помогут сократить синтаксис при верстке. Техника широко применяется в различных CSS-фреймворках. Например управление свойством float:

.float-left /* Or whatever name you like */ {
    float: left;
}

.float-right /* Or whatever name you like */ {
    float: right;
}

Или отображением элементов:

.hide {
    display: none;
}

.show {
    display: block;
}

9. Сниппеты дизайна

Позволяют упрощать отображать контент. Простой пример: объявление в CSS-файле стилей шрифтов в зависимости от места на сайте, где располагается контент. Эта, вроде бы простая техника, часто игнорируется разработчиками.

.content {
    font: 1em/1.4 Segoe, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}

.title {
    font: 1.7em/1.2 Baskerville, "Baskerville old face", "Hoefler Text", Garamond, "Times New Roman", serif;
}

.code {
    font: 0.8em/1.6 Monaco, Mono-Space, monospace;
}

10. Сниппеты разработки

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

*, *:before, *:after {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}

Еще один полезный инструмент — это clearfix, помогающий избавиться от несоответствий отображения элементов верстки в разных браузерах:

.clearfix:before,
.clearfix:after {
    content: " ";
    display: table;
}

.clearfix:after {
    clear: both;
}

/* IE6/7 support */
.clearfix {
    *zoom: 1;
}

Слишком длинные URL могут ломать верстку страницы. Чтобы избежать этого, можно применять следующий сниппет (подробнее на css-tricks.com), не работает в Opera и IE ниже восьмой версии:

.break {
    -ms-word-break: break-all;
    word-break: break-all;

    word-break: break-word;

    -webkit-hyphens: auto;
    -moz-hyphens: auto;
    hyphens: auto;
}

.ellipsis {
    width: 250px;
    white-space: nowrap;
    overflow: hidden;
    -ms-text-overflow: ellipsis; /* Required for IE8 */
    -o-text-overflow: ellipsis; /* Required for Opera */
    text-overflow: ellipsis;
}

Переносы текста в теге pre:

pre {
    white-space: pre-wrap;       /* Chrome amp; Safari */
    white-space: -moz-pre-wrap;  /* Mozilla since 1999 */
    white-space: -pre-wrap;      /* Opera 4-6 */
    white-space: -o-pre-wrap;    /* Opera 7 */
    word-wrap: break-word;       /* Internet Explorer 5.5+ */
}

11. Подготовка страницы для печати

Перевод контента в черно-белые цвета, отображение подчеркивания у ссылок, отображение URL рядом в скобках:

@media print {
    * {
        background: none !important;
        color: black !important;
        box-shadow: none !important;
        text-shadow: none !important;

        /* Images, vectors and such */
        filter: Gray();                          /* IE4-8: depreciated */
        filter: url('desaturate.svg#grayscale'); /* SVG version for IE10, Firefox, Safari 5 and Opera */
        -webkit-filter: grayscale(100%);         /* Chrome + Safari 6 */
        -moz-filter: grayscale(100%);            /* Future proof */
        -ms-filter: grayscale(100%);             /* Future proof */
        -o-filter: grayscale(100%);              /* Future proof */
        filter: grayscale(100%);                 /* Future proof or polyfilled */
    }

    a {
        text-decoration: underline;
    }

    a[href]:after {
        content: " (" attr(href) ")"; 
    }

    a[href="#"],
    a[href="javascript:"] {
        content: "";
    }
}
<!-- SVG version of grayscale filter: desaturate.svg -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
    <filter id="grayscale">
        <feColorMatrix type="matrix" values="0.3333 0.3333 0.3333 0 0
            0.3333 0.3333 0.3333 0 0
            0.3333 0.3333 0.3333 0 0
            0  0  0  1 0"/>
    </filter>
</svg>

 

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

Взято с Хабра

Nginx: setup SSL reverse proxy (load balanced SSL proxy)

776px-Nginx-battleship.svgA reverse proxy is a proxy server that is installed in a server network. Typically, reverse proxies are used in front of Web servers such as Apache, IIS, and Lighttpd. How do I setup nginx web server as SSL reverse proxy?

When you’ve multiple backend web servers, encryption / SSL acceleration can be done by a reverse proxy. Nginx can act as SSL acceleration software. It provided the following benefits:

  • Easy of use : Nginx is easy to setup and upgrade.
  • Security : Nginx provide an additional layer of defense as Apache is behind the proxy. It can protect against common web-based attacks too.
  • Load Distribution : nginx use very little memory and can distribute the load to several Apache servers. It can even rewrite urls on fly.
  • Caching : Nginx act as a reverse proxy which offload the Web servers by caching static content, such as images, css, js, static html pages and much more.
  • Compression : Nginx can optimize and compress the content to speed up the load time.

Our Sample Setup

Internet--
         |
    =============                          |---- apache1 (192.168.1.15)
    | ISP Router|                          |
    =============                          |---- apache2 (192.168.1.16)
         |                                 |
         |                                 |---- db1 (192.168.1.17)
         |      |eth0 -> 192.168.1.11 ----/
         |-lb0==|                        /
         |      |eth1 -> 202.54.1.1:443-/
         |
         |      |eth0 -> 192.168.1.10 -\
         |-lb1==|                       \
                |eth1 -> 202.54.1.1:443--\     
                                          |---- apache1 (192.168.1.15)
                                          |
                                          |---- apache2 (192.168.1.16)
                                          |
                                          |---- db1 (192.168.1.17)
  • lb0 — Linux box directly connected to the Internet via eth1. This is master SSL load balancer.
  • lb1 — Linux box directly connected to the Internet via eth1. This is backup SSL load balancer. This will become active if master networking failed.
  • 202.54.1.1 A virtual IP address that moves between lb0 and lb1. It is managed by keepalived.
  • nginx — It is installed on lb0 and lb1.
  • SSL Certificate — You need to install ssl certificates on lb0 and lb1.

For demonstration purpose I’m going to use Self-signed SSL certificate, but you can use real SSL certificate signed by CAs.

+------+        +-------------+        +-------------------+
|Client| <----> |SSL-Nginx:443| <----> |Apache-HTTP_mode:80|
+------+        +-------------+        +-------------------+
  • You’ve the SSL connection between client and Nginx.
  • Then Nginx act as proxy server and makes unencrypted connection to Apache at port 80.
  • Nginx can cache all static file and other files.

Generating Self-signed Certificate
First, create required directories:

# cd /usr/local/nginx/conf
# mkdir ssl
# cd ssl

To create a private key, enter:

# openssl genrsa -des3 -out nixcraft.in.key 1024

Sample outputs:

openssl-private-key

Fig.01: OpenSSL — Create a Private Key
To create a CSR (Certificate Signing Request):

# openssl req -new -key nixcraft.in.key -out nixcraft.in.csr

Sample outputs:
openssl-create-csr

Fig.02: OpenSSL — Create a CSR (Certificate Signing Request)
Please enter your domain name that you want to associate with the certificate. For example, for the Command Name I entered nixcraft.in as I’m going to use https://nixcraft.in/.

How Do I Remove The Passphrase? (Optional)

You can remove the passphrase so nginx can start on boot without entering the passphrase. Type the following commands

# cp nixcraft.in.key nixcraft.in.key.bak
# openssl rsa -in nixcraft.in.key.bak -out nixcraft.in.key

Finally, you should see three files as follows (note I’ve created all files as vivek user and than moved lb0 and lb1 server /usr/local/ngnix/conf/ssl/ directory):

# ls -l

Sample outputs:

remove-ssl-passphrase

Fig.03: All the files in ssl directory

# openssl x509 -req -days 365 -in nixcraft.in.csr -signkey nixcraft.in.key -out nixcraft.in.crt

Sample outputs:

openssl-create-crt-file

Fig.04: Generating The Actual Self-signed SSL Certificate

How Do I Copy SSL Certificates Files To lb1?

You need to copy those files to lb1, enter:

# ssh root@lb1 mkdir /usr/local/ngnix/conf/ssl
# rsync -av /usr/local/ngnix/conf/ssl/* root@lb1:/usr/local/ngnix/conf/ssl/

Configure Nginx As SSL Reverse Proxy (lb0 and lb1)

Edit nginx.conf, enter (you need to edit files on both lb0 and lb1):

# vi /usr/local/ngnix/conf/nginx.conf

Edit / append as follows:

server {
	### server port and name ###
        listen          202.54.1.1:443;
	ssl 		on;
        server_name     nixcraft.in;

	### SSL log files ###
        access_log      logs/ssl-access.log;
        error_log       logs/ssl-error.log;

	### SSL cert files ###
        ssl_certificate      ssl/nixcraft.in.crt;
        ssl_certificate_key  ssl/nixcraft.in.key;

	### Add SSL specific settings here ###

	ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;
	ssl_ciphers RC4:HIGH:!aNULL:!MD5;
     	ssl_prefer_server_ciphers on;
     	keepalive_timeout    60;
	ssl_session_cache    shared:SSL:10m;
     	ssl_session_timeout  10m;

	### We want full access to SSL via backend ###
     	location / {
	        proxy_pass  http://nixcraft;

		### force timeouts if one of backend is died ##
        	proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

		### Set headers ####
                proxy_set_header        Accept-Encoding   "";
	        proxy_set_header        Host            $host;
	        proxy_set_header        X-Real-IP       $remote_addr;
	        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

		### Most PHP, Python, Rails, Java App can use this header ###
		#proxy_set_header X-Forwarded-Proto https;##
		#This is better##
	        proxy_set_header        X-Forwarded-Proto $scheme;
		add_header              Front-End-Https   on;

		### By default we don't want to redirect it ####
	        proxy_redirect     off;
      }

Save and close the file. Reload nginx:

# /usr/local/nginx/sbin/nginx -t
# /usr/local/nginx/sbin/nginx -s reload

Verify port is opened:

# netstat -tulpn | grep :443

How Do I Test And Debug SSL Certificates From The Shell Prompt?
Use the openssl command as follows:

$ openssl s_client -connect nixcraft.in:443

Or better use the following command:

$ openssl s_client -connect nixcraft.in:443 -CApath /usr/share/ssl-cert/ -servername nixcraft.in

How Do I Cache Common Files?
Edit nginx.conf and add as follows to cache common files:

location ~* \.(jpg|png|gif|jpeg|css|js|mp3|wav|swf|mov|doc|pdf|xls|ppt|docx|pptx|xlsx)$ {
        proxy_buffering           on;
        proxy_cache_valid 200 120m;
        expires 864000;
}

Save and close the file. Reload nginx:

# nginx -s reload

Nginx redirect all HTTP request to HTTPS rewrite rules

776px-Nginx-battleship.svgI have setup nginx as a secure reverse proxy server. How do I redirect all http://example.com/ requests (traffic) to https://example.com/ under nginx web server?

The syntax is as follows. You need to add the following in location or server directives:

 

if ($host ~* ^(example\.com|www\.example\.com)$ ){
rewrite ^/(.*)$ https://example.com/$1 permanent;
}

OR better use the following rewrite:

rewrite ^ https://$server_name$request_uri? permanent;

Edit nginx.conf, enter:

# vi nginx.conf

You need to define both http and https server as follows:

 
## our http server at port 80
server {
      listen      1.2.3.4:80 default;
      server_name example.com www.example.com;
      ## redirect http to https ##
      rewrite        ^ https://$server_name$request_uri? permanent;
}

## Our https server at port 443. You need to provide ssl config here###
server {
      access_log  logs/example.com/ssl_access.log main;
      error_log   logs/example.com/ssl_error.log;
      index       index.html;
      root        /usr/local/nginx/html;
      ## start ssl config ##
      listen      1.2.3.4:443 ssl;
      server_name example.com www.example.com;

     ## redirect www to nowww
      if ($host = 'www.example.com' ) {
         rewrite  ^/(.*)$  https://example.com/$1  permanent;
      }

    ### ssl config - customize as per your setup ###
     ssl_certificate      ssl/example.com/example.com_combined.crt;
     ssl_certificate_key  ssl/example.com/example.com.key_without_password;
     ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;
     ssl_ciphers RC4:HIGH:!aNULL:!MD5;
     ssl_prefer_server_ciphers on;
     keepalive_timeout    70;
     ssl_session_cache    shared:SSL:10m;
     ssl_session_timeout  10m;

    ## PROXY backend
      location / {
        add_header           Front-End-Https    on;
        add_header  Cache-Control "public, must-revalidate";
        add_header Strict-Transport-Security "max-age=2592000; includeSubdomains";
        proxy_pass  http://exampleproxy;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      }
}

Save and close the file. Reload or restart the nginx:

# nginx -s reload

Test it:

$ curl -I http://example.com
$ curl -I http://example.com/foo/bar/file.html

Sample outputs:

HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Sat, 01 Dec 2012 23:49:52 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Location: https://example.com/