<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Юникс и другие &#187; highload</title>
	<atom:link href="http://boombick.org/blog/posts/category/highload/feed" rel="self" type="application/rss+xml" />
	<link>http://boombick.org/blog</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Tue, 29 Nov 2011 22:14:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Собственный видеохостинг</title>
		<link>http://boombick.org/blog/posts/72</link>
		<comments>http://boombick.org/blog/posts/72#comments</comments>
		<pubDate>Thu, 21 May 2009 15:40:56 +0000</pubDate>
		<dc:creator>boombick</dc:creator>
				<category><![CDATA[*NIX]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[highload]]></category>
		<category><![CDATA[web-servers]]></category>

		<guid isPermaLink="false">http://boombick.org/blog/posts/72</guid>
		<description><![CDATA[Статья описывает процесс построения собственного видеохостинга (как, например, YouTube) на базе lighttpd с модулем mod_flv_streaming для трансляции потокового видео в формате .flv и модулем mod_secdownload для предотвращения хотлинкинга. В качестве проигрывателя мы возьмем FlowPlayer, который поддерживает mod_flv_streaming. Также мы опишем процесс перекодировки видео различных форматов (.mp4 .mov .mpg .3gp .mpeg .wmv .avi) в формат FLV, [...]]]></description>
			<content:encoded><![CDATA[<p>Статья описывает процесс построения собственного видеохостинга (как, например, YouTube) на базе lighttpd с модулем <em>mod_flv_streaming</em> для трансляции потокового видео в формате .flv и модулем<br />
<em>mod_secdownload</em> для предотвращения хотлинкинга. В качестве проигрывателя мы возьмем <noindex><a href="http://flowplayer.org/">FlowPlayer</a></noindex>, который поддерживает <em>mod_flv_streaming</em>. Также мы опишем процесс перекодировки видео различных форматов (.mp4 .mov .mpg .3gp .mpeg .wmv .avi) в формат FLV, который будет использоваться на нашем сайте<br />
<span id="more-72"></span><br />
<strong>Необходимые замечания</strong><br />
Перед описанием непосредственно процесса давайте определим используемые в статье некоторые параметры, которые могут отличаться от ваших (и наверняка отличаются :))<br />
Все происходит на сервере с адресом <code>server1.example.com</code> и IP-адресом <code>192.168.0.100</code>. Предполагается, что на сервере уже установлен lighttpd и php с поддержкой MySQL<br />
В Лайти также включена поддержка PHP. В качестве операционной системы мы используем Debian Etch<br />
Итак, приступим</p>
<p><strong>Устанавливаем LAME</strong><br />
<noindex><a href="http://lame.sourceforge.net/">LAME</a></noindex> &#8211; это mp3-декодер. Он необходим нам для того, чтобы в наших сконвертированных видеофайлах сохранялась аудиодорожка. В репозитриях Etch LAME отсутствует, поэтому мы будем собирать его вручную.<br />
Установим необходимые пакеты:</p>
<blockquote><p> apt-get install build-essential</p></blockquote>
<p>Затем скачаем и скомпилируем LAME</p>
<blockquote>
<pre>
cd /tmp
wget http://mesh.dl.sourceforge.net/sourceforge/lame/lame-3.97.tar.gz
tar xvfz lame-3.97.tar.gz
cd lame-3.97
./configure --enable-shared --prefix=/usr
make
make install</pre>
</blockquote>
<p><strong>Устанавливаем ffmpeg</strong><br />
Для перекодирования видео мы будем использовать <code>ffmpeg</code>. Установим его и плагины к нему</p>
<blockquote><p> apt-get install ffmpeg libavcodec0d libavformat0d libavifile-0.7c2 libpostproc0d libasound2-plugins avifile-player avifile-utils avifile-mad-plugin avifile-mjpeg-plugin avifile-vorbis-plugin</p></blockquote>
<p>Проблема LAME в Debian заключается в том, что он не поддерживает кодирование mp3 из-за патентных ограничений, а значит наше видео превратится в &#8220;немое кино&#8221;. Чтож, немного поправим пакет</p>
<blockquote><p> cd /usr/src/<br />
apt-get source ffmpeg<br />
cd ffmpeg-0.cvs20060823</p></blockquote>
<p>Отредактируем файл <code>debain/rules</code>. В начале файла есть две строки <code>confflags</code> с опциями сборки. Добавим в одну из них <code>--enable-mp3lame</code> и сохраним файл</p>
<blockquote>
<pre>
[...]
confflags += --enable-gpl --enable-pp --enable-pthreads --enable-mp3lame
confflags += --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm
[...]</pre>
</blockquote>
<p>Соберем пакет</p>
<blockquote><p> dpkg-buildpackage</p></blockquote>
<p><code>dpkg-buildpackage</code>, скорее всего, будет &#8220;ругаться&#8221; на отсутствующие пакеты, которые нужны ему для сборки <code>ffmpeg</code></p>
<blockquote>
<pre>
server1:/usr/src/ffmpeg-0.cvs20060823# dpkg-buildpackage
dpkg-buildpackage: source package is ffmpeg
dpkg-buildpackage: source version is 0.cvs20060823-8
dpkg-buildpackage: source changed by Sam Hocevar (Debian packages) <sam+deb@zoy.org>
dpkg-buildpackage: host architecture i386
dpkg-buildpackage: source version without epoch 0.cvs20060823-8
dpkg-checkbuilddeps: Unmet build dependencies: debhelper (&gt;= 4.0) quilt libogg-dev libvorbis-dev liba52-dev libdts-dev zlib1g-dev libsdl1.2-dev libfreetype6-dev libimlib2-dev texi2html libraw1394-dev libdc1394-13-dev libtheora-dev (&gt;&gt; 0.0.0.alpha4) libgsm1-dev
dpkg-buildpackage: Build dependencies/conflicts unsatisfied; aborting.
dpkg-buildpackage: (Use -d flag to override.)
server1:/usr/src/ffmpeg-0.cvs20060823#
</sam+deb@zoy.org></pre>
</blockquote>
<p>Если вы видите что-то подобное, то просто доставьте недостающие пакеты</p>
<blockquote><p> apt-get install debhelper quilt libogg-dev libvorbis-dev liba52-dev libdts-dev zlib1g-dev libsdl1.2-dev libfreetype6-dev libimlib2-dev texi2html libraw1394-dev libdc1394-13-dev libtheora-dev libgsm1-dev</p></blockquote>
<p>и запустите <code>dpkg-buildpackage</code> снова</p>
<blockquote><p> dpkg-buildpackage</p></blockquote>
<p>Процесс создания нового пакета займет некоторое время, а результатом его будут *.deb-файлы в директории <code>/usr/src</code>. Установим их командой</p>
<blockquote><p> cd ..<br />
dpkg -i *.deb</p></blockquote>
<p><strong>Устанавливаем flvtool2</strong><br />
При перекодировке видео неплохо было добавить некоторые метаданные в конечные файлы, например информацию о длительности, чтобы наш плеер смог корректно показывать счетчик времени. Для этого воспользуемся утилитой <noindex><a href="http://rubyforge.org/projects/flvtool2/">flvtool2</a></noindex>. Она написана на Ruby, поэтому сначала установим его</p>
<blockquote><p> apt-get install ruby</p></blockquote>
<p>Затем скачаем и установим flvtool2</p>
<blockquote><p> cd /tmp<br />
wget http://rubyforge.org/frs/download.php/17497/flvtool2-1.0.6.tgz<br />
tar xvfz flvtool2-1.0.6.tgz<br />
cd flvtool2-1.0.6<br />
ruby setup.rb config<br />
ruby setup.rb setup<br />
ruby setup.rb install</p></blockquote>
<p><strong>Подгототавливаем директории для видео</strong><br />
Корневой директорией для Лайти в нашем случае является <code>/var/www</code> (по умолчанию в Debian так и есть). Конечно же мы не хотим хранить оригинальные и сконвертированные видеофайлы в этой директории, иначе их смогут скачать все, кто захочет (зная прямую ссылку). Поэтому директорию с оригинальными видео (<code>/var/videos/incoming</code>) и сконвертированными (<code>/var/videos/flv</code>) мы расположим <strong>вне</strong> DocumentRoot</p>
<blockquote><p> mkdir -p /var/videos/incoming<br />
mkdir -p /var/videos/flv</p></blockquote>
<p>Вы (или ваши пользователи) смогут загружать файлы в <code>/var/videos/incoming</code> через FTP или WEB-интерфейс, а вы будете их перекодировать (вручную или автоматически) в FLV-формат и хранить в <code>/var/videos/flv</code></p>
<p><strong>Перекодирование видео</strong><br />
Предположим, что у нас есть файл <code>video.avi</code> в директории <code>/var/videos/incoming</code> (или .mp4 .mov .mpg .3gp .mpeg .wmv). Мы хотим сконвертировать его в <code>fideo.flv</code> и сохранить в <code>/var/videos/flv</code>. Разрешение конечного файла должно быть 320&#215;240, звук 44100 Hz и частота кадров 12 fps</p>
<blockquote><p> ffmpeg -i /var/videos/incoming/video.avi -s 320&#215;240 -ar 44100 -r 12 /var/videos/flv/video.flv</p></blockquote>
<p>(для дополнительной информации рекомендую обратиться к <code>man ffmpeg</code>). Это займет некоторое время, а вывод будет похож на</p>
<blockquote>
<pre>
server1:~# ffmpeg -i /var/videos/incoming/video.avi -s 320x240 -ar 44100 -r 12 /var/videos/flv/video.flv
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
  configuration:  --enable-gpl --enable-pp --enable-pthreads --enable-mp3lame --enable-vorbis --enable-libogg
 --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
  libavutil version: 0d.49.0.0
  libavcodec version: 0d.51.11.0
  libavformat version: 0d.50.5.0
  built on Aug 14 2007 15:02:25, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Input #0, avi, from '/var/videos/incoming/video.avi':
  Duration: 00:10:53.8, start: 0.000000, bitrate: 5455 kb/s
  Stream #0.0: Video: mpeg4, yuv420p, 1024x576, 24.00 fps(r)
  Stream #0.1: Audio: ac3, 48000 Hz, 5:1, 448 kb/s
Output #0, flv, to '/var/videos/flv/video.flv':
  Stream #0.0: Video: flv, yuv420p, 320x240, q=2-31, 200 kb/s, 12.00 fps(c)
  Stream #0.1: Audio: mp3, 44100 Hz, stereo, 64 kb/s
Stream mapping:
  Stream #0.0 -&gt; #0.0
  Stream #0.1 -&gt; #0.1
No accelerated IMDCT transform found
Press [q] to stop encoding
frame= 7847 q=2.0 Lsize=   21682kB time=653.8 bitrate= 271.7kbits/s
video:16061kB audio:5108kB global headers:0kB muxing overhead 2.427536%
server1:~#</pre>
</blockquote>
<p>Обратите особое внимание на секцию <code>Output</code> &#8211; там должно быть два потока: видео и аудио. Если вы видите там только видеопоток, то значит какие-то проблемы с аудиокодированием, внимательно проверьте наши инструкции по подключению LAME<br />
После кодирования добавим метаданные</p>
<blockquote><p> cat /var/videos/flv/video.flv | flvtool2 -U stdin /var/videos/flv/video.flv</p></blockquote>
<p><strong>Настройка Lighttpd</strong><br />
Теперь приступим к настройке Лайти. Откроем главный конфигурационный файл <code>/etc/lighttpd/lighttpd.conf</code>  активируем в нем модули <code>mod_secdownload</code> и <code>mod_flv_streaming</code>. Обратите внимание: крайне важно, чтобы модуль <code>mod_secdownload</code> шел <em>перед</em> модулем <code>mod_flv_streaming</code> в секции <code>server.modules</code>. В обратном случае будут проблемы с отображением видео FlowPlayer&#8217;ом</p>
<blockquote>
<pre>
[...]
server.modules              = (
            "mod_access",
            "mod_alias",
            "mod_accesslog",
            "mod_fastcgi",
#           "mod_rewrite",
#           "mod_redirect",
#           "mod_status",
#           "mod_evhost",
#           "mod_compress",
#           "mod_usertrack",
#           "mod_rrdtool",
#           "mod_webdav",
#           "mod_expire",
            "mod_secdownload",
            "mod_flv_streaming",
#           "mod_evasive"
 )
[...]</pre>
</blockquote>
<p>Также добавьте в конец конфига следующие строки</p>
<blockquote>
<pre>
[...]
flv-streaming.extensions = ( ".flv" )
secdownload.secret          = "somesecret"
secdownload.document-root   = "/var/videos/flv/"
secdownload.uri-prefix      = "/dl/"
secdownload.timeout         = 120</pre>
</blockquote>
<p>Не забудьте заменить <code>somesecret</code> на реальную парольную фразу<br />
Как работает <code>mod_secdownload</code>:<br />
На web-странице расположена ссылка примерно следующего вида:<br />
<em>&lt;uri-prefix&gt;/&lt;token&gt;/&lt;timestamp-in-hex&gt;/&lt;rel-path&gt; </em> (например: <em>/dl/d8a8cb150f7e5962f6a8443b0b6c6cc2/46c1d9f6/video.flv</em>)<br />
Где &lt;token&gt; &#8211; это md5-хэш от</p>
<ul>
<li>Секретной строки</li>
<li>&lt;rel-path&gt; (начинающегося с /)</li>
<li></li>
<li>&lt;timestamp-in-hex&gt;</li>
<p><code>mod_secdownload</code> перенаправит эту ссылку на файл, расположенный в  <code>secdownload.document-root</code> (который вне основного корня веб-сервера) и обеспечит доступ к нему в течении <code>secdownload.timeout</code> секунд. По истечении времени ссылка перестанет быть валидной и доступ будет закрыт.<br />
После установки FlowPalyer мы будем генерировать валидные сслыки для <code>mod_secdownload</code> при помощи PHP-скрипта. Дополнительную информацию по <code>mod_secdownload</code> можно получить <noindex><a href="http://trac.lighttpd.net/trac/wiki/Docs%3AModSecDownload">здесь</a></noindex><br />
Не забудьте перезапустить Лайти</p>
<blockquote><p> /etc/init.d/lighttpd restart</p></blockquote>
<p><strong>Установка FlowPlayer</strong><br />
Скачайте последнюю версию плеера с <noindex><a href="http://flowplayer.org/download">http://flowplayer.org/download</a></noindex> и приготовьте его к работе</p>
<blockquote><p> cd /tmp<br />
wget http://belnet.dl.sourceforge.net/sourceforge/flowplayer/flowplayer-1.19.zip<br />
unzip flowplayer-1.19.zip<br />
mv flowplayer /var/www/</p></blockquote>
<p><strong>Настройка FlowPlayer</strong><br />
Плеер установлен, теперь давайте создадим файл, с помощью которого можно будет посмотреть наше видео. В нашем примере это <code>/var/www/flowplayertest.php</code>, в котором расположены все параметры для запуска плеера и генерируются валидные ссылки для <code>mod_secdownload</code></p>
<blockquote>
<pre>
&lt;?php
$secret = "somesecret";
$uri_prefix = "/dl/";

# filename
$f = "/video.flv";

# current timestamp
$t = time();

$t_hex = sprintf("%08x", $t);
$m = md5($secret.$f.$t_hex);

?&gt;

&lt;object type="application/x-shockwave-flash" data="/flowplayer/FlowPlayerThermo.swf"&gt;
    width="320" height="256" id="FlowPlayer"&gt;
&lt;param name="allowScriptAccess" value="sameDomain"&gt;&lt;/param&gt;
&lt;param name="movie" value="/flowplayer/FlowPlayerThermo.swf"&gt;&lt;/param&gt;
&lt;param name="quality" value="high"&gt;&lt;/param&gt;
&lt;param name="scale" value="noScale"&gt;&lt;/param&gt;
&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;
&lt;param name="flashvars" value="config={videoFile: '&lt;?php printf('%s%s/%s%s', $uri_prefix, $m, $t_hex, $f, $f); ?&gt;', streamingServer: 'lighttpd', loop: 'false', useNativeFullScreen: true}"&gt;&lt;/param&gt;
&lt;/object&gt;</pre>
</blockquote>
<p>Не забудьте позаботиться о том, чтобы переменная <code>$secret</code> совпадала со значением, указанным в конфиге Лайти. Также должны совпадать <code>$uri_prefix</code> и <code>secdownload.uri-prefix</code>. Если все верно, то ссылки точно будут рабочими. В переменной <code>$f</code> содержится имя видеофайла, начинающееся со слеша (&#8220;/&#8221;). В нашем примере имя &#8220;жестко&#8221; зашито в код, но вы можете получать его из БД, например.<br />
В тэгах <code>&lt;object&gt;&lt;/object&gt;</code> содержатся конфигурационные параметры для FlowPlayer. Плеер может использовать разные скины (в нашем примере это <code>FlowPlayerThermo</code>), видео имеет размер 320&#215;240 и панель управления имеет высоту 16px. Пожтому мы указали ширину равной 320px и высоту (240+16) 256px. Если вы используете другой скин, поправьте эти параметры. За документацией по FlowPlayer обращайтесь на <noindex><a href="http://flowplayer.org/demos/index.html">официальный сайт</a></noindex><br />
В параметре <code>&lt;param name="flashvars"...</code> содержатся настройки окружения плеера. Важным параметром является <code>videoFile</code> &#8211; это ссылка на файл, которую генерирует наш скрипт. Другая важная опция &#8211; это <code>streamingServer: 'lighttpd'</code>, которая указывает, что для потоковой трансляции файла мы используем <code>mod_flv_streaming</code> Остальные опции (<code>loop, useNativeFullScreen</code>) являются необязательными. Например, если вы установите опцию <code>useNativeFullScreen</code> в <code>true</code> (это поддержка нативного полноэкранного режима для Flash Player 9), то вы должны включить в object строку &lt;param name=&#8221;allowFullScreen&#8221; value=&#8221;true&#8221; /&gt; и не можете использовать &lt;param name=&#8221;wmode&#8221; value=&#8221;transparent&#8221; /&gt;<br />
За дополнительными настройками FlowPlayer обратитесь к документации</p>
<p><strong>Проверим?</strong><br />
Зайдем браузером на <code>http://192.168.0.100/flowplayertest.php</code> &#8211; видео должно работать (со звуком)<br />
<a href="http://boombick.org/blog/wp-content/uploads/2009/05/2.png" title="2.png"><img src="http://boombick.org/blog/wp-content/uploads/2009/05/2.thumbnail.png" alt="2.png" /></a><br />
И даже в полноэкранном режиме<br />
<a href="http://boombick.org/blog/wp-content/uploads/2009/05/3.png" title="3.png"><img src="http://boombick.org/blog/wp-content/uploads/2009/05/3.thumbnail.png" alt="3.png" /></a><br />
Enjoy.</p>
<p><strong>Оригинал:</strong> <noindex><a href="http://howtoforge.org/video_streaming_lighttpd_flowplayer">http://howtoforge.org/video_streaming_lighttpd_flowplayer</a></noindex></ul>
]]></content:encoded>
			<wfw:commentRss>http://boombick.org/blog/posts/72/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Построение отказоустойчивого балансировщика нагрузки на базе Perlbal/Heartbeat</title>
		<link>http://boombick.org/blog/posts/48</link>
		<comments>http://boombick.org/blog/posts/48#comments</comments>
		<pubDate>Tue, 27 Jan 2009 09:32:37 +0000</pubDate>
		<dc:creator>boombick</dc:creator>
				<category><![CDATA[highload]]></category>

		<guid isPermaLink="false">http://boombick.org/blog/posts/48</guid>
		<description><![CDATA[В этой статье описывается процесс настройки отказоустойчивого двухузлового балансировщика нагрузки с активной/пассивной конфигурацией, поддержкой сессий и механизма Failover на базе Perlbal/Heartbeat под управлением Debian. Балансировщик работает между конечным пользователем и двумя backend-серверами, которые отдают некий контент. (В нашем примере это два сервера с установленным Apache). Балансировщик не только проксирует запросы к бэкэнду, он еще и [...]]]></description>
			<content:encoded><![CDATA[<p>В этой статье описывается процесс настройки отказоустойчивого двухузлового балансировщика нагрузки с активной/пассивной конфигурацией, поддержкой сессий и механизма Failover на базе Perlbal/Heartbeat под управлением Debian. Балансировщик работает между конечным пользователем и двумя backend-серверами, которые отдают некий контент. (В нашем примере это два сервера с установленным Apache). Балансировщик не только проксирует запросы к бэкэнду, он еще и проверяет состояние бэкэнда и, в случае отказа, перенаправляет запросы к другому серверу (failover). Вдобавок, ведется постоянный мониторинг бэкэнд-серверов при помощи Heartbeat и, если master-сервер &#8220;лежит&#8221;, то slave автоматически становится мастером. Ваши пользователи не заметят сбоев в работе сервиса. Perlbal поддерживает механизм сессий, так что вы можете использовать ПО, завязанное на них (например форумы, онлайн-магазины etc)<br />
<span id="more-48"></span><br />
<strong>Наша конфигурация</strong><br />
Мы используем следующую конфигурацию:</p>
<ul>
<li>Узел балансировки 1: lb1.example.com, IP адрес: 192.168.0.100</li>
<li>Узел балансировки 2: lb3.example.com, IP адрес: 192.168.0.101</li>
<li>Web-сервер 1: http1.example.com, IP адрес: 192.168.0.102</li>
<li>Web-сервер 2: http3.example.com, IP адрес: 192.168.0.103</li>
<li>Также нам понадобится виртуальный IP, который будет объединять узлы балансировки: 192.168.0.99</li>
</ul>
<p>Вот схематичное изображение нашего кусочка сети:</p>
<blockquote>
<pre>
    shared IP=192.168.0.99
 192.168.0.100  192.168.0.101 192.168.0.102 192.168.0.103
 -------+------------+--------------+-----------+----------
        |            |              |           |
     +--+--+      +--+--+      +----+----+ +----+----+
     | lb1 |      | lb2 |      |  http1  | |  http2  |
     +-----+      +-----+      +---------+ +---------+
     Perlbal      Perlbal      2 web servers (Apache)
     heartbeat    heartbeat</pre>
</blockquote>
<p>Общий (виртуальный) IP-адрес не является проблемой, если вы сами являетесь администратором своей сети и можете самостоятельно выделять IP-адреса. Если же вы используете публичные адреса, то вам придется найти хостера, который даст вам два сервера (узлы балансировки) в одной подсети. Для общего IP вы можете использовать свободный адрес из той же подсети.<br />
<code>http1</code> и <code>http2</code> &#8211; это &#8220;стандартные&#8221; сервера с Debian Etch и установленным Apache. (Конфигурация по умолчанию расположена в <code>/etc/apache2/sites-available/default</code>. Будьте внимательны, если вы используете другие пути, не забывайте делать на это поправку)</p>
<p><strong>Подготовка бэкэнда</strong><br />
Мы сконфигурируем Perlbal как прозрачный прокси. Т.е. он будет транслировать запросы к бэкэнд-серверам, сохраняя оригинальный адрес клиента в заголовке <code>X-Forwarded-For</code> Конечно же, мы хотим видеть в логах оригинальные адреса, а не IP наших балансировочных узлов. Поэтому немного поправим конфигурацию логов Apache. Отредактируем файл <code>/etc/apache2/apache2.conf</code><br />
<em>http1/http2:</em></p>
<blockquote>
<pre>
[...]
#LogFormat "%h %l %u %t \"%r\" %&gt;s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %&gt;s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
[...]</pre>
</blockquote>
<p>Затем перезапустим Apache</p>
<blockquote><p>/etc/init.d/apache2 restart</p></blockquote>
<p>И на этом настройка бэкэндов закончена. Перейдем к балансировочным узлам.</p>
<p><strong>Установка Perlbal</strong><br />
На момент написания статьи, perlbal не был доступен в репозиториях Debian, поэтому выполним его установку вручную.<br />
Сначала установим необходимые зависимости:</p>
<p><em>lb1/lb2:</em></p>
<blockquote><p> apt-get install build-essential unzip lynx ncftp perl</p></blockquote>
<p>Затем запустим оболочку Perl</p>
<blockquote><p>perl -MCPAN -e shell</p></blockquote>
<p>И выполним в ней три команды</p>
<blockquote><p> force install HTTP::Date<br />
install IO::AIO<br />
force install Perlbal</p></blockquote>
<p>Perlbal установлен. Нажмите <code>q</code> для выхода из оболочки Perl</p>
<p><strong>Настройка узлов балансировки</strong><br />
Конфигурационный файл Perlbal находится в <code>/etc/perlbal/perlbal.conf</code>, но его еще надо создать :) Создаем директорию и файл, и помещаем туда следующие строки:</p>
<blockquote><pre>
CREATE POOL webfarm
  POOL webfarm ADD 192.168.0.102:80
  POOL webfarm ADD 192.168.0.103:80

CREATE SERVICE balancer
  SET listen          = 192.168.0.99:80
  SET role            = reverse_proxy
  SET pool            = webfarm
  SET persist_client  = on
  SET persist_backend = on
  SET verify_backend  = on
ENABLE balancer
</pre>
</blockquote>
<p>Вероятно, вы захотите узнать больше об опциях конфигурации Perlbal. Лучший способ это сделать &#8211; скачать последнюю версию с <noindex><a href="http://code.google.com/p/perlbal/downloads/list">http://code.google.com/p/perlbal/downloads/list</a></noindex>, распоковать архив и обратить внимание на поддиректории <code>conf/</code> и <code>doc/</code>. Там вы найдете описание параметров и различные примеры конфигурации.</p>
<p><strong>Настройка Heartbeat</strong><br />
Мы настроили Perlbal на прослушивание нашего виртуального IP <code>192.168.0.99</code>, но кто-то должен &#8220;сообщить&#8221; узлам балансировки, что они также должны слушать этот IP. Это сделает Heartbeat. Установим его:<br />
<i>lb1/lb2:</i></p>
<blockquote><p>apt-get install heartbeat</p></blockquote>
<p>Для того, чтобы разрешить Perlbal слушать IP, мы должны добавить в <code>/etc/sysctl.conf</code> следующую строчку:</p>
<blockquote><pre>
[...]
net.ipv4.ip_nonlocal_bind=1</pre>
</blockquote>
<p>И выполнить команду</p>
<blockquote><p>sysctl -p</p></blockquote>
<p>Теперь создадим три конфигурационных файла для Heartbeat: <code>/etc/ha.d/authkeys</code>, <code>/etc/ha.d/ha.cf</code>, и <code>/etc/ha.d/haresources</code>.<code>/etc/ha.d/authkeys</code> и <code>/etc/ha.d/haresources</code> должны быть одинаковыми на <code>lb1</code> и <code>lb2</code>, а <code>/etc/ha.d/ha.cf</code> отличается всего одной строчкой!  </p>
<blockquote><p>vi /etc/ha.d/authkeys</p></blockquote>
<blockquote><pre>
auth 3
3 md5 somerandomstring
</pre>
</blockquote>
<p>somerandomstring &#8211; это пароль, который используется heartbeat на <code>lb1</code> и <code>lb2</code> для взаимной аутентификации. Задайте ваш собственный пароль. Вы можете использовать три различных механизма шифрования, в данном примере используется md5</p>
<p><code>/etc/ha.d/authkeys</code> должен быть доступен для чтения только пользователю <code>root</code><br />
<i>lb1/lb2:</i></p>
<blockquote><p>chmod 600 /etc/ha.d/authkeys</p></blockquote>
<p><i>lb1:</i></p>
<blockquote><p>vi /etc/ha.d/ha.cf</p></blockquote>
<blockquote><pre>
#
#       keepalive: how many seconds between heartbeats
#
keepalive 2
#
#       deadtime: seconds-to-declare-host-dead
#
deadtime 10
#
#       What UDP port to use for udp or ppp-udp communication?
#
udpport        694
bcast  eth0
mcast eth0 225.0.0.1 694 1 0
ucast eth0 192.168.0.101
#       What interfaces to heartbeat over?
udp     eth0
#
#       Facility to use for syslog()/logger (alternative to log/debugfile)
#
logfacility     local0
#
#       Tell what machines are in the cluster
#       node    nodename ...    -- must match uname -n
node    lb1.example.com
node    lb2.example.com
</pre>
</blockquote>
<p><i style="color:#F00">ВАЖНО:</i> В качестве имен узлов (nodenames) используется вывод команды</p>
<blockquote><p>uname -n </p></blockquote>
<p>на обоих узлах балансировки.<br />
Опции <code>udpport</code>, <code>bcast</code>, <code>mcast</code>, и <code>ucast</code> определяют способы коммуникации между узлами и задают параметры определения состояния узла. Вы можете оставить значения <code>udpport</code>, <code>bcast</code> и <code>mcast</code> такими же, как в примере, но опция <code>ucast</code> очень важна. В ней задается адрес второго узла балансировщика. В нашем примере это <code>192.168.0.101 (lb2.example.com)</code></p>
<p>На <code>lb2</code> все точно также, за исключением опции <code>ucast</code>, значением для которой должен выступать адрес <code>lb1</code><br />
<i>lb2:</i></p>
<blockquote><p>vi /etc/ha.d/ha.cf</p></blockquote>
<blockquote><pre>
#
#       keepalive: how many seconds between heartbeats
#
keepalive 2
#
#       deadtime: seconds-to-declare-host-dead
#
deadtime 10
#
#       What UDP port to use for udp or ppp-udp communication?
#
udpport        694
bcast  eth0
mcast eth0 225.0.0.1 694 1 0
ucast eth0 192.168.0.100
#       What interfaces to heartbeat over?
udp     eth0
#
#       Facility to use for syslog()/logger (alternative to log/debugfile)
#
logfacility     local0
#
#       Tell what machines are in the cluster
#       node    nodename ...    -- must match uname -n
node    lb1.example.com
node    lb2.example.com
</pre>
</blockquote>
<p><i>lb1/lb2:</i></p>
<blockquote><p>vi /etc/ha.d/haresources</p></blockquote>
<blockquote><pre>
lb1.example.com 192.168.0.99
</pre>
</blockquote>
<p>Первый параметр &#8211; это вывод</p>
<blockquote><p>uname -n</p></blockquote>
<p>Не имеет значения на каком узле вы создадите этот файл. Он указывает на виртуальный IP <code>192.168.0.99</code><br />
Теперь запустим Heartbeat на обоих узлах</p>
<blockquote><p>/etc/init.d/heartbeat start</p></blockquote>
<p>Затем выполняем<br />
<i>lb1:</i></p>
<blockquote><p>ip addr sh eth0</p></blockquote>
<p>Мы должны увидеть, что хост <code>lb1</code> слушает наш виртуальный IP</p>
<blockquote><pre>
lb1:~# ip addr sh eth0
2: eth0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:0c:29:a5:5b:93 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.100/24 brd 192.168.0.255 scope global eth0
    inet 192.168.0.99/24 brd 192.168.0.255 scope global secondary eth0:0
    inet6 fe80::20c:29ff:fea5:5b93/64 scope link
       valid_lft forever preferred_lft forever
lb1:~#
</pre>
</blockquote>
<p>Это можно проверить, выполнив команду <code>ifconfig</code></p>
<blockquote><pre>
lb1:~# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0C:29:A5:5B:93
          inet addr:192.168.0.100  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fea5:5b93/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:63983 errors:0 dropped:0 overruns:0 frame:0
          TX packets:31480 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:92604963 (88.3 MiB)  TX bytes:2689903 (2.5 MiB)
          Interrupt:177 Base address:0x1400

eth0:0    Link encap:Ethernet  HWaddr 00:0C:29:A5:5B:93
          inet addr:192.168.0.99  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          Interrupt:177 Base address:0x1400

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:56 errors:0 dropped:0 overruns:0 frame:0
          TX packets:56 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:3888 (3.7 KiB)  TX bytes:3888 (3.7 KiB)

lb1:~#</blockquote>
</pre>
<p><code>lb2</code> &#8211; это пассивный балансировочный узел. Он не должен слушать виртуальный IP, пока <code>lb1</code> &#8220;жив&#8221;. Проверим это:<br />
<i>lb2:</i></p>
<blockquote><p>ip addr sh eth0</p></blockquote>
<p>Вывод должен быть примерно таким:</p>
<blockquote><pre>
lb2:~# ip addr sh eth0
2: eth0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:0c:29:e0:78:92 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.101/24 brd 192.168.0.255 scope global eth0
    inet6 fe80::20c:29ff:fee0:7892/64 scope link
       valid_lft forever preferred_lft forever
lb2:~#
</pre>
</blockquote>
<blockquote><p>ifconfig</p></blockquote>
<p>не должен показать виртуальный IP</p>
<blockquote><pre>
eth0      Link encap:Ethernet  HWaddr 00:0C:29:E0:78:92
          inet addr:192.168.0.101  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fee0:7892/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:75127 errors:0 dropped:0 overruns:0 frame:0
          TX packets:42144 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:109669197 (104.5 MiB)  TX bytes:3393369 (3.2 MiB)
          Interrupt:169 Base address:0x1400

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:56 errors:0 dropped:0 overruns:0 frame:0
          TX packets:56 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:3888 (3.7 KiB)  TX bytes:3888 (3.7 KiB)

lb2:~#
</pre>
</blockquote>
<p><strong>Запускаем Perlbal</strong><br />
<i>lb1/lb2:</i></p>
<blockquote><p>perlbal &#8211;daemon</p></blockquote>
<p>Конечно же, нам не хочется каждый раз запускать демон руками. Поэтому пропишем его автоматический запуск в <code>/etc/rc.local</code></p>
<blockquote><pre>
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

/usr/local/bin/perlbal --daemon
exit 0</pre>
</blockquote>
<p>Для остановки демона выполните команду</p>
<blockquote><p>killall perlbal </p></blockquote>
<p><strong>Тестируем</strong><br />
Наш балансировочный узел настроен, запущен и готов к работе.<br />
Вы можете выполнять HTTP-запросы к виртуальному IP <code>192.168.0.99</code> (или к тому адресу или доменному имени, с которым работаете вы) и в ответ будете получать контент с бэкэнд-серверов.<br />
Для проверки отказоустойчивости и механизма failover остановите один из бэкэнд-серверов. Все запросы автоматически будут транслироваться к оставшемуся. Попробуйте остановить master-узел балансировщика (<code>lb1</code>), узел <code>lb2</code> сразу возьмет на себя роль активного узла. вы можете проверить это, выполнив<br />
<i>lb2:</i></p>
<blockquote><p>ip addr sh eth0</p></blockquote>
<p>Теперь в этом выводе присутствует виртуальный адрес:</p>
<blockquote><pre>
lb2:~# ip addr sh eth0
2: eth0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:0c:29:e0:78:92 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.101/24 brd 192.168.0.255 scope global eth0
    inet 192.168.0.99/24 brd 192.168.0.255 scope global secondary eth0:0
    inet6 fe80::20c:29ff:fee0:7892/64 scope link
       valid_lft forever preferred_lft forever
lb2:~#</pre>
</blockquote>
<p>Как только узел <code>lb1</code> будет вновь запущен, он опять будет выполнять функции master-узла.</p>
<p><strong>Поддержка виртуальных хостов в Perlbal</strong><br />
Perlbal поддерживает виртуальные хосты. Допустим, мы хотим чтобы все запросы на <code>*.site.com</code> обслуживались узлами с адресами <code>192.168.0.102</code> и <code>192.168.0.103</code>, а запросы на <code>*.example.com</code> узлами с адресами <code>192.168.0.104</code> и <code>192.168.0.105</code>. Вот как это будет выглядеть в конфиге <code>/etc/perlbal/perlbal.conf</code></p>
<blockquote><pre>
LOAD vhosts

CREATE POOL webfarm1
  POOL webfarm1 ADD 192.168.0.102:80
  POOL webfarm1 ADD 192.168.0.103:80

CREATE SERVICE balancer1
  SET role            = reverse_proxy
  SET pool            = webfarm1
  SET persist_client  = on
  SET persist_backend = on
  SET verify_backend  = on
ENABLE balancer1

CREATE POOL webfarm2
  POOL webfarm2 ADD 192.168.0.104:80
  POOL webfarm2 ADD 192.168.0.105:80

CREATE SERVICE balancer2
  SET role            = reverse_proxy
  SET pool            = webfarm2
  SET persist_client  = on
  SET persist_backend = on
  SET verify_backend  = on
ENABLE balancer2

CREATE SERVICE vdemo
  SET listen         = 192.168.0.99:80
  SET role           = selector
  SET plugins        = vhosts
  SET persist_client = on

  VHOST *.site.com     = balancer1
  VHOST *.example.com  = balancer2
ENABLE vdemo</pre>
</blockquote>
<p>Have a lot fun!</p>
<p><noindex><b>Оригинал:</b> <a href="http://howtoforge.org/setting-up-a-high-availability-load-balancer-with-perlbal-heartbeat-on-debian-etch">http://howtoforge.org/setting-up-a-high-availability-load-balancer-with-perlbal-heartbeat-on-debian-etch</a></noindex></p>
]]></content:encoded>
			<wfw:commentRss>http://boombick.org/blog/posts/48/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Интеграция APC (Alternative PHP Cache) с PHP5 и lighttpd</title>
		<link>http://boombick.org/blog/posts/44</link>
		<comments>http://boombick.org/blog/posts/44#comments</comments>
		<pubDate>Mon, 26 Jan 2009 20:23:11 +0000</pubDate>
		<dc:creator>boombick</dc:creator>
				<category><![CDATA[*NIX]]></category>
		<category><![CDATA[highload]]></category>
		<category><![CDATA[web-servers]]></category>

		<guid isPermaLink="false">http://boombick.org/blog/posts/44</guid>
		<description><![CDATA[Эта статья описывает установку и настройку APC для PHP5 и lighttpd, работающих на Debian Etch. APC &#8211; это свободная и бесплатная система кэширования и оптимизации байт-кода PHP. Похожие системы &#8211; это, например, eAccelerator и XCache Установка проводилась на Debian Etch с IP-адресом 192.168.0.100. Подразумевается, PHP и lighttpd уже установлены и настроены. Я использовал домашнюю директорию [...]]]></description>
			<content:encoded><![CDATA[<p>Эта статья описывает установку и настройку APC для PHP5 и lighttpd, работающих на Debian Etch. APC &#8211; это свободная и бесплатная система кэширования и оптимизации байт-кода PHP. Похожие системы &#8211; это, например, eAccelerator и XCache<br />
<span id="more-44"></span><br />
Установка проводилась на Debian Etch с IP-адресом <code>192.168.0.100</code>. Подразумевается, PHP и lighttpd уже установлены и настроены. Я использовал домашнюю директорию lighttpd по умолчанию (<code>/var/www</code>), но вы можете использовать любой виртуальный хост :) Правда, в этом случае, путь к info.php придется скорректировать в соответствии с настройками вашего сервера.</p>
<p><strong>Начнем</strong><br />
Перед установкой APC, мы посмотрим на конфигурацию PHP. Для этого мы создадим файл <code>info.php</code> в домашней директории Лайти (<code>/var/www</code> в нашем примере):</p>
<blockquote><p>vim /var/www/info.php</p></blockquote>
<p>Со следующим содержанием:</p>
<blockquote>
<pre>
&lt;?php
phpinfo();
?&gt;</pre>
</blockquote>
<p>И вызовем его через браузер, у нас он находится по адресу <code>http://192.168.0.100/info.php</code>:<br />
<a href="http://boombick.org/blog/wp-content/uploads/2009/01/1.png" title="1.png"><img src="http://boombick.org/blog/wp-content/uploads/2009/01/1.thumbnail.png" alt="1.png" /></a><br />
Как мы видим, у нас установлен PHP версии 5.2.0&#8230; Но APC нет :(<br />
<a href="http://boombick.org/blog/wp-content/uploads/2009/01/2.png" title="2.png"><img src="http://boombick.org/blog/wp-content/uploads/2009/01/2.thumbnail.png" alt="2.png" /></a></p>
<p><strong>Установка APC</strong><br />
APC &#8211; это расширение для PHP, доступное через <noindex><a href="http://pecl.php.net/">PECL</a></noindex>. PECL можно установить через php-pear, поэтому сначала давайте установим pear:</p>
<blockquote><p>apt-get install php-pear</p></blockquote>
<p>Кроме того, мы должны установить некоторые зависимости APC, чтобы PECL смог его собрать</p>
<blockquote><p>apt-get install php5-dev build-essential</p></blockquote>
<p>Ну вот и все, зависимости установлены, ставим APC</p>
<blockquote><p>pecl install apc</p></blockquote>
<p>Нюанс: на следующий вопрос ответьте &#8220;Нет&#8221; (No):</p>
<blockquote><p> [...]<br />
Use apxs to set compile flags (if using APC with Apache)? [yes] : <span style="color: #ff0000">&lt;&#8211; no</span><br />
[...]</p></blockquote>
<p>Теперь, когда APC установлен, создадим конфигурационный файл <code>/etc/php5/cgi/conf.d/apc.ini</code> Единственно необходимая опция &#8211; это, собственно, активация самого APC: <code>extension=apc.so</code> Остальные опции являются необязательными, подробнее можно прочитать на <noindex><a href="http://php.net/manual/en/ref.apc.php">http://php.net/manual/en/ref.apc.php</a></noindex></p>
<blockquote><p>vim /etc/php5/cgi/conf.d/apc.ini</p></blockquote>
<blockquote>
<pre>
extension=apc.so
apc.enabled=1
apc.shm_size=30</pre>
</blockquote>
<p>Это все :) Давайте снова зайдем на нашу информационную страничку (<code>http://192.168.0.100/info.php</code>) и убедимся, что APC работает<br />
<a href="http://boombick.org/blog/wp-content/uploads/2009/01/3.png" title="3.png"><img src="http://boombick.org/blog/wp-content/uploads/2009/01/3.thumbnail.png" alt="3.png" /></a></p>
<p><noindex><strong>Оригинал:</strong> <a href="http://howtoforge.org/integrating-apc-into-php5-and-lighttpd-debian-etch">http://howtoforge.org/integrating-apc-into-php5-and-lighttpd-debian-etch</a></noindex></p>
]]></content:encoded>
			<wfw:commentRss>http://boombick.org/blog/posts/44/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	<img style='margin:0;padding:0;border:0;' width='1px' height='1px' src="http://boombick.org/blog/wp-content/plugins/mystat/mystat.php?act=time_load&id=0&rnd=191227025" /></channel>
</rss>

