ХАКЕР 04/ /171/ 2013 Новые горизонты135С помощью такой конфигурации мы получим сразу два вещателя, одиниз которых будет доступен по адресу rtmp://сайт/rtmp, а второй, вещающийв качестве 320 × 240, — по адресу rtmp://сайт/rtmp-320x240. Далее на сайтможно повесить флеш-плеер и кнопки выбора качества, которые будут подсовыватьплееру тот или иной адрес вещателя.Ну и напоследок пример вещания музыки в сеть:while true; doffmpeg -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/rtmp/stream;doneGIT-ПРОКСИСистема контроля версий Git способна обеспечивать доступ к репозиториямне только по протоколам Git и SSH, но и по HTTP. Когда-то реализациядоступа по HTTP была примитивной и неспособной обеспечить полноценнуюработу с репозиторием. С версии 1.6.6 ситуация изменилась, и сегодняэтот протокол можно использовать, чтобы, например, обойти ограничениябрандмауэров как с той, так и с другой стороны соединения либо для созданиясобственного Git-хостинга с веб-интерфейсом.К сожалению, официальная документация рассказывает только об организациидоступа к Git средствами веб-сервера Apache, но, так как самареализация представляет собой внешнее приложение со стандартным CGIинтерфейсом,ее можно прикрутить практически к любому другому серверу,включая lighttpd и, конечно же, nginx. Для этого не потребуется ничего, кромесамого сервера, установленного Git и небольшого FastCGI-сервера fcgiwrap,который нужен, потому что nginx не умеет работать с CGI напрямую, но умеетвызывать скрипты с помощью протокола FastCGI.Вся схема работы будет выглядеть следующим образом. Сервер fcgiwrapбудет висеть в фоне и ждать запроса на исполнение CGI-приложения.Nginx, в свою очередь, будет сконфигурирован на запрос исполнения CGIбинарникаgit-http-backend через FastCGI-интерфейс каждый раз при обращениик указанному нами адресу. Получив запрос, fcgiwrap исполняет githttp-backendс указанными CGI-аргументами, переданными Git-клиентом,и возвращает результат.Чтобы реализовать такую схему, сначала установим fcgiwrap:$ sudo apt-get install fcgiwrapНастраивать его не нужно, все параметры передаются по протоколуFastCGI. Запущен он будет тоже автоматически. Поэтому остается только настроитьnginx. Для этого создаем файл /etc/nginx/sites-enabled/git (если такогокаталога нет, можно писать в основной конфиг) и пишем в него следующее:# vi /etc/nginx/sites-enabled/gitserver {# Висим на порту 8080listen 8080;# Адрес нашего сервера (не забудь добавить запись# в DNS)server_name git.example.ru;# Логиaccess_log /var/log/nginx/git-http-backend.access.log;error_log /var/log/nginx/git-http-backend.error.log;# Основной адрес для анонимного доступаlocation / {# При попытке загрузки отправляем юзера# на приватный адресif ($arg_service ~* "git-receive-pack") {rewrite ^ /private$uri last;}include /etc/nginx/fastcgi_params;# Адрес нашего git-http-backendfastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;# Адрес Git-репозиторияfastcgi_param GIT_PROJECT_ROOT /srv/git;# Адрес файлаfastcgi_param PATH_INFO $uri;# Адрес сервера fcgiwrapfastcgi_pass 127.0.0.1:9001;}# Адрес для доступа на записьlocation ~/private(/.*)$ {}}# Полномочия юзераauth_basic "git anonymous read-only,authenticated write";# HTTP-аутентификация на основе htpasswdauth_basic_user_file /etc/nginx/htpasswd;# Настройки FastCGIinclude /etc/nginx/fastcgi_params;fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;fastcgi_param GIT_PROJECT_ROOT /srv/git;fastcgi_param PATH_INFO $1;fastcgi_pass 127.0.0.1:9001;Этот конфиг предполагает три важные вещи:1. Адресом репозитория будет /srv/git, поэтому выставляем соответствующиеправа доступа:$ sudo chown -R www-data:www-data /srv/git2. Сам репозиторий должен быть открыт на чтение анонимусами и позволятьаплоад по HTTP:$ cd /srv/git$ git config core.sharedrepository true$ git config http.receivepack true3. Аутентификация осуществляется с помощью файла htpasswd, нужно егосоздать и добавить в него пользователей:$ sudo apt-get install apache2-utils$ htpasswd -c /etc/nginx/htpasswd user1$ htpasswd /etc/nginx/htpasswd user2...На этом все, перезагружаем nginx:$ sudo service nginx restartДалее можно подключиться к репозиторию с помощью клиента Git.МИКРОКЕШИРОВАНИЕПредставим себе ситуацию с динамичным, часто обновляемым сайтом, которыйвдруг начинает получать очень большие нагрузки (ну попал он на страницуодного из крупнейших новостных сайтов) и перестает справляться с отдачейконтента. Грамотная оптимизация и реализация правильной схемыкеширования займет долгое время, а проблемы нужно решать уже сейчас.Что мы можем сделать?Есть несколько способов выйти из этой ситуации с наименьшими потерями,однако наиболее интересную идею предложил Фенн Бэйли (FennBailey, fennb.com). Идея в том, чтобы просто поставить перед сервером nginxи заставить его кешировать весь передаваемый контент, но не просто кешировать,а всего на одну секунду. Изюминка здесь в том, что сотни и тысячипосетителей сайта в секунду, по сути, будут генерировать всего одно обращениек бэкенду, получая в большинстве своем кешированную страницу.При этом разницу вряд ли кто-то заметит, потому что даже на динамичномсайте одна секунда обычно ничего не значит.Конфиг с реализацией этой идеи будет выглядеть не так уж и сложно:# vi /etc/nginx/sites-enabled/cache-proxy# Настройка кешаproxy_cache_path /var/cache/nginx levels=1:2keys_zone=microcache:5m max_size=1000m;server {Когда-то реализация доступапо HTTP была примитивнойи неспособной обеспечить полноценнуюработу с репозиторием
136SYN/ACK ХАКЕР 04/ 171/ 2013listen 80;server_name example.com;# Кешируемый адресlocation / {# Кеш включен по умолчаниюset $no_cache "";# Отключаем кеш для всех методов, кроме GET# и HEADif ($request_method !~ ^(GET|HEAD)$) {set $no_cache "1";}# В случае если клиент загружает контент на сайт# (no_cache = 1), делаем так, чтобы отдаваемые# ему данные не кешировались в течение двух# секунд и он смог увидеть результат загрузкиif ($no_cache = "1") {add_header Set-Cookie "_mcnc=1; Max-Age=2;Path=/";add_header X-Microcachable "0";}if ($http_cookie ~* "_mcnc") {set $no_cache "1";}}}# Включаем/отключаем кеш в зависимости# от состояния переменной no_cacheproxy_no_cache $no_cache;proxy_cache_bypass $no_cache;# Проксируем запросы на реальный серверproxy_pass http://appserver.example.ru;proxy_cache microcache;proxy_cache_key $scheme$host$request_method$request_uri;proxy_cache_valid 200 1s;# Защита от проблемы Thundering herdproxy_cache_use_stale updating;# Добавляем стандартные хедерыproxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;# Не кешируем файлы размером больше 1 Мбproxy_max_temp_file_size 1M;Особое место в этом конфиге занимает строка «proxy_cache_use_staleupdating;», без которой мы бы получили периодические всплески нагрузкина бэкенд-сервер из-за запросов, пришедших во время обновлениякеша. В остальном все стандартно и должно быть понятно без лишнихобъяснений.ПРИБЛИЖЕНИЕ ПРОКСИ К ЦАНесмотря на повсеместное глобальное увеличение скоростей интернета,физическая удаленность сервера от целевой аудитории все равно продолжаетиграть свою роль. Это значит, что, если русский сайт крутится на сервере,расположенном где-нибудь в Америке, скорость доступа к нему будетаприори ниже, чем с российского сервера с такой же шириной канала(естественно, если закрыть глаза на все остальные факторы). Другое дело,что размещать серверы за рубежом зачастую выгоднее, в том числе и в планеобслуживания. Поэтому для получения профита, в виде более высокихскоростей отдачи, придется идти на хитрость.В январском отчете компании Netcraft nginx вырвался на второе местоОдин из возможных вариантов: разместить основной производительныйсервер на Западе, а не слишком требовательный к ресурсам фронтенд, отдающийстатику, развернуть на территории России. Это позволит без серьезныхзатрат выиграть в скорости. Конфиг nginx для фронтенда в этом случаебудет простой и всем нам знакомой реализацией прокси:# vi /etc/nginx/sites-enabled/proxy# Храним кеш 30 дней в 100-гигабайтном хранилищеproxy_cache_path /var/cache/nginx levels=1:2keys_zone=static:32m inactive=30d max_size=100g;server {listen 80;server_name example.com;}# Собственно, наш проксиlocation ~* \.(jpg|jpeg|gif|png|ico|css|midi|wav|bmp|js|swf|flv|avi|djvu|mp3)$ {# Адрес бэкендаproxy_pass back.example.com:80;proxy_redirect off;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;proxy_buffer_size 16k;proxy_buffers 32 16k;proxy_cache static;proxy_cache_valid 30d;proxy_ignore_headers "Cache-Control" "Expires";proxy_cache_key "$uri$is_args$args";proxy_cache_lock on;}ВЫВОДЫСегодня с помощью nginx можно решить множество самых разных задач, многиеиз которых вообще не связаны с сервером и протоколом HTTP. Почтовыйпрокси, потоковое вещание и интерфейс Git — это только часть таких задач. zФизическая удаленность сервера от аудитории по-прежнему важна. Если русскийсайт крутится на сервере, расположенном в Америке, скорость доступак нему будет априори ниже, чем с российского сервера с такой же ширинойканала (естественно, если закрыть глаза на все остальные факторы)