<?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>Insight IT &#187; PostgreSQL</title>
	<atom:link href="http://www.insight-it.ru/tag/postgresql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.insight-it.ru</link>
	<description>Информационные технологии</description>
	<lastBuildDate>Tue, 31 Jan 2012 09:34:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Архитектура DISQUS</title>
		<link>http://www.insight-it.ru/masshtabiruemost/arkhitektura-disqus/</link>
		<comments>http://www.insight-it.ru/masshtabiruemost/arkhitektura-disqus/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 00:37:19 +0000</pubDate>
		<dc:creator>Иван Блинков</dc:creator>
				<category><![CDATA[Масштабируемость]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[DISQUS]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[Fabric]]></category>
		<category><![CDATA[Ganglia]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[HAProxy]]></category>
		<category><![CDATA[heartbeat]]></category>
		<category><![CDATA[Hudson]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Memcached]]></category>
		<category><![CDATA[pgbouncer]]></category>
		<category><![CDATA[pgFouine]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Pyflakes]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[Slony]]></category>
		<category><![CDATA[syslog-ng]]></category>
		<category><![CDATA[WSGI]]></category>
		<category><![CDATA[Архитектура DISQUS]]></category>

		<guid isPermaLink="false">http://www.insight-it.ru/?p=893</guid>
		<description><![CDATA[DISQUS &#8212; самая популярная система комментирования и одновременно самое большое в мире Django-приложение. Она установлена более чем на полумиллионе сайтов и блогов, в том числе и очень крупных, таких как Engadget, CNN, MTV, IGN. Основной особенностью в её реализации является тот факт, что DISQUS не является тем сайтом, который хотят увидеть пользователи, он лишь предоставляет [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:left; margin:0 1em;" class="size-full wp-image-894 alignleft" title="DISQUS" src="http://www.insight-it.ru/wp-content/uploads/2011/03/disqus.jpg" alt="DISQUS" width="256" height="256" /> <a href="http://www.disqus.com" target="_blank">DISQUS</a> &#8212; самая популярная система комментирования и одновременно самое большое в мире Django-приложение. Она установлена более чем на полумиллионе сайтов и блогов, в том числе и очень крупных, таких как Engadget, CNN, MTV, IGN. Основной особенностью в её реализации является тот факт, что DISQUS не является тем сайтом, который хотят увидеть пользователи, он лишь предоставляет механизмы комментирования, авторизации и интеграции с социальными сетями. Пики нагрузки возникают одновременно c появлением какой-то шумихи в Интернете, что достаточно непредсказуемо. Как же им удается справляться с этой ситуацией?<span id="more-893"></span></p>
<h2 style="padding-top:2em;">Платформа</h2>
<ul>
<li><a href="/tag/linux/" target="_blank">Linux</a> &#8212; операционная система</li>
<li><a href="/tag/python/" target="_blank">Python</a> &#8212; язык программирования</li>
<li><a href="/tag/django/" target="_blank">Django</a> &#8212; основной framework</li>
<li><a href="/tag/django/" target="_blank"></a><a href="/tag/apache/" target="_blank">Apache 2.2</a> + <a href="/tag/wsgi/" target="_blank">mod_wsgi</a> &#8212; веб-сервер</li>
<li><a href="/tag/wsgi/" target="_blank"></a><a href="/tag/postgresql/" target="_blank">PostgreSQL</a> &#8212; СУБД</li>
<li><a href="/tag/postgresql/" target="_blank"></a><a href="/tag/memcached/" target="_blank">memcached</a> &#8212; кэширование</li>
<li><a href="/tag/memcached/" target="_blank"></a><a href="/tag/haproxy/" target="_blank">HAProxy</a> &#8212; балансировка нагрузки</li>
<li><a href="/tag/pgbouncer/" target="_blank"></a><a href="/tag/slony/" target="_blank">Slony</a> &#8212; репликация данных</li>
<li><a href="/tag/slony/" target="_blank"></a><a href="/tag/heartbeat/" target="_blank">heartbeat</a> &#8212; обеспечение доступности</li>
</ul>
<h2>Статистика</h2>
<ul>
<li>До 17 тысяч запросов в секунду</li>
<li>500 000 сайтов</li>
<li>15 миллионов зарегистрированных пользователей</li>
<li>75 миллионов комментариев</li>
<li>250 миллионов посетителей (на август 2010г.)</li>
</ul>
<h2>Основные трудности</h2>
<ul>
<li>Непредсказуемость нагрузки (основными причинами шумихи в Интернете являются катастрофы и выходки знаменитостей)</li>
<li>Обсуждения никогда не теряют актуальность (нельзя держать в кэше все дискуссии с 2008 года)</li>
<li>Нельзя угадать на каком сайте из тысяч возникнет пик трафика</li>
<li>Персональные настройки, динамическое разбиение на страницы и сортировки снижают эффективность кэширования</li>
<li>Высокая доступность (из-за разнообразия сайтов и их аудитории сложно запланировать технические работы)</li>
</ul>
<h2>Архитектура</h2>
<p><div id="attachment_895" class="wp-caption aligncenter" style="width: 607px"><a href="http://www.insight-it.ru/wp-content/uploads/2011/03/disqus_architecture.jpeg"><img class="size-full wp-image-895" title="Архитектура DISQUS" src="http://www.insight-it.ru/wp-content/uploads/2011/03/disqus_architecture.jpeg" alt="Архитектура DISQUS" width="597" height="918" /></a><p class="wp-caption-text">Архитектура DISQUS</p></div></p>
<ul>
<li><strong>Оборудование</strong>, в сумме около 100 серверов:
<ul>
<li>30% веб-серверов (Apache + mod_wsgi)</li>
<li>10% серверов баз данных (PostgreSQL)</li>
<li>25% кэш-серверов (memcached)</li>
<li>20% балансировка нагрузки и обеспечение доступности (HAProxy + heartbeat)</li>
<li>15% прочие сервера (Python скрипты)</li>
</ul>
</li>
<li><strong>Балансировка нагрузки</strong>:
<ul>
<li>HAProxy:
<ul>
<li>Высокая производительность</li>
<li>Интеллектуальная проверка доступности</li>
<li>Неплохая статистика</li>
</ul>
</li>
</ul>
</li>
<li><strong>Репликация</strong>:
<ul>
<li>Используется Slony-I</li>
<li>Основана на триггерах</li>
<li>Master/Slave для обеспечения большего объема операций чтения</li>
</ul>
</li>
<li><strong>Высокая доступность</strong>:
<ul>
<li>heartbeat</li>
<li>Пассивная копия мастер баз данных на случай сбоя основной</li>
</ul>
</li>
<li><strong>Партиционирование</strong>:
<ul>
<li>Реализовано на уровне кода</li>
<li>Простая реализация, быстрые положительные результаты</li>
<li>Два метода разделения данных:
<ul>
<li><em>Вертикальное:</em>
<ul>
<li>Создание нескольких таблиц с меньшим количеством колонок вместо одной (она же нормализация)</li>
<li>Позволяет разделять базы данных</li>
<li>Данные объединяются в коде (медленнее, чем на уровне СУБД, но не намного)</li>
<li>Бартер производительности на масштабируемость</li>
<li>Более эффективное кэшировние</li>
<li>Механизм роутеров в Django позволяет достаточно легко реализовать данный функционал</li>
</ul>
</li>
<li><em>Горизонтальное:</em>
<ul>
<li>Некоторые сайты имеют очень большие массивы данных</li>
<li>Партнеры требуют повышенного уровня доступности</li>
<li>Помогает снижать загрузку по записи на мастер базе данных</li>
<li>В основном используется все же вертикальное партиционирование</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>Производительность базы данных</strong>:
<ul>
<li>Особое внимание уделяется тому, чтобы индексы помещались в оперативную память</li>
<li>Логгирование медленных запросов (автоматизировано с помощью syslog-ng + pgFouine + cron)</li>
<li>Использование пулов соединений (Django не умеет этого, используется pgbouncer, позволяет экономить на ресурсоемких операциях установления и прекращения соединений)</li>
<li>Оптимизация QuerySet&#8217;ов:
<ul>
<li>Не используется чистый SQL</li>
<li>Встроенный кэш позволяет выделять части выборки</li>
<li>Но это не всегда нужно, они убрали этот кэш</li>
</ul>
</li>
<li>Атомарные операции:
<ul>
<li>Поддерживают консистентность данных</li>
<li>Использование update(), так как save() не является thread-safe</li>
<li>Отлично работают для таких вещей, как счетчики</li>
</ul>
</li>
<li>Транзакции:
<ul>
<li>TransactionMiddleware поначалу использовалось, но со временем стало обузой</li>
<li>В postgrrsql_psycopg2 есть опция autocommit:
<ul>
<li>Это означает что каждый запрос выполняется в отдельной транзакции</li>
<li>Обработка каждого пользовательского HTTP-запроса не начинает новую транзакцию</li>
<li>Но все же транзакции из нескольких операций записи в СУБД нужны (сохранение нескольких объектов одновременно и полный откат в  случае ошибки)</li>
<li>В итоге все HTTP-запросы по-умолчанию начинаются в режиме autocommit, но в случае необходимости  переключаются в транзакционный режим</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>Отложенные сигналы</strong>:
<ul>
<li>Постановка в очередь низкоприоритетных задач (даже если они не длинные по времени)</li>
<li>Асинхронные сигналы очень удобны для разработчика (но не так, как настоящие сигналы)</li>
<li>Модели отправляются в очередь в сериализованном виде</li>
</ul>
</li>
<li><strong>Кэширование</strong>:
<ul>
<li>Используется memcached</li>
<li>Новый pylibmcна основе libmemcached в качестве клиента (проекты django-pylibmc и django-newcache)</li>
<li>Настраиваемые алгоритмы поведения клиента</li>
<li>Используется _auto_reject_hosts и _retry_timeout для предотвращения повторных подключений к вышедшим из строя кэш-серверам</li>
<li>Алгоритм размещения ключей: консистентное хэширование на основе libketama</li>
<li>Существует проблема, когда одно очень часто используемое значение в кэше инвалидируется:
<ul>
<li>Множество клиентов одновременно пытаются получить новое значение из СУБД одновременно</li>
<li>В большинстве случаев правильным решением было бы вернуть большинству устаревшие данные и позволить одному клиенту обновить кэш</li>
<li>django-newcache и MintCache умеют это делать</li>
<li>Заполнение кэша новым значением вместо удаления при инвалидации также помогает избежать этой проблемы</li>
</ul>
</li>
</ul>
</li>
<li><strong>Мониторинг</strong>:
<ul>
<li>Информация о производительности запросов к БД, внешних вызовов и рендеринге шаблонов записывается через собственный middleware</li>
<li>Сбор и отображение с помощью Ganglia</li>
</ul>
</li>
<li><strong>Отключение функционала</strong>:
<ul>
<li>Необходим способ быстро отключить новый функционал, если оказывается, что он работает не так, как планировалось</li>
<li>Система должна срабатывать мгновенно, по всем серверам, без записи на диск</li>
<li>Позволяет запускать новые возможности постепенно, лишь для части аудитории</li>
<li>Позволяет постоянно использовать основную ветку кода</li>
<li>Аналогичная система используется и в <a href="/tag/facebook/" target="_blank">Facebook</a></li>
</ul>
</li>
<li><strong>Масштабирование команды разработчиков</strong>:
<ul>
<li>Небольшая команда</li>
<li>Месячная аудитория / количество разработчиков = 40 миллионов</li>
<li>Это означает:
<ul>
<li>Автоматическое тестирование</li>
<li>И максимально простой процесс разработки</li>
</ul>
</li>
<li>Новый сотрудник может начать работать уже через несколько минут, нужно лишь:
<ul>
<li>Установить и настроить PostgreSQL</li>
<li>Скачать исходный код из <a href="/tag/git/" target="_blank">git</a></li>
<li>С помощью pip и virtualenv установить зависимости</li>
<li>Изменить настройки в settings.py</li>
<li>Выполнить автоматическое создание структуры данных средствами Django</li>
</ul>
</li>
</ul>
</li>
<li><strong>Непрерывное тестирование</strong>:
<ul>
<li>Ежедневное развертывание с помощью <a href="/tag/fabric/" target="_blank">Fabric</a></li>
<li><a href="/tag/hudson/" target="_blank">Hudson</a> обеспечивает регулярно осуществляет и тестирует сборки</li>
<li>Интегрирован <a href="/tag/selenium/" target="_blank">Selenium</a></li>
<li>Быстрое тестирование с помощью <a href="/tag/pyflakes/" target="_blank">Pyflakes</a> и post-commit hooks</li>
<li>70 тысяч строк Python кода, 73% покрытие тестами, прогон всех тестов занимает 20 минут</li>
<li>Собственная система исполнения тестов с поддержкой XML, Selenium, подсчета количества запросов, тестирования Master/Slave базы данных и интеграцией с очередью</li>
</ul>
</li>
<li><strong>Отслеживание проблем и задач</strong>:
<ul>
<li>Переключились с Trac на Redmine (из-за поддержки под-задач)</li>
<li>Отправка исключений на e-mail &#8212; плохая идея</li>
<li>Раньше использовали django-db-log, но теперь опубликовали свою систему сбора ошибок и логов под названием <a href="https://github.com/dcramer/django-sentry" target="_blank">Sentry</a></li>
</ul>
</li>
</ul>
<h2>Делаем выводы</h2>
<ul>
<li>Язык программирования, каким бы он ни был, не является проблемой</li>
<li>Django в целом очень хорош (но приходится все же использовать набор собственных патчей)</li>
<li>Даже при использовании низкопроизводительного framework можно построить масштабируемую систему</li>
<li>Вертикальное партиционирование позволяет пожертвовать производительностью в пользу масштабируемости</li>
<li>Даже небольшой командой разработчиков можно добиться высоких результатов, если не пренебрегать автоматизацией тестирования</li>
<li>Большое значение имеет возможность вовремя отслеживать и оперативно реагировать на сбои</li>
</ul>
<h2>Источник информации</h2>
<p>Данная статья написана на основе выступления Jason Yan и David Cramer на DjangoConf 2010. В презентации можно найти примеры кода, ссылки на упоминаемые проекты и дополнительные материалы:</p>
<div id="__ss_5148151" style="width: 425px;"><object id="__sse5148151" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=djangocon2010scalingdisqus-100907133713-phpapp01&amp;stripped_title=djangocon-2010-scaling-disqus&amp;userName=zeeg" /><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=djangocon2010scalingdisqus-100907133713-phpapp01&amp;stripped_title=djangocon-2010-scaling-disqus&amp;userName=zeeg" allowfullscreen="true" allowscriptaccess="always" name="__sse5148151"></embed></object></div>
<p><em>Другие статьи по масштабируемости высоконагруженных систем можно почитать <a href="/highload" target="_blank">в соответствующем разделе</a>, а вовремя узнавать о новых &#8212; <a href="/feed" target="_blank">подписавшись на RSS</a>. Вчера, кстати, прикрутил DISQUS к Insight IT, приглашаю постоянных читателей и всех остальных потестировать <img src='http://www.insight-it.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.insight-it.ru/masshtabiruemost/arkhitektura-disqus/feed/</wfw:commentRss>
		<slash:comments>45</slash:comments>
		</item>
		<item>
		<title>Веб-сервер за два вечера</title>
		<link>http://www.insight-it.ru/unix-way/unix/web-server-za-dva-vechera/</link>
		<comments>http://www.insight-it.ru/unix-way/unix/web-server-za-dva-vechera/#comments</comments>
		<pubDate>Thu, 14 Feb 2008 12:59:10 +0000</pubDate>
		<dc:creator>Иван Блинков</dc:creator>
				<category><![CDATA[Unix]]></category>
		<category><![CDATA[Beastie]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[веб-сервер]]></category>
		<category><![CDATA[операционная система]]></category>
		<category><![CDATA[сервер]]></category>
		<category><![CDATA[системное администрирование]]></category>

		<guid isPermaLink="false">http://www.insight-it.ru/unix-way/unix/veb-server-za-dva-vechera/</guid>
		<description><![CDATA[Многие из вас наверняка все еще помнят те времена, когда компьютерная техника находилась лишь на ранней стадии своего развития. Позволить себе иметь в личном распоряжении персональный компьютер мог далеко не каждый, а о серверном оборудовании и вовсе не могло быть и речи. Но, к счастью, времена меняются, и на сегодняшний день покупка даже серверного оборудования [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/beastie.png" alt="Beastie" title="Beastie: The BSD Daemon" style="float: left" /><br />
Многие из вас наверняка все еще помнят те времена, когда компьютерная техника находилась лишь на ранней стадии своего развития. Позволить себе иметь в личном распоряжении персональный компьютер мог далеко не каждый, а о серверном оборудовании и вовсе не могло быть и речи.</p>
<p>Но, к счастью, времена меняются, и на сегодняшний день покупка даже серверного оборудования связана с достаточно скромными затратами, сопоставимыми с бюджетом покупки настольного компьютера или ноутбука. Но возникает другой вопрос &#8212; а что же с этим оборудованием делать? Вполне логичным ответом было бы: &#171;использовать по прямому назначению&#187;, о чем мы с Вами сегодня и поговорим в компании с замечательным персонажем по имени <em><a href="/tag/beastie" target="_blank">Beastie</a></em> и операционной системой <strong><a href="/tag/freebsd" target="_blank">FreeBSD</a></strong>, с которой он частенько ассоциируется.</p>
<p><span id="more-39"></span><br />
Под &#171;использованием по прямому назначению&#187; конечно же можно было подразумевать множество разных применений, но я  хотел все-таки остановиться на варианте использования в роли веб-сервера, как альтернативу многочисленным услугам по предоставлению shared и VPS хостинга.</p>
<h3>Предистория</h3>
<p>Некоторое время назад ко мне в руки попал простенький сервер, который как раз предполагалось использовать как хостинг для одного из проектов. Оставалось лишь сделать его пригодным для выполнения этой задачи. Казалось бы дело это как минимум не тривиальное, но буквально через пару дней мне довелось убедиться в обратном.</p>
<p>Ассортимент оборудования, спрятанного внутри <strong>1U</strong> корпуса, был вполне стандартным, ничего особенного: процессор <strong>Intel Xeon 5335</strong>, оперативная память <strong>Kingston 2х2 GB ECC Full-buffered</strong>, жесткий диск изначально только один &#8212; <strong>WD 150 GB 10000rpm SATA</strong>, а вот модель материнской платы, к сожалению, на память назвать не могу, вроде что-то от <strong>SuperMicro</strong>, с простенькой встроенной видеокартой, сетевой картой с двумя гигабитными Ethernet портами и встроенным же видимо software RAID-контроллером. Опытный глаз наверняка заметил бы в этом списке сильную недоукомплектацию, особенно проявляющуюся при упоминании процессора в единственном числе, отсутствии RAID, и скромным объемам оперативной памяти. Объясняется это достаточно просто &#8212; проект еще предстоит тестировать перед запуском, а этой платформы для этого будет более чем достаточно.</p>
<p>Перед запуском проекта в открытое плавание естественно предстоит upgrade оборудования.</p>
<h3 style="text-align: right">День первый</h3>
<h4>Подготовка</h4>
<p>Если верить бумажкам, идущим в комплекте с сервером, на единственный жестком диск в магазине установили демо-версию одной из серверных операционных систем от одной мало кому известной корпорации. Смотреть что это за зверь такой у меня особого желания не было, по-этому я не долго думая пошел искать среди своей коллекции дистрибутивов болванку с заранее выбранным <a href="/tag/opensource" target="_blank">opensource</a> решением вопроса об <a href="/tag/os">операционной системе</a> &#8212; <strong><a href="/tag/freebsd">FreeBSD 6.2</a></strong>.</p>
<p>Почему выбор пал именно на эту <a href="/tag/os" target="_blank">ОС</a> объяснить не так уж и просто, но я все же попробую. Выбор был достаточно классический: <em><a href="/tag/unix" target="_blank">Unix</a> vs <a href="/tag/linux" target="_blank">Linux</a></em>, возникали еще некоторые сомнения насчет решений от <em>Sun</em> в виде <em>Solaris</em> и <em>OpenSolaris</em>, но от них я отказался достаточно быстро в основном из-за более чем скромной документации и проприетарного происхождения, попутно закрыв глаза на все положительные отзывы, которые я видел в <a href="/net" target="_blank">Сети</a>.</p>
<p>Так как мне хотелось иметь иметь перед собой <em>конструктор</em> для сбора системы именно таким образом, как было бы удобно мне, а не разработчикам дистрибутива, то список вариантов, выступавших на стороне <a href="/tag/linux" target="_blank">Linux</a> быстро начал сокращаться, начиная с <strong>CentOS</strong>. Предпоследним вычеркнутым из списка дистрибутивов <a href="/tag/linux" target="_blank">Linux</a> был <strong>Debian</strong>, что оставило в нем лишь <a href="/tag/gentoo" target="_blank">Gentoo Linux</a>. Финальный выбор между <a href="/tag/freebsd">FreeBSD</a> и <a href="/tag/gentoo" target="_blank">Gentoo</a> был сделан уже легче: во-первых, по <a href="/unix-way/linux/gentoo-linux-sony-vaio/" target="_blank">своему опыту с ноутбуком</a> я уже понял, что с <a href="/tag/gentoo" target="_blank">Gentoo</a> предстояло бы немало хлопот, а, во-вторых, в новый <em>конструктор</em>, как ни крути, &#171;играть&#187; намного интереснее, чем в старый, так что долго думать не пришлось <img src='http://www.insight-it.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4>Установка</h4>
<p>Найдя наконец диск с <a href="/tag/freebsd">FreeBSD</a>, я попытался решить следующий возникший вопрос: а как же установить операционную систему с компакт-диска на компьютер, не имеющий соответствующего привода? Так как сервер был запломбирован и находился на гарантии, вариант частично разобрать и подключить обычный привод отпал сразу же, ровно как и вариант с подключением внешнего привода по причине его отсутствия. Подходящее решение было найдено практически сразу же, благо жесткие диски подключались по принципу hotswap: вытащив жесткий диск без развинчивания корпуса, я подключил его к подвернувшемуся под руку настольному компьютеру, обладающему DVD-приводом. Загрузка прошла успешно и я приступил к установке, руководствуясь <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html" target="_blank" rel="nofollow">FreeBSD Handbook</a>, пересказывать его особого желания у меня  нет, остановлюсь лишь на некоторых особенностях этого процесса.</p>
<p>Первым этапом установки, где пришлось задуматься, был <strong>fdisk</strong> (разбиение диска на так называемые <em>slice</em>). Для избежания путаницы для самого себя, я решил, что размещу рабочие директории http-сервера и базы данных в <strong>/var</strong>, которую и выделил в отдельный <em>slice</em>, занимающий б<em>о</em>льшую часть доступного дискового пространства. В ассортимент доступного при установке программного обеспечения я особо вникать не стал, так как знал, что у меня всегда будет возможность заняться им позже, и как следствие этого выбрал что-то очень близкое к стандартному набору <a href="/tag/po" target="_blank">ПО</a>.<br />
Подтвердив установку и подождав достаточно непродолжительный период времени, я перезагрузил систему, вытащив установочный диск в процессе. Установка оказалась на удивление элементарной, что привело к полученной с первой попытки работоспособной системе. Увидев долгожданное приглашение к вводу логина и пароля я убедился, что могу беспрепятственно получить доступ к консоли и сразу же выключил систему, чтобы перенести жесткий диск обратно на сервер.</p>
<p>Так как сетевое подключение еще только предстояло настроить, то на сервер переносить пришлось не только жесткий диск, но и монитор с клавиатурой. На новом оборудовании все так же прекрасно запустилось, и я принялся за настройку подключения. Особых проблем не возникло &#8212; в <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html#NETWORK-COMMUNICATION" target="_blank" rel="nofollow">Handbook</a>&#8216;е все более чем качественно задокументировано, самым сложным был процесс выбора драйвера, вернее осознавание того, что он изначально правильно сам установился. Следующей маленькой проблемой было угадывание какой же из <em>Ethernet</em>-портов был только что настроен, и, соответственно, подключение кабеля именно в него, а не в его соседа. После завершения всех манипуляций я с радостью обнаружил, что <strong>ping</strong> от сервера до gateway&#8217;а успешно проходит, что по сути и означало окончание настройки сетевого подключения.<br />
Следущей целью было избавить себя от необходимости пользоваться позаимствованными у другого компьютера клавиатурой и монитором. Дело тоже оказалось достаточно нехитрым, <strong>sshd</strong> установился и настроился вполне самостоятельно где-то в процессе установки, от меня потребовалось лишь создать дополнительного пользователя, написать нехитрую строчку в <strong>rc.conf</strong>: <em>sshd_enable=&#187;YES&#187;</em> и собственно запустить daemon&#8217;а. Этого было вполне достаточно, чтобы набрав на своем <a href="/tag/noutbuk" target="_blank">ноутбуке</a> <strong>ssh</strong> в консоли, с указанием необходимых параметров, получить удаленный доступ к серверу по протоколу <strong>SSH</strong>.</p>
<p>Решив, что для начала этого будет вполне достаточно, я отправился по другим делам, так как тот вечер еще даже не успел подойти к своему завершению.</p>
<h3 style="text-align: right">День второй</h3>
<h4>Программное обеспечение</h4>
<p>Хорошо, вполне работоспособную <a href="/tag/os" target="_blank">операционную систему</a> мы получили. Осталось снабдить ее необходимым <a href="/tag/po" target="_blank">программным обеспечением</a> для выполнения своих обязанностей, определенных нами заранее.</p>
<p>Прежде чем что-либо устанавливать, очень не пожалел, что ознакомился как с соответствующим <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html#PORTS" rel="nofollow" target="_blank">разделом handbook&#8217;a</a>, так и с <a href="http://www.freebsd.org/ports/" rel="nofollow" target="_blank">доступным ассортиментом ПО</a>. После этого я перешел-таки собственно к выбору и установке <a href="/tag/po" target="_blank">ПО</a>:</p>
<ul>
<li>Так как одной из основных составных частей практически любого веб-сервера является http-daemon, именно с его выбора я и решил начать. Причем начал еще задолго до описываемых событий, вся многофункциональность <a href="/tag/apache" target="_blank">Apache</a> мне была не нужна, а аналоги <em>mod_auth</em> и <em>mod_rewrite</em> есть и в более легких http-серверах. Cамо веб-приложение, которое там предполагалось располагать, работает по большей части на <a href="/tag/php" target="_blank">PHP</a>, так что ничего особенного от httpd совсем не требовалось. В итоге финальный выбор был между <em>быстрыми</em> и <em>легкими</em> вариантами: <strong>nginx</strong> и <strong><a href="/tag/lighttpd" target="_blank">lighttpd</a></strong>, какой-либо весомой причины по которой я выбрал <strong><a href="/tag/lighttpd" target="_blank">lighttpd</a></strong> с <strong>mod_fastcgi</strong> привести не могу, основным фактором был мой некоторый опыт работы с ним в прошлом, и отсутствие такового в отношении <strong>nginx</strong>. Установка прошла легко и непринужденно с помощью в сжатые сроки найденного в <a href="/tag/google" target="_blank">Google</a> <a href="http://www.cyberciti.biz/faq/howto-setup-lighttpd-fastcgi-php-server/" target="_blank" rel="nofollow">мануала</a>.</li>
<li>Другим немаловажным компонентом сервера является <strong>ftpd</strong>, как известно используемый для передачи файлов. Собственно говоря, если активное его использование не планируется, то особого значения какой именно сервер будет использоваться значения не имеет: любой из доступных устанавливается настраивается в пару простых шагов без каких-либо проблем (если это имеет значение &#8212; я выбрал <strong>vsftpd</strong>, так как мне уже далеко не один раз доводилось его настраивать на домашних компьютерах, и, как следствие, даже инструкция не понадобилась). Но при потенциальной возможности работы через Интернет, этот протокол является достаточно уязвимым, так как не использует никакого шифрования. Эта проблема решается с помощью механизма <em>FTP over SSH</em>, который представляет собой использование <strong>SSH</strong> в роли туннеля для передачи файлов по <strong>FTP</strong>. О том, как воспользоваться этим механизмом вам подскажет <strong>man ssh</strong>, какой-либо дополнительной конфигурации он не требует, разве что настройки соответствующим образом firewall&#8217;а, но об этом я расскажу позже.</li>
<li>Сам <a href="/tag/php" target="_blank">PHP</a> установлен последней доступной в <a href="http://www.freebsd.org/ports/" rel="nofollow" target="_blank">ports</a> версии и , как уже упоминалось, был подключен к <a href="/tag/lighttpd" target="_blank">lighttpd</a> с помощью <strong>mod_fastcgi</strong>, какой-либо дополнительной конфигурации с моей стороны не потребовалось, я разве что выбрал список модулей (в общем-то тоже занятие не сложное, достаточно лишь осознавать какие именно используются, плюс я еще решил <strong><a href="http://www.hardened-php.net/suhosin/" rel="nofollow" target="_blank">Suhosin</a></strong> установить) и просто просмотрел по диагонали все конфиги (в основном сам <strong>php.ini</strong> и <strong>lighttpd.conf</strong>) на предмет их соответствия потребностям моего приложения. Отдельная история возникла с лишь одним модулем &#8212; <em><a href="/tag/blitz" target="_blank">Blitz</a></em>, который на данный момент все еще отсутствует в репозиториях как <a href="/tag/freebsd" target="_blank">FreeBSD</a>, так и подавляющего большинства (если не всех) дистрибутивов <a href="/tag/linux" target="_blank">Linux</a>. Его пришлось устанавливать вручную из исходников по <a href="http://alexeyrybak.com/blitz/blitz_ru.html#install_config.install" target="_blank" rel="nofollow">соответствующему мануалу</a>, что правда тоже дело не хитрое и заняло всего несколько минут.</li>
<li><strong><a href="/tag/subd" target="_blank">СУБД</a></strong> особо выбирать не пришлось &#8212; приложение написано было с расчетом на <strong><a href="/tag/postgresql" target="_blank">PostrgeSQL</a></strong>, ее соответственно и прикручивал к <strong><a href="/tag/php" target="_blank">PHP</a>.</strong> Этот этап был пожалуй одним из самых проблематичных, так как сразу после классического <strong>make install clean</strong> соответствующий daemon запускаться отказался. Какого-либо осознанного сообщения об ошибке <strong>/usr/local/etc/rc.d/postgresqld start</strong> не выводило как в консоль, так и в логи, но тем не менее консольный клиент <strong>psql</strong> и само веб-приложение жаловались на отсутствие запущенной <a href="/tag/subd" target="_blank">СУБД</a>. Этот факт сильно затруднял поиск возможных вариантов решения на просторах <a href="/tag/internet">Сети</a>, так что не найдя ничего полезного я решил заняться диагностикой проблемы и поиском решения для нее самостоятельно. Методом проб и ошибок, перебрав множество возможных вариантов запуска daemon&#8217;а, я пришел к выводу, что у пользователя от имени которого он должен был запускаться явно проблемы с доступом к файловой системе. Видимо так получилось из-за нестандартного расположения самой базы данных &#8212; в директории <strong>/var</strong>. Не смотря на тот факт, что <strong>chown</strong> и <strong>chmod</strong> были использованы по прямому назначению в отношении соответствующих директорий для установления прав доступа. В итоге оказалось, что директория указанная для этого пользователя как домашняя (по памяти пишу, могу ошибиться, но вроде <strong>/usr/local/pgsql</strong>) по каким-то причинам не создалась и соответственно именно этот факт и мешал запуску daemon&#8217;а. Восстановив справедливость в отношении этого пользователя, я обнаружил, что <strong><a href="/tag/postgresql" target="_blank">PostrgeSQL</a></strong> успешно запустился-таки, а мое приложение тоже стало функционировать именно так, как ему было положено. Проверив содержимое соответствующего конфига, я решил его больше не трогать, а то как говорится &#171;premature optimization is the root of all evil&#187;&amp;copyright;. За компанию решил установить веб-интерфейс к <a href="/tag/postgresql" target="_blank">PostrgeSQL</a> &#8212; <strong>phppgadmin</strong>. Собравшись из <a href="http://www.freebsd.org/ports/" rel="nofollow" target="_blank">портов</a>, он повел себя как-то не очень адекватно, совсем не так каким я привык его видеть у себя на <a href="/tag/noutbuk" target="_blank">ноутбуке</a>, разбираться в причинах было не охота &#8212; простое копирование и замена соответствующей директории по <em>ftp</em> буквально за минуту решило проблему.</li>
<li>Вариантов фильтров сетевого трафика в <a href="/tag/freebsd" target="_blank">FreeBSD</a> имеется предостаточно: <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html#FIREWALLS-PF" target="_blank" rel="nofollow">pf</a>, <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html#FIREWALLS-IPF" target="_blank" rel="nofollow">ipf</a>, <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html#FIREWALLS-IPFW%22" target="_blank" rel="nofollow">ipfw</a>. Опыта работы ни с одним из них у меня не было, так что выбор происходил из достаточно субъективных критериев &#8212; очевидности принципов работы правил и достаточности документации. Так как я был уверен, что каждый из них сможет обеспечить достаточный уровень безопасности, основываясь на указанных выше критериях в итоге я выбрал <strong>ipf</strong>. Документация позволила легко и непринужденно все установить и настроить, правда за компанию пришлось разбираться и с <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html#KERNELCONFIG" rel="nofollow" target="_blank">пересборкой ядра</a>. В качестве базы для построения собственного списка правил я использовал приведенный все там же, в документации, пример. Само собой пришлось доработать его под конкретную систему, но методом проб и ошибок эта задача выполняется достаточно быстро <em>(будте осторожны с 22 портом, используемым для SSH &#8212; очень легко на этом этапе случайно заблокировать самому себе доступ к серверу)</em>. Получившийся в итоге список правил приводить не буду, так как его еще предстоит довести до ума на активно работающей системе.</li>
</ul>
<h3>Заключение</h3>
<p>Не прошло и двух дней, как из простого набора оборудования получился вполне готовый к работе веб-сервер, конечно же доводить до ума его придется еще достаточно долго, но просто стабильно работать он был в состоянии уже тогда. Дальше его отвезли в место постоянного его прибывания, подключили к более-менее приличному интернет-каналу, с моей стороны при этом потребовалось лишь слегка поменять настройки сетевого подключения, и вот &#8212; он уже доступен из <a href="/net" target="_blank">Сети</a>. Практически сразу же обнаружился один мой недочет в плане выбора <a href="/tag/po" target="_blank">ПО</a> &#8212; буквально в первую же ночь после открытия публичного доступа к серверу нашлась масса желающих попытаться подобрать по словарю логин и пароль для доступа к серверу по SSH, но он был открыт лишь для одной учетной записи, у которой было мягко говоря нестандартное имя пользователя, даже его никто за ночь не смог угадать, а до более чем 20-символьного пароля дело так и не дошло. На следующее утро я, не долго думая, установил программу под названием <strong><a href="http://www.freebsd.org/cgi/url.cgi?ports/security/sshguard/pkg-descr" rel="nofollow" target="_blank">sshguard</a></strong>, которая сразу же предотвратила все последующие попытки подобным образом издеваться над сервером. Дальше надо было настроить запись на DNS-сервере для ассоциации домена с IP нашего сервера, настроить почту, закончить работу над самим веб-приложением и много чего еще, но это уже совсем другая история.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.insight-it.ru/unix-way/unix/web-server-za-dva-vechera/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Веб-сервер за два вечера</title>
		<link>http://www.insight-it.ru/unix-way/unix/veb-server-za-dva-vechera/</link>
		<comments>http://www.insight-it.ru/unix-way/unix/veb-server-za-dva-vechera/#comments</comments>
		<pubDate>Thu, 14 Feb 2008 12:59:03 +0000</pubDate>
		<dc:creator>Иван Блинков</dc:creator>
				<category><![CDATA[Unix]]></category>
		<category><![CDATA[Beastie]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[веб-сервер]]></category>
		<category><![CDATA[операционная система]]></category>
		<category><![CDATA[сервер]]></category>
		<category><![CDATA[системное администрирование]]></category>

		<guid isPermaLink="false">http://www.insight-it.ru/?p=83</guid>
		<description><![CDATA[Многие из вас наверняка все еще помнят те времена, когда компьютерная техника находилась лишь на ранней стадии своего развития. Позволить себе иметь в личном распоряжении персональный компьютер мог далеко не каждый, а о серверном оборудовании и вовсе не могло быть и речи. Но, к счастью, времена меняются, и на сегодняшний день покупка даже серверного оборудования [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/beastie.png" alt="Beastie" title="Beastie: The BSD Daemon" style="float: left" /><br />
Многие из вас наверняка все еще помнят те времена, когда компьютерная техника находилась лишь на ранней стадии своего развития. Позволить себе иметь в личном распоряжении персональный компьютер мог далеко не каждый, а о серверном оборудовании и вовсе не могло быть и речи.</p>
<p>Но, к счастью, времена меняются, и на сегодняшний день покупка даже серверного оборудования связана с достаточно скромными затратами, сопоставимыми с бюджетом покупки настольного компьютера или ноутбука. Но возникает другой вопрос &#8212; а что же с этим оборудованием делать? Вполне логичным ответом было бы: &#171;использовать по прямому назначению&#187;, о чем мы с Вами сегодня и поговорим в компании с замечательным персонажем по имени <em><a href="/tag/beastie" target="_blank">Beastie</a></em> и операционной системой <strong><a href="/tag/freebsd" target="_blank">FreeBSD</a></strong>, с которой он частенько ассоциируется.</p>
<p><span id="more-83"></span><br />
Под &#171;использованием по прямому назначению&#187; конечно же можно было подразумевать множество разных применений, но я  хотел все-таки остановиться на варианте использования в роли веб-сервера, как альтернативу многочисленным услугам по предоставлению shared и VPS хостинга.</p>
<h3>Предистория</h3>
<p>Некоторое время назад ко мне в руки попал простенький сервер, который как раз предполагалось использовать как хостинг для одного из проектов. Оставалось лишь сделать его пригодным для выполнения этой задачи. Казалось бы дело это как минимум не тривиальное, но буквально через пару дней мне довелось убедиться в обратном.</p>
<p>Ассортимент оборудования, спрятанного внутри <strong>1U</strong> корпуса, был вполне стандартным, ничего особенного: процессор <strong>Intel Xeon 5335</strong>, оперативная память <strong>Kingston 2х2 GB ECC Full-buffered</strong>, жесткий диск изначально только один &#8212; <strong>WD 150 GB 10000rpm SATA</strong>, а вот модель материнской платы, к сожалению, на память назвать не могу, вроде что-то от <strong>SuperMicro</strong>, с простенькой встроенной видеокартой, сетевой картой с двумя гигабитными Ethernet портами и встроенным же видимо software RAID-контроллером. Опытный глаз наверняка заметил бы в этом списке сильную недоукомплектацию, особенно проявляющуюся при упоминании процессора в единственном числе, отсутствии RAID, и скромным объемам оперативной памяти. Объясняется это достаточно просто &#8212; проект еще предстоит тестировать перед запуском, а этой платформы для этого будет более чем достаточно.</p>
<p>Перед запуском проекта в открытое плавание естественно предстоит upgrade оборудования.</p>
<h3 style="text-align: right">День первый</h3>
<h4>Подготовка</h4>
<p>Если верить бумажкам, идущим в комплекте с сервером, на единственный жестком диск в магазине установили демо-версию одной из серверных операционных систем от одной мало кому известной корпорации. Смотреть что это за зверь такой у меня особого желания не было, по-этому я не долго думая пошел искать среди своей коллекции дистрибутивов болванку с заранее выбранным <a href="/tag/opensource" target="_blank">opensource</a> решением вопроса об <a href="/tag/os">операционной системе</a> &#8212; <strong><a href="/tag/freebsd">FreeBSD 6.2</a></strong>.</p>
<p>Почему выбор пал именно на эту <a href="/tag/os" target="_blank">ОС</a> объяснить не так уж и просто, но я все же попробую. Выбор был достаточно классический: <em><a href="/tag/unix" target="_blank">Unix</a> vs <a href="/tag/linux" target="_blank">Linux</a></em>, возникали еще некоторые сомнения насчет решений от <em>Sun</em> в виде <em>Solaris</em> и <em>OpenSolaris</em>, но от них я отказался достаточно быстро в основном из-за более чем скромной документации и проприетарного происхождения, попутно закрыв глаза на все положительные отзывы, которые я видел в <a href="/net" target="_blank">Сети</a>.</p>
<p>Так как мне хотелось иметь иметь перед собой <em>конструктор</em> для сбора системы именно таким образом, как было бы удобно мне, а не разработчикам дистрибутива, то список вариантов, выступавших на стороне <a href="/tag/linux" target="_blank">Linux</a> быстро начал сокращаться, начиная с <strong>CentOS</strong>. Предпоследним вычеркнутым из списка дистрибутивов <a href="/tag/linux" target="_blank">Linux</a> был <strong>Debian</strong>, что оставило в нем лишь <a href="/tag/gentoo" target="_blank">Gentoo Linux</a>. Финальный выбор между <a href="/tag/freebsd">FreeBSD</a> и <a href="/tag/gentoo" target="_blank">Gentoo</a> был сделан уже легче: во-первых, по <a href="/unix-way/linux/gentoo-linux-sony-vaio/" target="_blank">своему опыту с ноутбуком</a> я уже понял, что с <a href="/tag/gentoo" target="_blank">Gentoo</a> предстояло бы немало хлопот, а, во-вторых, в новый <em>конструктор</em>, как ни крути, &#171;играть&#187; намного интереснее, чем в старый, так что долго думать не пришлось <img src='http://www.insight-it.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4>Установка</h4>
<p>Найдя наконец диск с <a href="/tag/freebsd">FreeBSD</a>, я попытался решить следующий возникший вопрос: а как же установить операционную систему с компакт-диска на компьютер, не имеющий соответствующего привода? Так как сервер был запломбирован и находился на гарантии, вариант частично разобрать и подключить обычный привод отпал сразу же, ровно как и вариант с подключением внешнего привода по причине его отсутствия. Подходящее решение было найдено практически сразу же, благо жесткие диски подключались по принципу hotswap: вытащив жесткий диск без развинчивания корпуса, я подключил его к подвернувшемуся под руку настольному компьютеру, обладающему DVD-приводом. Загрузка прошла успешно и я приступил к установке, руководствуясь <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html" target="_blank" rel="nofollow">FreeBSD Handbook</a>, пересказывать его особого желания у меня  нет, остановлюсь лишь на некоторых особенностях этого процесса.</p>
<p>Первым этапом установки, где пришлось задуматься, был <strong>fdisk</strong> (разбиение диска на так называемые <em>slice</em>). Для избежания путаницы для самого себя, я решил, что размещу рабочие директории http-сервера и базы данных в <strong>/var</strong>, которую и выделил в отдельный <em>slice</em>, занимающий б<em>о</em>льшую часть доступного дискового пространства. В ассортимент доступного при установке программного обеспечения я особо вникать не стал, так как знал, что у меня всегда будет возможность заняться им позже, и как следствие этого выбрал что-то очень близкое к стандартному набору <a href="/tag/po" target="_blank">ПО</a>.<br />
Подтвердив установку и подождав достаточно непродолжительный период времени, я перезагрузил систему, вытащив установочный диск в процессе. Установка оказалась на удивление элементарной, что привело к полученной с первой попытки работоспособной системе. Увидев долгожданное приглашение к вводу логина и пароля я убедился, что могу беспрепятственно получить доступ к консоли и сразу же выключил систему, чтобы перенести жесткий диск обратно на сервер.</p>
<p>Так как сетевое подключение еще только предстояло настроить, то на сервер переносить пришлось не только жесткий диск, но и монитор с клавиатурой. На новом оборудовании все так же прекрасно запустилось, и я принялся за настройку подключения. Особых проблем не возникло &#8212; в <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html#NETWORK-COMMUNICATION" target="_blank" rel="nofollow">Handbook</a>&#8216;е все более чем качественно задокументировано, самым сложным был процесс выбора драйвера, вернее осознавание того, что он изначально правильно сам установился. Следующей маленькой проблемой было угадывание какой же из <em>Ethernet</em>-портов был только что настроен, и, соответственно, подключение кабеля именно в него, а не в его соседа. После завершения всех манипуляций я с радостью обнаружил, что <strong>ping</strong> от сервера до gateway&#8217;а успешно проходит, что по сути и означало окончание настройки сетевого подключения.<br />
Следущей целью было избавить себя от необходимости пользоваться позаимствованными у другого компьютера клавиатурой и монитором. Дело тоже оказалось достаточно нехитрым, <strong>sshd</strong> установился и настроился вполне самостоятельно где-то в процессе установки, от меня потребовалось лишь создать дополнительного пользователя, написать нехитрую строчку в <strong>rc.conf</strong>: <em>sshd_enable=&#187;YES&#187;</em> и собственно запустить daemon&#8217;а. Этого было вполне достаточно, чтобы набрав на своем <a href="/tag/noutbuk" target="_blank">ноутбуке</a> <strong>ssh</strong> в консоли, с указанием необходимых параметров, получить удаленный доступ к серверу по протоколу <strong>SSH</strong>.</p>
<p>Решив, что для начала этого будет вполне достаточно, я отправился по другим делам, так как тот вечер еще даже не успел подойти к своему завершению.</p>
<h3 style="text-align: right">День второй</h3>
<h4>Программное обеспечение</h4>
<p>Хорошо, вполне работоспособную <a href="/tag/os" target="_blank">операционную систему</a> мы получили. Осталось снабдить ее необходимым <a href="/tag/po" target="_blank">программным обеспечением</a> для выполнения своих обязанностей, определенных нами заранее.</p>
<p>Прежде чем что-либо устанавливать, очень не пожалел, что ознакомился как с соответствующим <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html#PORTS" rel="nofollow" target="_blank">разделом handbook&#8217;a</a>, так и с <a href="http://www.freebsd.org/ports/" rel="nofollow" target="_blank">доступным ассортиментом ПО</a>. После этого я перешел-таки собственно к выбору и установке <a href="/tag/po" target="_blank">ПО</a>:</p>
<ul>
<li>Так как одной из основных составных частей практически любого веб-сервера является http-daemon, именно с его выбора я и решил начать. Причем начал еще задолго до описываемых событий, вся многофункциональность <a href="/tag/apache" target="_blank">Apache</a> мне была не нужна, а аналоги <em>mod_auth</em> и <em>mod_rewrite</em> есть и в более легких http-серверах. Cамо веб-приложение, которое там предполагалось располагать, работает по большей части на <a href="/tag/php" target="_blank">PHP</a>, так что ничего особенного от httpd совсем не требовалось. В итоге финальный выбор был между <em>быстрыми</em> и <em>легкими</em> вариантами: <strong>nginx</strong> и <strong><a href="/tag/lighttpd" target="_blank">lighttpd</a></strong>, какой-либо весомой причины по которой я выбрал <strong><a href="/tag/lighttpd" target="_blank">lighttpd</a></strong> с <strong>mod_fastcgi</strong> привести не могу, основным фактором был мой некоторый опыт работы с ним в прошлом, и отсутствие такового в отношении <strong>nginx</strong>. Установка прошла легко и непринужденно с помощью в сжатые сроки найденного в <a href="/tag/google" target="_blank">Google</a> <a href="http://www.cyberciti.biz/faq/howto-setup-lighttpd-fastcgi-php-server/" target="_blank" rel="nofollow">мануала</a>.</li>
<li>Другим немаловажным компонентом сервера является <strong>ftpd</strong>, как известно используемый для передачи файлов. Собственно говоря, если активное его использование не планируется, то особого значения какой именно сервер будет использоваться значения не имеет: любой из доступных устанавливается настраивается в пару простых шагов без каких-либо проблем (если это имеет значение &#8212; я выбрал <strong>vsftpd</strong>, так как мне уже далеко не один раз доводилось его настраивать на домашних компьютерах, и, как следствие, даже инструкция не понадобилась). Но при потенциальной возможности работы через Интернет, этот протокол является достаточно уязвимым, так как не использует никакого шифрования. Эта проблема решается с помощью механизма <em>FTP over SSH</em>, который представляет собой использование <strong>SSH</strong> в роли туннеля для передачи файлов по <strong>FTP</strong>. О том, как воспользоваться этим механизмом вам подскажет <strong>man ssh</strong>, какой-либо дополнительной конфигурации он не требует, разве что настройки соответствующим образом firewall&#8217;а, но об этом я расскажу позже.</li>
<li>Сам <a href="/tag/php" target="_blank">PHP</a> установлен последней доступной в <a href="http://www.freebsd.org/ports/" rel="nofollow" target="_blank">ports</a> версии и , как уже упоминалось, был подключен к <a href="/tag/lighttpd" target="_blank">lighttpd</a> с помощью <strong>mod_fastcgi</strong>, какой-либо дополнительной конфигурации с моей стороны не потребовалось, я разве что выбрал список модулей (в общем-то тоже занятие не сложное, достаточно лишь осознавать какие именно используются, плюс я еще решил <strong><a href="http://www.hardened-php.net/suhosin/" rel="nofollow" target="_blank">Suhosin</a></strong> установить) и просто просмотрел по диагонали все конфиги (в основном сам <strong>php.ini</strong> и <strong>lighttpd.conf</strong>) на предмет их соответствия потребностям моего приложения. Отдельная история возникла с лишь одним модулем &#8212; <em><a href="/tag/blitz" target="_blank">Blitz</a></em>, который на данный момент все еще отсутствует в репозиториях как <a href="/tag/freebsd" target="_blank">FreeBSD</a>, так и подавляющего большинства (если не всех) дистрибутивов <a href="/tag/linux" target="_blank">Linux</a>. Его пришлось устанавливать вручную из исходников по <a href="http://alexeyrybak.com/blitz/blitz_ru.html#install_config.install" target="_blank" rel="nofollow">соответствующему мануалу</a>, что правда тоже дело не хитрое и заняло всего несколько минут.</li>
<li><strong><a href="/tag/subd" target="_blank">СУБД</a></strong> особо выбирать не пришлось &#8212; приложение написано было с расчетом на <strong><a href="/tag/postgresql" target="_blank">PostrgeSQL</a></strong>, ее соответственно и прикручивал к <strong><a href="/tag/php" target="_blank">PHP</a>.</strong> Этот этап был пожалуй одним из самых проблематичных, так как сразу после классического <strong>make install clean</strong> соответствующий daemon запускаться отказался. Какого-либо осознанного сообщения об ошибке <strong>/usr/local/etc/rc.d/postgresqld start</strong> не выводило как в консоль, так и в логи, но тем не менее консольный клиент <strong>psql</strong> и само веб-приложение жаловались на отсутствие запущенной <a href="/tag/subd" target="_blank">СУБД</a>. Этот факт сильно затруднял поиск возможных вариантов решения на просторах <a href="/tag/internet">Сети</a>, так что не найдя ничего полезного я решил заняться диагностикой проблемы и поиском решения для нее самостоятельно. Методом проб и ошибок, перебрав множество возможных вариантов запуска daemon&#8217;а, я пришел к выводу, что у пользователя от имени которого он должен был запускаться явно проблемы с доступом к файловой системе. Видимо так получилось из-за нестандартного расположения самой базы данных &#8212; в директории <strong>/var</strong>. Не смотря на тот факт, что <strong>chown</strong> и <strong>chmod</strong> были использованы по прямому назначению в отношении соответствующих директорий для установления прав доступа. В итоге оказалось, что директория указанная для этого пользователя как домашняя (по памяти пишу, могу ошибиться, но вроде <strong>/usr/local/pgsql</strong>) по каким-то причинам не создалась и соответственно именно этот факт и мешал запуску daemon&#8217;а. Восстановив справедливость в отношении этого пользователя, я обнаружил, что <strong><a href="/tag/postgresql" target="_blank">PostrgeSQL</a></strong> успешно запустился-таки, а мое приложение тоже стало функционировать именно так, как ему было положено. Проверив содержимое соответствующего конфига, я решил его больше не трогать, а то как говорится &#171;premature optimization is the root of all evil&#187;&amp;copyright;. За компанию решил установить веб-интерфейс к <a href="/tag/postgresql" target="_blank">PostrgeSQL</a> &#8212; <strong>phppgadmin</strong>. Собравшись из <a href="http://www.freebsd.org/ports/" rel="nofollow" target="_blank">портов</a>, он повел себя как-то не очень адекватно, совсем не так каким я привык его видеть у себя на <a href="/tag/noutbuk" target="_blank">ноутбуке</a>, разбираться в причинах было не охота &#8212; простое копирование и замена соответствующей директории по <em>ftp</em> буквально за минуту решило проблему.</li>
<li>Вариантов фильтров сетевого трафика в <a href="/tag/freebsd" target="_blank">FreeBSD</a> имеется предостаточно: <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html#FIREWALLS-PF" target="_blank" rel="nofollow">pf</a>, <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html#FIREWALLS-IPF" target="_blank" rel="nofollow">ipf</a>, <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html#FIREWALLS-IPFW%22" target="_blank" rel="nofollow">ipfw</a>. Опыта работы ни с одним из них у меня не было, так что выбор происходил из достаточно субъективных критериев &#8212; очевидности принципов работы правил и достаточности документации. Так как я был уверен, что каждый из них сможет обеспечить достаточный уровень безопасности, основываясь на указанных выше критериях в итоге я выбрал <strong>ipf</strong>. Документация позволила легко и непринужденно все установить и настроить, правда за компанию пришлось разбираться и с <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html#KERNELCONFIG" rel="nofollow" target="_blank">пересборкой ядра</a>. В качестве базы для построения собственного списка правил я использовал приведенный все там же, в документации, пример. Само собой пришлось доработать его под конкретную систему, но методом проб и ошибок эта задача выполняется достаточно быстро <em>(будте осторожны с 22 портом, используемым для SSH &#8212; очень легко на этом этапе случайно заблокировать самому себе доступ к серверу)</em>. Получившийся в итоге список правил приводить не буду, так как его еще предстоит довести до ума на активно работающей системе.</li>
</ul>
<h3>Заключение</h3>
<p>Не прошло и двух дней, как из простого набора оборудования получился вполне готовый к работе веб-сервер, конечно же доводить до ума его придется еще достаточно долго, но просто стабильно работать он был в состоянии уже тогда. Дальше его отвезли в место постоянного его прибывания, подключили к более-менее приличному интернет-каналу, с моей стороны при этом потребовалось лишь слегка поменять настройки сетевого подключения, и вот &#8212; он уже доступен из <a href="/net" target="_blank">Сети</a>. Практически сразу же обнаружился один мой недочет в плане выбора <a href="/tag/po" target="_blank">ПО</a> &#8212; буквально в первую же ночь после открытия публичного доступа к серверу нашлась масса желающих попытаться подобрать по словарю логин и пароль для доступа к серверу по SSH, но он был открыт лишь для одной учетной записи, у которой было мягко говоря нестандартное имя пользователя, даже его никто за ночь не смог угадать, а до более чем 20-символьного пароля дело так и не дошло. На следующее утро я, не долго думая, установил программу под названием <strong><a href="http://www.freebsd.org/cgi/url.cgi?ports/security/sshguard/pkg-descr" rel="nofollow" target="_blank">sshguard</a></strong>, которая сразу же предотвратила все последующие попытки подобным образом издеваться над сервером. Дальше надо было настроить запись на DNS-сервере для ассоциации домена с IP нашего сервера, настроить почту, закончить работу над самим веб-приложением и много чего еще, но это уже совсем другая история.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.insight-it.ru/unix-way/unix/veb-server-za-dva-vechera/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Общаемся с базой данных</title>
		<link>http://www.insight-it.ru/programmirovanie/php/obshhaemsya-s-bazojj-dannykh/</link>
		<comments>http://www.insight-it.ru/programmirovanie/php/obshhaemsya-s-bazojj-dannykh/#comments</comments>
		<pubDate>Wed, 16 Jan 2008 19:04:09 +0000</pubDate>
		<dc:creator>Иван Блинков</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[БД]]></category>
		<category><![CDATA[интерфейс]]></category>
		<category><![CDATA[кодинг]]></category>
		<category><![CDATA[ООП]]></category>
		<category><![CDATA[СУБД]]></category>
		<category><![CDATA[технология]]></category>
		<category><![CDATA[хранение данных]]></category>

		<guid isPermaLink="false">http://www.insight-it.ru/programming/php/obshhaemsya-s-bazojj-dannykh/</guid>
		<description><![CDATA[На этот раз хочется обсудить такой одновременно важный и несложный момент в реализации работы любого интернет-проекта, как координации работы Ваших скриптов с СУБД. Если подойти к этому вопросу &#34;в лоб&#34;, то код станет очень неудобен как для понимания, так и для использования: код станет переполнен различными функциями соединения с БД, отправки запросов, преобразования результатов запросов [...]]]></description>
			<content:encoded><![CDATA[<p>На этот раз хочется обсудить такой одновременно важный и несложный момент в реализации работы любого интернет-проекта, как координации работы Ваших скриптов с СУБД.</p>
<p>Если подойти к этому вопросу &quot;в лоб&quot;, то код станет очень неудобен как для понимания, так и для использования: код станет переполнен различными функциями соединения с БД, отправки запросов, преобразования результатов запросов в массивы PHP, подсчета строк, которые затронул запрос, а также многие и многие другие.</p>
<p>Для желающих минимизировать подобного рода издержки в процессе написания кода, хочу предложить один из, на мой взгляд, самых эффективных способов решения этой проблемы.</p>
<p><span id="more-26"></span></p>
<p>Этим способом будет являться написание класса, реализующего интерфейс между СУБД и PHP-скриптами. Для начала стоит определиться с ассортиментом функций, которые будет призван выполнять наш класс:</p>
<ul>
<li><em>установка соединения</em>, а также проверка успешности выполнения этого действия;</li>
<li><em>отправка запросов</em>, как заданных извне так и, возможно, из какого-либо ассортимента заранее написанных запросов;</li>
<li><em>обработка результатов запросов</em>, не ограничивающаяся одним SELECT, должны быть предоставлены методы обработки результатов любых видов запросов (или хотябы большинства).</li>
</ul>
<p>Вполне очевидным является тот факт, что методы этого класса будут использоваться практически повсеместно в большинстве проектов. Вследствии чего становится нецелесообразным создание объекта нашего класса и передача его по всем функциям и методам всех скриптов, в таких случае намного предпочтительнее делать владельцем методов и переменных сам класс, а не экземпляр класса, с помощью ключевого слова <strong>static</strong>. Это позволит пользоваться услугами нашего класса из любого места кода. Приступим-с собственно к кодингу, начать стоит с заготовки пустого класса:</p>
<pre lang="PHP">
<?php
class SQL
{
  private static $connection; // соединение с СУБД
  static function connect()  // установка соединения
  {

  }
  static function query($str,$bool=false) // произвольный запрос
  {

  }

?>
</pre>
<p>В зависимости от предпочитаемой Вами СУБД набор конкретных функций, используемых в реализации нашего класса, будет вариироваться. В большинстве случаев предпочитаю пользоваться PostgreSQL, на это причин у меня несколько, но это тема для отдельного разговора. Благодаря этому факту приводимый в качестве примера код будет использовать функции для работы именно с этой СУБД. Для поклонников же других этот систем вопрос в подавляющем большинстве случаев заключается лишь в замене этих функций на аналогичные из других модулей PHP, например для популярной и широкораспространенной MySQL достаточно будет всеголишь пройтись автозаменой <strong>pg_ =&gt; mysql_</strong> и слегка подредактировать параметры некоторых функций.</p>
<p>Перейдем к реализации установления соединения с СУБД, не стоит ожидать увидеть здесь ничего необычного:</p>
<pre lang="PHP">
static function connect()  // установка соединения
{
  self::$connection=pg_pconnect("host=localhost dbname=pgsql user=pgsql password=MyPassword");
  // не забываем менять указанные данные для авторизации на правильные
  if(!isset(self::$connection))
  {
    echo "Сайт не работает по техническим причинам.Просим прощения за доставленные неудобства.";
    exit;	// ни в коем случае не выводим более информативных сообщений об ошибке, чем это
  }
}
</pre>
<p>А вот с отправкой и обработкой результатов запросов ситуация далеко не так однозначна. Помимо простой передачи самого текста запроса в СУБД, необходимо правильно определить тип запроса и в соответствии с этим обработать результат. Можно конечно попытаться сделать это автоматически на основе вытаскивания первого слова из текста запроса, но мне всетаки кажется более предпочтительным определение &quot;вручную&quot; желаемого вида представление результата. Выполнение произвольных запросов может выглядеть, например, следующим образом:</p>
<pre lang="PHP">
static function query($str,$bool=false) // произвольный запрос
{
  //echo $str.""; // очень удобно на стадии разработки в процессе поиска ошибок
  $result=@pg_query(self::$connection,$str); // @ - для сокрытия теоретически возможных ошибок
  // or die('Query failed: '.pg_last_error());
  // не забываем убирать в комментарий в финальном варианте проекта
  // или совсем удалять
  if($result)  // Если получен результат, отличный от false
  {
    if($bool)  // Если выбран результат в виде boolean
    {
      return true;
    }
    else  // Если выбран результат в виде массива
    {
      $n=pg_num_rows($result);	// для создания универсального формата массива
      if($n==1)return pg_fetch_array($result,0,PGSQL_ASSOC);
      else  // даже когда результат содержит только одну строку
      {
        $j=pg_num_rows($result);
        $list=array();
        for($i=0;$i<$j;$i++)
        $list[]=pg_fetch_array($result,$i,PGSQL_ASSOC);
        return $list;
      }
    }
  }else return false;
}
</pre>
<p>Помимо базовой отправки запросов, в некоторых случаях имеет смысл написать несколько методов, отправляющих частоиспользуемые запросы, что в некоторых случаях позволяет сократить объем и уменьшить нагроможденность кода. Хоть я и предпочитаю не пользоваться такими вещами, но привести пример такого рода метода все же стоит:</p>
<pre lang="PHP">
static function selectAll($table)
{ // пример метода отправки чаcтоиспользуемых запросов
  return self::query("select * from ".$table.";");
}
</pre>
<p>Если чувствуете необходимость в подобных функциях, можно написать огромное количество, все ограничивается лишь Вашим воображением и знаниями SQL.</p>
<p>Что ж, осталось лишь собрать весь код в <a href="/wp-content/uploads/source/sql.class.phps">единый листинг</a>:</p>
<pre lang="PHP">
<?php
class SQL
{
  private static $connection; // соединение с СУБД
  static function connect()  // установка соединения
  {
    self::$connection=pg_pconnect("host=localhost dbname=pgsql user=pgsql password=MyPassword");
    // не забываем менять указанные данные для авторизации на правильные
    if(!isset(self::$connection))
    {
      echo "Сайт не работает по техническим причинам.Просим прощения за доставленные неудобства.";
      exit;	// ни в коем случае не выводим более информативных сообщений об ошибке, чем это
    }
  }
  static function query($str,$bool=false) // произвольный запрос
  {
    //echo $str.""; // очень удобно на стадии разработки в процессе поиска ошибок
    $result=@pg_query(self::$connection,$str); // @ - для сокрытия теоретически возможных ошибок
    // or die('Query failed: '.pg_last_error());
    // не забываем убирать в комментарий в финальном варианте проекта
    // или совсем удалять
    if($result)  // Если получен результат, отличный от false
    {
      if($bool)  // Если выбран результат в виде boolean
      {
        return true;
      }
      else  // Если выбран результат в виде массива
      {
         $n=pg_num_rows($result);	// для создания универсального формата массива
         if($n==1)return pg_fetch_array($result,0,PGSQL_ASSOC);
         else  // даже когда результат содержит только одну строку
         {
           $j=pg_num_rows($result);
           $list=array();
           for($i=0;$i<$j;$i++)
           $list[]=pg_fetch_array($result,$i,PGSQL_ASSOC);
           return $list;
         }
      }
    }else return false;
  }
  static function selectAll($table)
  { // пример метода отправки чаcтоиспользуемых запросов
    return self::query("select * from ".$table.";");
  }
}
?>
</pre>
<p>Вот так вот оно и выглядит в простейшем варианте, дорабатывать под собственные нужды код можно до бесконечности естественно, но в большинстве случаев даже такой реализации вполне должно хватать.</p>
<p>Эта статья является частью <a href="/dzhentelmenskij-nabor-php-programmista">серии статей "Джентельменский набор PHP программиста"</a>, если Вам понравилась эта статья то очень вероятно, что Вам придутся по душе и остальные статьи.</p>
<p>Не забываем <a href="/feed" target="_blank">подписываться на RSS блога</a>, а также на <a href="/comments/feed" target="_blank">ленту комментариев</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.insight-it.ru/programmirovanie/php/obshhaemsya-s-bazojj-dannykh/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
	</channel>
</rss>

