<?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>PS</title>
	<atom:link href="http://seriyps.ru/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://seriyps.ru/blog</link>
	<description>Linux, программирование, Я!</description>
	<lastBuildDate>Fri, 18 May 2012 19:04:45 +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>На стачку! Впечатления и обзор конференции. День 2.</title>
		<link>http://seriyps.ru/blog/2012/04/17/na-stachku-vpechatleniya-i-obzor-konferencii-day-2/</link>
		<comments>http://seriyps.ru/blog/2012/04/17/na-stachku-vpechatleniya-i-obzor-konferencii-day-2/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 07:30:40 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[Общекомпьютерное]]></category>
		<category><![CDATA[конференция]]></category>
		<category><![CDATA[стачка]]></category>
		<category><![CDATA[Ульяновск]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=750</guid>
		<description><![CDATA[Вечер прогулок по городу, ночь в гостинице и вот он &#8212; второй день конференции. Решил доклады не пропускать (не зря же 12 часов в поезде ехал!) и пошел сразу на первый доклад. Сергей Ломаков, Simtech. &#171;Использование key-value хранилища redis в боевых условиях&#187;. Рассказал о юзкейсах редиса, об основных возможностях и опыте работы с ним. Редис [...]]]></description>
			<content:encoded><![CDATA[<p>Вечер прогулок по городу, ночь в гостинице и вот он &#8212; второй день конференции. Решил доклады не пропускать (не зря же 12 часов в поезде ехал!) и пошел сразу на первый доклад.</p>
<p><span id="more-750"></span></p>
<h3>Сергей Ломаков, Simtech. &#171;Использование key-value хранилища redis в боевых условиях&#187;.</h3>
<p>Рассказал о юзкейсах редиса, об основных возможностях и опыте работы с ним. Редис достаточно простой и производительный, но в нем нет встроенных инструментов горизонтального масштабирования. Поддерживает хранимые процедуры на Lua (применяли ли их на практике не понял). Упомянул, что можно на основе редиса сделать простую MQ (массив и RPUSH + LPOP), есть возможности pub-sub. Довольно интересные способы сортировки с возможностью сохранить результат как отдельный ключ. Для персистентности существуют снепшоты (позволяют быстро запускаться с него, но работает на основе fork, т.е. возможен перерасход памяти) и append-only файл (снижает производительность, довольно медленный старт сервера). Довольно быстрая и устойчивая master-slave репликация. Посоветовал использовать 32-битную сборку для экономии памяти, запускать несколько экземпляров по числу ядер. Полезно разделять экземпляры по назначению (кому-то важна персистентность, например статистике, кому-то нет, напр. кеш).</p>
<p>Мне доклад показался не очень интересным, скорее всего потому что с редисом уже работал, а тут было довольно много простых вещей и информации из документации. Но и были полезные советы и примеры из собственного опыта.</p>
<h3>Юрий Бушмелев, echo. &#171;Облако в подсобке. Строим правильную локальную инфраструктуру&#187;.</h3>
<p>При использовании реального железа возникает множество проблем связанных, например, с привязкой к оборудованию, с конфликтами различных сервисов, запущенных на одном сервере и т.п.</p>
<p>Виртуализация серверов позволяет:</p>
<ul>
<li>Избавиться от зависимости от конкретного оборудования</li>
<li>Запускать разные сервисы в разных VM</li>
<li>Более эффективно использовать ресурсы (т.к. на одном хосте можно размещать одновременно виртуалки с разными профилями нагрузки (IO/процессор/память)</li>
<li>упрощение бэкапов за счет снапшотов</li>
<li>повышается отказоустойчивость</li>
</ul>
<p>Для надежного и удобного хранения данных виртуальных машин нужно использовать &#171;Системы хранения данных&#187;, в том числе для Live Migration между хост-серверами. Процесс роста такой:</p>
<ol>
<li>Один сервер виртуализации</li>
<li>Несколько серверов виртуализации и СХД</li>
<li>Несколько серверов СХД для надежности</li>
</ol>
<p>Системы виртуализации тоже не все одинаковые. Основные типы: автономная (не нужна ОС-хост, работает сразу на железе) и на основе хостовой ОС. Автономная лучше т.к. не требуется установка хостовой ОС.</p>
<p>Пример реального бюджетного облака: автономный или гибридный гипервизор, СХД из 2-х серверов с SCSI-failover и софт-raid, не брендовые сервера.</p>
<p>Основные тормоза &#8212; на дисковом IO.</p>
<p>От себя &#8212; не знаю есть ли реальный смысл поднимать собственные &#171;облака на коленке&#187; когда есть амазоны-ракспейсы-селектелы. Скорее всего оправданы когда нужны какие-то специальные условия или имеются особые требования.</p>
<h3>Василий Сошников, SimbirSoft. &#171;Кроссплатформенная разработка: Windows, Linux, MacOS,  iOS, Android&#187;</h3>
<p>Доклад читали 2 докладчика по очереди. Я не очень хорошо вник в суть, но кажется описывали опыт разработки мультиплатформенного софта на низкоуровневых языках (C++).</p>
<p>Структура такая: [бэкенд] &lt;-&gt; [Notification center] &lt;-&gt;[фронтенд]. Важно разработать простой гибкий протокол для которого можно создать биндинг в C. Обсуждали какие-то Pimpl vs Factory, <em>во время доклада попытался выяснить у соседей что такое pimpl &#8212; безуспешно) </em>Отметили что важно, чтобы система сборки поддерживала командную строку и pipelining. Посоветовали иметь в проекте минимум внешних зависимостей для облегчения портирования. В качестве платформонезависимого способа передачи бинарных данных посоветовали Thrift или ProtocolBuffers.</p>
<p>Честно говоря, мало что понял из доклада, плюс по времени затянулся а мне нужно было из гостиницы съезжать, так что на вопросы/ответы даже не остался.</p>
<p>Дальше уже начинаются более интересные доклады&#8230; Хотел попасть на доклад Михаила Табунова про Backbone.JS, но из за затянувшегося доклада и гостинницы так на него и не попал. так что дальше идет</p>
<h3>Константин Осипов, mail.ru. &#171;Tarantool/Box 1.5. опыт оптимизации производительности NoSQL СУБД&#187;</h3>
<p>Tarantool &#8212; это т.н. Relaxed-relational база данных. Есть базы, есть таблицы, в них есть кортежи, часть из них описываются схемой, часть без схемы (фиксированная и нефиксированная части), есть btree и hash индексы (только на фиксированную часть, на нефиксированную появятся в след. версиях). Инкрементальное перестроение индексов/хешей. Отличается очень высокой производительностью и очень тесной интеграцией с Lua &#8212; на нем пишутся хранимые процедуры, есть множество процедур из коробки. Существуют упрощенный SQL интерфейс, собственный бинарный протокол и эмуляция Memcached протокола. При этом SQL интерфейс существует только на клиенте где сразу преобразуется в бинарный протокол. Основной &#171;потребитель&#187; &#8212; собственно Mail.ru. В tarantool хранятся сессии и данные о присутствии на сайте. Фактически &#8212; при каждом клике пользователя на проектах Mail.ru идет обращение к Tarantool. У mail.ru 20млн онлайн пользователей создают 100 тыс запросов к Tarantool в ссекунду. База работает на кластере из 2-х боевых серверов и 2-х реплик для надежности. На каждом сервере запущено по 2 копии tarantool и вполне справляется с нагрузкой.</p>
<p>В Tarantool нет транзакций, но операции атомарные, с записью на диск. Более-менее сложные вещи лучше реализовывать на хранимых процедурах.</p>
<p>На вопрос &#171;чем вы лучше редиса&#187; ответил, что у них более гибкие структуры данных, лучше интеграция с LUA, лучше организована работа с диском. Проблемы со сборщиком мусора в LUA решили.</p>
<p>От себя &#8212; судя по описанию, довольно интересная база с широкими возможностями, но у нее очень маленькое комьюнити и мало внешних проектов, использующих Tarantool. Создается впечатление, что автор не очень-то хочет/старается его (комьюнити) поддерживать. &#171;Мне и так каждый день приходят советы как мне БД продвинуть, улучшить, пропиарить. Какой-то секс посреди красной площади получается&#187;. Ну что-ж, пожелаю удачи и развития, возможно найду время поковыряться.</p>
<h3>Алексей Рыбак, badoo. &#171;Архитектура badoo&#187;.</h3>
<p style="text-align: right;"><em>&#171;Когда у вас в руках молоток, любая проблема кажется гвоздем&#187;</em></p>
<p>Badoo &#8212; один из популярных на западе и в европе сайтов знакомств с командой разработки в России. У них 2000 серверов в 2-х датацентрах. Список используемых технологий очень короткий: Linux, Nginx,PHP, C, C++, MySQL с HandlerSocket, Memcached; есть немного MongoDB и немного Python, но их стараются выпилить О_о.</p>
<p>Значительная часть кода пишется как эксперимент, в случае чего можно безболезненно выкинуть. В badoo консервативны к выбору технологий и инструментов (очень!).</p>
<p>Для того чтобы выбрать в какой из датацентров &#171;приземлить&#187; пользователя используется GeoIP DNS.</p>
<p>Существует внутренний стандарт-соглашение что время сборки страничек не должно превышать 0.1 секунду. Сборка странички происходит синхронно в PHP, данные берутся из MySQL, C/C++ демонов,Memcached. Все обращения к другим серверам обернуты в таймеры (pinba). Для кеширования байткода PHP используют APC или eAccelerator. Создали и поддерживают шаблонизатор Blitz и менеджер процессов PHP-fpm. Логи ошибок собирают в Scribe.</p>
<p>Весь SQL &#8212; в коде приложения. Не используют триггеров/хранимых процедур и т.п. Используют только простые запросы, без view, без вложенных запросов, не используют  внешних ключей (вроде используют JOIN). Контроль целостности, как я понял, осуществляется тоже вручную в коде. Активно используют шардинг. Написана собственная система репликации шардов между ДЦ для MySQL. Используют параллельный апгрейд  схем таблиц на шардах. Используют транзакционные очереди (?). На серверах Memcached регулярно делают полный flush. Для шардинга ключей используют простой <code>$i/n</code> или <code>crc32($s)/n</code>. Активно используют время жизни ключей, используют prolongate для мемкеша (увеличение времени жизни при обращении к ключу). Есть система очередей в MySQL с периодическим поллингом в 20-30 секунд O_o (вроде так сделано чтобы использовать транзакции и с очередями в том числе). Какое-то время использовали RabbitMQ, но выпилили.</p>
<p>Для администрирования используют puppet и собственную библиотеку для PHP mssh (multi-ssh).</p>
<p>У меня этот доклад вызвал какой-то butthurt. Неужели оправданно так жестко подходить к выбору инструментов и, при возможности,  выпиливать &#187;проявления вольности&#187; некоторых разработчиков (Python, Mongo, RabbitMQ)? В чем проблема развести небольшой зоопарк не понимаю. Учитывая, что у них все-таки уже довольно большая команда и найти спецов по новым  технологиям не будет такой уж проблемой. Однозначно могу сказать, что в Badoo я бы работать не хотел&#8230; Возможно чего-то не понимаю конечно.</p>
<h3>Лев Валкин, echo. &#171;Инь и янь масштабированиия&#187;</h3>
<p style="text-align: right;"><em>Шардинг! Шардинг! Шардинг!</em></p>
<p>Второй доклад Льва Валкина. На самом деле без контекста не совсем понятно о чем он рассказывал ИМХО. Т.к. я с контекстом немного  знаком, расскажу.</p>
<p>Echo предоставляет огромным медийным и контентным западным площадкам и брендам различные социальные реалтайм социальные виджеты (комментарии, лайки, топы, голосования, шаринг и пр) плюс конструктор на основе этих виджетов и SQL &#8212; подобный язык запросов к платформе. Учитывая объемы траффика и данных, множество связей в сочетании с гибкостью платформы, получается довольно уникальная штука. 50 000 запросов в секунду, 200 серверов, куча реалтайма.</p>
<p>На докладе рассказал об Incident Command System &#8212; систему реагирования на внештатные ситуации, позаимствованную у пожарных: тот, кто первым обнаружил проблему становится ответственным за нее и руководит процессом &#171;ремонта&#187;.</p>
<p>Затем некоторые размышления на тему программирования, когда лучше применять бесконечные очереди (RabbitMQ) а когда что-то простое (Nginx + воркеры). Рассказал, что в Echo активно используют фичи Erlang, например часто используют горячую замену кода прямо на production, но это несколько расслабляет программистов и они начинают этой возможностью злоупотреблять. Упомянул, что важно допускать остановку части серверов без потери работоспособности всей системы (устранять единые точки отказа).</p>
<p>Отдельно коснулся важности интроспекции и рассказал как с этим все хорошо в Эрланге. Помимо бенчмарков у них используются замеры с историей во времени чтобы наблюдать аномалии и отклонения.</p>
<p>Отдельно рассказал про продвинутую систему логгирования: при каждом запросе к их сервису в Erlang собираются все возможные данные и метрики и на лету анализируются и фильтруются. В среднем на каждый запрос может накопиться несколько десятков мегабайт такой отладочной информации. В случае необходимости эти данные логгируются на диск, иначе просто отбрасываются. Оверхед на такое логгирование существенный, от 5 до 30 процентов, но он размазывается по кластеру.</p>
<p>Значительная часть серверов живет в Amazon, но это дорого и часто встречаются аномалии и нестабильности, поэтому поддерживают и свою инфраструктуру в Colocation. В частности, все сервера баз данных свои. Главный плюс амазона &#8212; можно в случае необходимости быстро отмасштабироваться в 10 раз, но не более.</p>
<p>Языки разработки: в первую очередь Erlang и OCaml, так же используются Python, PHP, Haskell, C, Perl. В команде есть много хороших специалистов знающих по несколько языков. Так что выбирают язык если хорошо подходит для решения конкретных задач или есть какая-то хорошая библиотечка на нем.</p>
<p>Хоть и большая часть софта на Erlang, нанимают не Erlang-программистов, а просто хороших инженеров, в случае необходимости обучают Erlang-у в процессе работы.</p>
<p>От себя: хоть доклад был, на мой взгляд, немного несвязным, но тем не менее было весьма интересно. Радует, что не боятся новых технологий и &#171;языкового зоопарка&#187;.</p>
<p>Кстати, после доклада, в кулуарах обсуждали проблемы с масштабированием, с которыми в Echo приходится сталкиваться: у них хранится сложная структура данных &#8212; социальный граф со множеством связей. А т.к. клиентам предоставляются гибкие средства работы с ним (EQL &#8212; SQL-подобный язык) то шардирование реализовать не получается, т.к. не ясно по какому критерию разбивать данные и Materialized View так же не подходит, т.к. приведет к копированию огромных количеств данных. Как с этим бороться &#8212; еще не придумали)</p>
<p>Ну вот и все, конференция закончена. Огромное спасибо всем, отдельно организаторам и докладчикам. Пожалуй, одна из лучших конференций на которых я побывал. Буду надеяться что мероприятие станет как минимум ежегодным и будет держать планку на уровне. А мне пора на поезд.</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2012/04/17/na-stachku-vpechatleniya-i-obzor-konferencii-day-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>На стачку! Впечатления и обзор конференции. День 1.</title>
		<link>http://seriyps.ru/blog/2012/04/17/na-stachku-vpechatleniya-i-obzor-konferencii-day1/</link>
		<comments>http://seriyps.ru/blog/2012/04/17/na-stachku-vpechatleniya-i-obzor-konferencii-day1/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 06:30:58 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[Общекомпьютерное]]></category>
		<category><![CDATA[конференция]]></category>
		<category><![CDATA[стачка]]></category>
		<category><![CDATA[Ульяновск]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=734</guid>
		<description><![CDATA[Давненько не бывал на конференциях, наконец-то удалось совместить наличие хорошей конференции с возможностью на нее пойти. И так, 13 и 14-го апреля в г. Ульяновск проходила конференция &#171;Стачка!&#187; на которой я имел удовольствие поприсутствовать. Сразу отмечу, что несмотря на то, что конференция была бесплатной, уровень организации и качество докладов были на уровне вполне известных платных [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nastachku.ru/"><img class="alignright" title="На стачку! лого" src="http://nastachku.ru/skins/basic/customer/images/logo.gif" alt="" width="137" height="70" /></a>Давненько не бывал на конференциях, наконец-то удалось совместить наличие хорошей конференции с возможностью на нее пойти. И так, 13 и 14-го апреля в г. Ульяновск проходила конференция &#171;Стачка!&#187; на которой я имел удовольствие поприсутствовать. Сразу отмечу, что несмотря на то, что конференция была бесплатной, уровень организации и качество докладов были на уровне вполне известных платных конференций. Выбрали отличное живописное место, организовали онлайн трансляцию (на сайте выложены архивы с видео докладов). Спасибо организаторам, постарались на славу!</p>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2012/04/IMAG0106.jpg"><img title="Ульяновский дом пионеров - место проведения конференции" src="http://seriyps.ru/blog/wp-content/uploads/2012/04/IMAG0106-150x150.jpg" alt="" width="150" height="150" /></a> <a href="http://seriyps.ru/blog/wp-content/uploads/2012/04/IMAG0101-e1334609285371.jpg"><img class="alignnone size-thumbnail wp-image-743" title="Ульяновск утром" src="http://seriyps.ru/blog/wp-content/uploads/2012/04/IMAG0101-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>Теперь расскажу о докладах (в общем-то краткий пересказ докладов, много букв! Если нужны подробности &#8212; смотрите видео на сайте).<span id="more-734"></span></p>
<h3>Илья Космодемьянский. &#171;Теория и практика распределенных баз данных&#187;.</h3>
<p>Свой доклад посвятил следующим темам:</p>
<ul>
<li>Области применения репликаций</li>
<li>Транзакции, локальные и распределенные</li>
<li>Очереди сообщений</li>
<li>Materialized View</li>
</ul>
<p>Довольно общий доклад, обзорный. Если кто-то планирует начать работать с распределенными БД (или неожиданно столкнулся с необходимостью с ними работать) будет полезен. Опять же, отличия подходов к работе с БД в локальном и распределенном случаях.</p>
<h3>Роман Павлушко, avito.ru &#171;Нагруженный поиск на Sphinx&#187;.</h3>
<p>Доклад о том, как создавался и как поддерживается поиск на крупнейшем сайте объявлений в рунете Avito.ru. Докладчик в начале нервничал, но потом разошелся)</p>
<p>Изначальная архитектура сайта была завязана на базу данных. Использовались различные хранимые процедуры, кеш так же укладывался в базу, поиск был реализован на встроенном в PostgreSQL полнотекстовом индексе (tsearch). Когда же столкнулись с серьезными нагрузками, то начали максимально разгружать БД, упростили схему, вынесли кеш в In-memory базу а поиск перенесли в Sphinx.</p>
<p>На сайте Sphinx используется для 2-х вещей: непосредственно поиск и &#171;похожие объявления&#187; и эти 2 части генерируют большую часть траффика на сайте. Поиск обрабатывает около 140 млн запросов в сутки, размер индекса &#8212; 3Гб. В кластере 16 серверов и на всех серверах одинаковые индексы.</p>
<p>Каждые 20 минут запускается ПОЛНАЯ переиндексация, которая  длится 20 минут. Есть несколько различных индексов для разных целей + главный индекс. В качестве источника данных для индексации используют отдельную реплику базы данных, в которую реплицируют только нужные таблицы и Matreialized Views &#8212; ы <strong>только</strong> с активными объявлениями. При этом индексы строятся параллельно &#8212; просто через bash запускаются несколько экземпляров Sphinx indexer, каждый на свой индекс. После окончания процесса новые индексы разносятся по поисковым серверам с помощью uftp + rsync где запускается процедура ротации индексов.</p>
<p>Помимо фронтенда, Sphinx используют в бэкофисе, где успешно используют распределенный индекс.</p>
<p>Лайфхаки:</p>
<ul>
<li>не используют MVA ибо работает медленнее, для каждого параметра отдельный атрибут.</li>
<li>при пагинации если offset &gt; total_matches / 2 то сортируют результат в обратном порядке</li>
<li>Индексы хранят в tmpfs (фактически в памяти).</li>
<li>В качестве протокола общения используют SphinxQL.</li>
<li>Не используют Live Update индексов, т.к. когда пробовали, получили быстрое снижение производительности, ну и нет необходимости.</li>
<li>Стараются использовать Multi Query, ибо быстрее.</li>
<li>Не один индекс! Разбивают индекс по  категориям на кусочки.</li>
</ul>
<p>Меня впечатлило в этом докладе то, что использовали простые и, в каком-то смысле, наколенные решения. Ну и здорово, что реальный опыт, конкретные примеры, success story) Люблю такие доклады.</p>
<h3>Макс Лапшин. &#171;erlyvideo. Использование эрланг в видеостриминговом сервере&#187;.</h3>
<p>Я сам уже достаточно давно интересуюсь этим языком и OTP платформой, почитываю книжечку, пишу HelloWorld-ы и думаю даже в будущем начать разрабатывать на нем. Python уже поднадоел, а другие языки не имеют принципиально ничего особенного.</p>
<p>Так вот, про доклад. В Java-подобных языках имеются проблемы с параллельным программированием: Stop The World сборщик мусора, проблемы с обработкой ошибок (утечка ресурсов, слишком много кода посвящено обработке ошибок). Ну и всякие синхронизации/дедлоки само собой.</p>
<p>В отличие от них, у Erlang совершенно другой подход. Для параллелизма и изоляции ошибок используются легковесные процессы, существующие только внутри Erlang VM и дающие очень маленький оверхед (можно запускать миллионы таких процессов на одной машине). Ссылки отсутствуют как таковые, все данные немутабельны. Ошибки не обрабатываются программистом, описывается только HappyPath, в случае возникновения ошибки падает только процесс-обработчик (освобождая свои ресурсы) и тут-же перезапускается процессом &#8212; супервизором. У каждого микропотока собственный сборщик мусора, который работает независимо от остальных (т.е. нет моментов, когда вся система целиком встает колом из за активации GC). Дополнительные плюшки:</p>
<ul>
<li>Обновление кода сервисов без перезапуска и без даунтайма</li>
<li>Прозрачная работа в кластере (можно запустить микропроцесс и общаться с ним на удаленной машине точно так же как и на локальной)</li>
<li>Встроенный в VM асинхронный IO с синхронным API (нет лапши из коллбеков).</li>
<li>Удобная интроспекция работающей системы (можно удаленно подключиться к работающей системе и посмотреть где что происходит, какой процесс потребляет ресурсы и чем он именно занимается).</li>
<li>Удобная работа с бинарными данными.</li>
<li>Автоматическое распараллеливание по ядрам процессора.</li>
</ul>
<p>Ну и конечно же упомянул проблемы Node.JS, спасибо, это всегда полезно)</p>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2012/04/IMAG0107.jpg"><img class="alignnone size-full wp-image-747" title="why node sucks" src="http://seriyps.ru/blog/wp-content/uploads/2012/04/IMAG0107-e1334610055196.jpg" alt="" width="600" height="338" /></a></p>
<p>Рассказал немного про удобство работы с видео-потоками в Erlang (долгоживущие соединения, неустойчивая внешняя среда, битые данные. ошибки). Легко поддерживать старый код, т.к. кода мало)</p>
<p>От себя &#8212; т.к. эрлангом сам интересуюсь, ничего нового для себя не узнал, но все равно было интересно и приятно послушать.</p>
<h3>Александр Титов, skype. &#171;Инженерный дзен. Непрерывные изменения&#187;</h3>
<p>Долгие релиз-циклы это потеря денег для компании и увеличение числа ошибок в продакшне. Нельзя допускать долгих релиз-циклов. Каждая новая фича &#8212; релиз, но с возможностью быстро откатиться в случае необходимости.</p>
<p>Инструментарий:</p>
<ul>
<li>Chef &#8212; основной инструмент. Управление конфигурацией серверов, инфраструктурой, одновременно и живая документация на инфраструктуру, версионирование.</li>
<li>vagrant &#8212; удобная оболочка для virtualbox + DSL для эмуляции различных инфраструктур</li>
<li>Юнит-тесты само собой</li>
<li>Jenkins</li>
</ul>
<p>&#171;Проповедует&#187; devops &#8212; т.е. когда разработчики являются одновременно и админами: &#171;Уметь и софт написать и конфиг Nginx подправить&#187;.</p>
<p>Доклад понравился, нужно обдумать и посмотреть как сейчас в нашей организации это устроено. Возникла идея пригласить докладчика к нам на консультацию&#8230; еще посоветуюсь с руководством.</p>
<h3>Лев Валкин в кулуарах.</h3>
<p>Успел поспрашивать как в Echo используются фичи Erlang, так вот:</p>
<ul>
<li>Активно используют живое обновление кода</li>
<li>Активно используют  Erlang-кластеризацию (межнодное взаимодействие). В кластер объединены не все сервера, а разбиты по группам.</li>
<li>Используют message-passing без хаков</li>
<li>Используют юнит-тесты и какую-то библиотеку для &#171;фаззинга&#187; (кажется QuickCheck)</li>
<li>Часто тестируют код &#171;на живую&#187;-прямо на продакшне: &#171;У нас 50 000 запросов в секунду, если и есть ошибка, то это проявляется сразу&#187;.</li>
<li>Не используют dialyzer, но собираются начать.</li>
<li>Для тяжелой математики используют OCaml</li>
</ul>
<div>Что-ж, меня это сильно успокоило, ибо рассказы про ErlyVideo и Ejabberd <strong>заставляли усомниться</strong> в том, что горячая замена кода, кластеризация и чистый message-passing совместимы с суровой реальностью. Просто в ErlyVideo очень специфические задачи.</div>
<h3>Лев Валкин, echo. &#171;Ульяновск как яйцо силиконовой долины. Инкубация&#187;.</h3>
<p>Единственный доклад не по программированию, который я посетил. Для начала предистория. <strong>Лев Валкин</strong> &#8212; основатель стартапа Echo родом из Ульяновска. Сейчас живет в USA, а команда разработки находится в Ульяновске. Ну и он всячески, не безуспешно, старается развивать и поддерживать IT движуху в этом городе. В докладе рассказал о том, в чем, по его мнению, заключается секрет развития силиконовой долины и чего не хватает Ульяновску для того чтобы стать &#171;Российской силиконовой долиной&#187;.</p>
<p>Успешному развитию силиконовой долины (для краткости далее &#8212; СД) поспособствовали:</p>
<ul>
<li>удаленность от крупных городов бизнес-центров, в которых существовали крупные агрессивные компании</li>
<li>Хороший климат) Упрощает коммуникацию.</li>
<li>Взаимодействие с университетами</li>
<li>Отсутствие государства и политиков</li>
<li>Кажется, упоминалась небольшая территория (все рядом)</li>
</ul>
<p>Так же пояснил важный момент: в СД развиваются и всячески поощряются горизонтальные связи между компаниями между специалистами из одной области. Т.е. программисты одной компании обмениваются знаниями с программистами другой, менеджеры &#8212; с менеджерами, техподдержка с техподдержкой и т.п. И это очень важно в ситуациях, когда знания специалиста бывают не до конца востребованы в его компании, но могут пригодиться кому то еще. Не менее важен и &#171;обмен&#187; специалистами.</p>
<p>Про Ульяновск: плюсы это то, что он удален от Москвы (мало сильных конкурентов, спецы не сбегают в Москву), довольно большая концентрация IT компаний, <del>погода</del>, небольшая территория. Минусы &#8212; не развиты горизонтальные связи и обмен опытом.</p>
<p>Порекомендовал для удержания и повышения мотивации сотрудников использовать profit-sharing (опционы и т.п.).</p>
<p>От себя &#8212; давно наблюдаю, не особо в курсе как развиваются IT бизнесы, появляются ли новые компании в Ульяновске, но какая-то IT движуха там явно есть. Тот &#8212; же UlCamp например, присутствие Echo с вакансиями на которые люди из Москвы приезжают&#8230;</p>
<h3>Аня Степанян, Undev. &#171;Как мы делали webvybory2012&#8243;</h3>
<p>Доклад о том, с какими трудностями пришлось столкнуться команде UnDev при разработке такого масштабного проекта в столь сжатые сроки и о том, как они героически с ними боролись.</p>
<p>Трудно выбрать хорошие камеры. Медленный интернет на многих участках (до 128кбит/с), часть компьютеров за NAT. Есть специальные требования к компьютерам. Заказы в огромных количествах. В итоге имелось 10 различных комбинаций оборудования. На тестирование очередного релиза на всех конфигурациях уходят сутки. Были проблемы связанные с тем, что официально адреса участков публикуются за месяц до выборов, поэтому пришлось составлять свою базу адресов, с которой были проблемы и неточности &#8212; корректировали вручную.</p>
<p>Сам сайт был практически статическим (JSON дампы), база данных &#8212; PostgreSQL. Языки программирования: Ruby, Python, CoffeeScript, работа с видео на ObjC.</p>
<p>На этом первый день конференции закончился, народ довольно быстро разошелся, да и я тоже пошел погулять по городу. Впереди еще один день конференции, продолжение следует&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2012/04/17/na-stachku-vpechatleniya-i-obzor-konferencii-day1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Плагин L2TP для NetworkManager</title>
		<link>http://seriyps.ru/blog/2012/01/31/plagin-l2tp-dlya-networkmanager/</link>
		<comments>http://seriyps.ru/blog/2012/01/31/plagin-l2tp-dlya-networkmanager/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 21:58:33 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[linux на десктопе]]></category>
		<category><![CDATA[beeline]]></category>
		<category><![CDATA[IPSec]]></category>
		<category><![CDATA[l2tp]]></category>
		<category><![CDATA[linux на сервере]]></category>
		<category><![CDATA[network-manager-l2tp]]></category>
		<category><![CDATA[NetworkManager]]></category>
		<category><![CDATA[pppd]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[vpn]]></category>
		<category><![CDATA[xl2tpd]]></category>
		<category><![CDATA[интернет]]></category>
		<category><![CDATA[провайдер]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=714</guid>
		<description><![CDATA[TL;DR: теперь подключаться к L2TP VPN можно через NetworkManager. Допилил сегодня плагин для Network Manager с поддержкой L2TP. Поддерживает VPN через L2TP и, теоретически, L2TP через IPSec. Я проверял на &#171;beeline домашний интернет&#187; (http://help.internet.beeline.ru/internet/install/windows7/l2tp) и в общем-то для этого его и взялся дорабатывать. В принципе, можно даже озаглавить статью типа &#171;Настройка beeline l2tp vpn через [...]]]></description>
			<content:encoded><![CDATA[<p>TL;DR: теперь подключаться к L2TP VPN можно через NetworkManager.</p>
<p>Допилил сегодня плагин для Network Manager с поддержкой L2TP. Поддерживает VPN через L2TP и, теоретически, L2TP через IPSec.<br />
Я проверял на &#171;beeline домашний интернет&#187; (<a href="http://help.internet.beeline.ru/internet/install/windows7/l2tp">http://help.internet.beeline.ru/internet/install/windows7/l2tp</a>) и в общем-то для этого его и взялся дорабатывать. В принципе, можно даже озаглавить статью типа &#171;<strong>Настройка beeline l2tp vpn через NetworkManager</strong>&#171;.</p>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2012/01/network-manager-l2tp.png"><img title="NetworkManager l2tp plugin screenshot" src="http://seriyps.ru/blog/wp-content/uploads/2012/01/network-manager-l2tp-e1327959857491.png" alt="" width="500" height="414" /></a></p>
<h2>Установка</h2>
<p>Можно установить из PPA:<br />
<a href="https://launchpad.net/~seriy-pr/+archive/network-manager-l2tp" target="_blank">https://launchpad.net/~seriy-pr/+archive/network-manager-l2tp</a></p>
<pre><code>sudo apt-add-repository ppa:seriy-pr/network-manager-l2tp
sudo apt-get update
sudo apt-get install network-manager-l2tp-gnome</code></pre>
<p>После установки настоятельно рекомендую выполнить</p>
<pre><code>sudo service xl2tpd stop
sudo update-rc.d xl2tpd disable</code></pre>
<p>После этого можно будет создать новое VPN подключение &#171;Layer 2 Tunnelling Protocol (L2TP)&#187; (см. скриншот).<br />
Напомню как:</p>
<ol>
<li>Кликаем по иконке NM в трее</li>
<li>Выбираем &#171;Изменить соединения&#187;</li>
<li>Открываем вкладку VPN</li>
<li>Жмем &#171;Добавить&#187;</li>
<li>В выпадающем списке выбираем &#171;Layer 2 Tunnelling Protocol (L2TP)&#187;  жмем создать</li>
<li>Дальше уже заполняем окно с настройками для нового соединения</li>
</ol>
<p>Можно сразу попасть на 5-й пункт если запустить в консоли <code>nm-connection-editor --type=vpn --create</code></p>
<h2>Если что-то не работает</h2>
<p>Можете пожаловаться мне. Делать это следует так:<br />
Сперва выполняем команды <code>lsb_release -a</code> и <code>uname -a</code> и отправляем мне что они напечатают.<br />
В идеале прикладывайте еще ссылку на инструкцию вашего провайдера по настройке VPN для Windows.<br />
Дальше в зависимости от того какая возникла проблема:</p>
<h3>Не устанавливается пакет</h3>
<p>Присылайте вывод команды<br />
<code>apt-cache policy network-manager-l2tp</code><br />
Ну и какую ошибку пишет при установке.</p>
<h3>Не получается Добавить новое VPN подключение</h3>
<p>Имеется в виду что пакет установился, но при попытке <strong>создать и настроить</strong> новое VPN подключение возникают проблемы (нет пункта &#171;Layer 2 Tunnelling Protocol (L2TP)&#187; или программа вылетает или не сохраняются настройки).<br />
В консоли запускаете команду<br />
<code>nm-connection-editor --type=vpn --create</code><br />
И пробуете добавить и настроить новое подключение. Присылайте что напечатает в консоль и опишите саму проблему конечно же.</p>
<h3>При попытке подключения происходят ошибки</h3>
<p>Открываете 2 консоли, в одной запускаете</p>
<pre><code>sudo /usr/lib/NetworkManager/nm-l2tp-service --debug</code></pre>
<p>в другой</p>
<pre><code>tail -f -n 0 /var/log/syslog</code></pre>
<p>и пробуете подключиться. <strong>После</strong> того как случится фейл, присылайте что напечатает за это время в обоих терминалах (в выводе первой команды <strong>может засветиться ваш пароль &#8212; замените его звездочками</strong>!).</p>
<h2>Альтернативные GUI программы для подключения к L2TP VPN в Linux</h2>
<p>Если этот плагин почему то так у вас и не заработал, можете попробовать одну из следующих GUI-программ (к слову, все эти L2TP-GUI, в т.ч. и мой плагин, &#171;внутри себя&#187; используют одни и те же консольные программы: <a href="http://www.xelerance.com/services/software/xl2tpd/" target="_blank">xl2tpd</a> (для L2TP), <a href="http://ppp.samba.org/" target="_blank">pppd</a> (для VPN) и <a href="http://openswan.org/" target="_blank">openswan</a> (для IPSec), но генерируют к ним немного разные конфиги и запускают их немного по разному).</p>
<h3>vpnpptp</h3>
<p><a href="http://code.google.com/p/vpnpptp/" target="_blank">Официальный сайт vpnpptp</a>. Программа написана на Pascal и Bash с использованием Qt. Из плюсов &#8212; много настроек, разрабатывается нашими соотечественниками, оптимизирована для подключения к beeline. Из минусов, пожалуй, довольно нестабильная работа, необходимость вводить root-пароль для подключения и не очень удобный интерфейс. (Ну и еще сам код программы жуткий).</p>
<h3>L2tp-IPsec-VPN</h3>
<p><a href="https://launchpad.net/l2tp-ipsec-vpn" target="_blank">Сайт</a>, <a href="http://wiki.l2tpipsecvpn.tuxfamily.org/wiki/index.php?title=Main_Page" target="_blank">Wiki</a>. Написана на C++ и Qt. Из плюсов &#8212; очень хорошая поддержка IPsec, неплохой интерфейс, можно подключаться без root пароля, активно разрабатывается, дружелюбный разработчик =). Из минусов &#8212; опять же, недостаточно стабильная работа, поддержку работы БЕЗ IPSec (нужно для работы с beeline) добавили совсем недавно (по моей <a href="https://answers.launchpad.net/l2tp-ipsec-vpn/+question/184430" target="_blank">просьбе</a>), но заставить его работать с beeline так и не получилось.</p>
<h2>Эпилог</h2>
<p>Разработку веду на Github <a href="https://github.com/seriyps/NetworkManager-l2tp" target="_blank">https://github.com/seriyps/NetworkManager-l2tp</a>.<br />
Пожелания, багрепорты, комментарии, благодарности приветствуются.</p>
<p>Тикеты с просьбой добавить поддержку L2TP в NM появились на <a href="https://bugs.launchpad.net/network-manager/+bug/264691" target="_blank" title="NM 0.7 No option for connecting to L2TP IPSEC VPN">Launchpad</a> и <a href="https://bugzilla.gnome.org/show_bug.cgi?id=554046" target="_blank" title="[enh] L2TP VPN support">Gnome</a> в сентябре 2008г. Изначально плагин разработал Alexey Torkhov, но затем прекратил его поддержку.</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2012/01/31/plagin-l2tp-dlya-networkmanager/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
		<item>
		<title>Использование Django ORM отдельно от Django</title>
		<link>http://seriyps.ru/blog/2011/06/20/django-orm-standalone/</link>
		<comments>http://seriyps.ru/blog/2011/06/20/django-orm-standalone/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 08:39:48 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[standalone]]></category>
		<category><![CDATA[костыли]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=679</guid>
		<description><![CDATA[Понадобилось использовать Django ORM вне контекста самой Django. Конечно, проще и правильнее было бы использовать SQLAlchemy т.к. она рассчитана на такое использование, но мне нужно было написать паука, сохраняющего данные в БД и веб-интерфейс к этим данным. Веб-интерфейс точно решил делать на Django, а в пауке использовать те-же самые модели, чтобы не проделывать одну и [...]]]></description>
			<content:encoded><![CDATA[<p>Понадобилось использовать Django ORM вне контекста самой Django. Конечно, проще и правильнее было бы использовать SQLAlchemy т.к. она рассчитана на такое использование, но мне нужно было написать паука, сохраняющего данные в БД и веб-интерфейс к этим данным. Веб-интерфейс точно решил делать на Django, а в пауке использовать те-же самые модели, чтобы не проделывать одну и ту же работу дважды. Т.к. паук был первым этапом работ а админка &#8212; вторым, появилась необходимость создавать таблицы из моделей без использования &#171;syncdb&#187;.</p>
<p>В качестве основы использовалкод модуля <a title="stanfalone Django ORM module" href="https://bitbucket.org/rfc1437/django-standalone">django-standalone</a> и статью <a title="standalone Django ORM" href="http://imbolc.name/2009/12/django-orm.html">Django ORM без Джанги</a> - эта статья практически полностью решает проблему, но есть и несколько недостатков:</p>
<ul>
<li>Модели для создания таблиц нужно перечислять вручную</li>
<li>Не создаются внешние ключи</li>
<li>По &#8212; мелочи &#8212; нужно каждой модели вручную задавать app_label</li>
</ul>
<p>Попытаемся исправить эти недостатки.</p>
<p><span id="more-679"></span>Сразу предупреждаю, что от необходимости устанавливать Django нас статья не освобождает. Так что первым шагом устанавливаем Django:</p>
<p><code class="bash">sudo pip install Django</code></p>
<p>Собственно, приведу сразу код с комментариями</p>
<pre><code>#/usr/bin/env python
# -*- coding: utf8 -*-

from django.conf import settings
settings.configure(
    # задаем параметры подключения к БД
    DATABASES={
        'default': {
            'ENGINE': 'postgresql_psycopg2', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
            'NAME': '***', # Or path to database file if using sqlite3.
            'USER': '***', # Not used with sqlite3.
            'PASSWORD': '***', # Not used with sqlite3.
            'HOST': '****', # Set to empty string for localhost. Not used with sqlite3.
            'PORT': '****', # Set to empty string for default. Not used with sqlite3.
        }
    },
    # этот префикс будет добавляться к именам таблиц вместо имени приложения
    # его нужно указывать только при использовании в скрипте. При использовании в
    # Django этот параметр лучше убрать.
    STANDALONE_APP_NAME='some_prefix'
)

from django.db import models

class StandAloneMetaclass(models.base.ModelBase):
    """Метакласс, который задает app_label моделям используя
    значение из STANDALONE_APP_NAME"""
    def __new__(cls, name, bases, attrs):
        app_name = settings.STANDALONE_APP_NAME or None
        if app_name:
            if 'Meta' in attrs:
                if not hasattr(attrs['Meta'], 'app_label'):
                    # устанавливаем app_label только если он уже не указан в самой модели
                    setattr(attrs['Meta'], 'app_label', app_name)
        return super(StandAloneMetaclass, cls).__new__(cls, name, bases, attrs)

class BlogNote(models.Model):
    __metaclass__ = StandAloneMetaclass  # всем моделям нужно прописать этот метакласс
    text=models.TextField()
    # необходимо добавить атрибут Meta всем моделям для корректной работы метакласса
    class Meta:
        pass

class BlogComment(models.Model):
    __metaclass__ = StandAloneMetaclass
    text=models.TextField()
    note=models.ForeignKey(BlogNote)  # внешние ключи тоже работают

    class Meta:
        pass

def create_tables(tables):
    from django.db import connection, transaction
    from django.core.management.color import no_style
    pending_references = {}  # список внешних колючей, ожидающих создания связываемых таблиц
    seen_models = set()  # список созданных
    style = no_style()  # указывает, что не нужно раскрашивать синтаксис сгенерированного SQL
    for model in tables:  # проходим по списку моделей
        sql, references = connection.creation.sql_create_model(model, style) # генерируем SQL и объекты внешних ключей
        seen_models.add(model)
        for refto, refs in references.items():
            pending_references.setdefault(refto, []).extend(refs)
            if refto in seen_models:
                sql.extend(  # если все таблицы внешнего ключа существуют, то добавляем сам ключ
                    connection.creation.sql_for_pending_references(
                            refto,
                            style,
                            pending_references))
        sql.extend(
            connection.creation.sql_for_pending_references(
                model,
                style,
                pending_references))
        cursor = connection.cursor()
        for stmt in sql:  # выполняем запросы к БД
            print stmt
            try:
                cursor.execute(stmt)
            except Exception, e:
                print e
                pass
        print
    transaction.commit_unless_managed()  # завершаем транзакцию
    for model in tables:  # создаем индексы
        index_sql = connection.creation.sql_indexes_for_model(model, style)
        if index_sql:
            try:
                for stmt in index_sql:
                    print stmt
                    cursor.execute(stmt)
            except Exception, e:
                transaction.rollback_unless_managed()
            else:
                transaction.commit_unless_managed()

if __name__ == "__main__":
    # находим все классы Django моделей в локальной области видимости и создаем для них
    # таблицы в БД
    create_tables(model for model in locals().values() if type(model) == StandAloneMetaclass)</code></pre>
<p>Большая часть содержимого create_table() скопировано из файла <a title="syncdb" href="https://code.djangoproject.com/browser/django/trunk/django/core/management/commands/syncdb.py">django/core/management/commands/syncdb.py</a>. По сравнению с оригинальной статьей отпала необходимость вручную указывать для каждой модели app_label и вручную передавать список моделей для создания. Но появилась необходимость прописывать <code>__metaclass__</code>. Успокаивает то, что он один и тот же для всех классов. Ну и необходимо всем прописывать <code>class Meta: pass</code>. Можно это поправить, если создать базовый класс абстрактной модели с этими атрибутами и наследовать все модели от него.</p>
<p>Ну и общее впечатление &#8212; Django ORM не самое удачное решение для использования отдельно от  Django. Если есть возможность, стоит использовать более подходящие библиотеки, например <a title="SQLAlchemy Python ORM" href="http://www.sqlalchemy.org/">SQLAlchemy</a>. Она хоть и более сложна для освоения, но и более мощная, поддерживает пуллинг соединений, более управляемая и рассчитана на такое использование.</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2011/06/20/django-orm-standalone/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Плагин Vkontakte.ru для Gwibber</title>
		<link>http://seriyps.ru/blog/2011/01/31/plugin-vkontakte-ru-dlya-gwibber/</link>
		<comments>http://seriyps.ru/blog/2011/01/31/plugin-vkontakte-ru-dlya-gwibber/#comments</comments>
		<pubDate>Mon, 31 Jan 2011 07:04:01 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[bazaar]]></category>
		<category><![CDATA[gwibber]]></category>
		<category><![CDATA[Launchpad]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[vkontakte]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=612</guid>
		<description><![CDATA[Вступление Не так давно решил вплотную познакомиться со всей кухней OpenSource со стороны разработчика и в качестве первой пробы решил написать плагин к Gwibber для поддержки Вконтакте. Надо сказать, что тикет на Launchpad на эту тему висит с середины 2010 года (датирован 2010-05-01) с довольно длинным обсуждением, было несколько попыток реализовать поддержку, но готового решения [...]]]></description>
			<content:encoded><![CDATA[<h3>Вступление</h3>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2011/01/gwibber_vk.png"><img class="alignright size-full wp-image-613" title="Gwibber + Vkontakte" src="http://seriyps.ru/blog/wp-content/uploads/2011/01/gwibber_vk.png" alt="Gwibber + Vkontakte" width="338" height="150" /></a>Не так давно решил вплотную познакомиться со всей кухней OpenSource со стороны разработчика и в качестве первой пробы решил написать плагин к Gwibber для поддержки Вконтакте. Надо сказать, что <a title="Launchpad bug #572753" href="https://bugs.launchpad.net/gwibber/+bug/572753" target="_blank">тикет на Launchpad</a> на эту тему висит с середины 2010 года (датирован 2010-05-01) с довольно длинным обсуждением, было несколько попыток реализовать поддержку, но готового решения никто не предложил. Помимо Launchpad, появился <a title="Протокол vkontakte.ru для gwibber на Ubuntu.ru" href="http://forum.ubuntu.ru/index.php?topic=65621.0">топик на форуме Ubuntu.ru</a>, в котором топикстартер сообщил, что реализовал поддержку ВК, но код так никому и не показал.</p>
<p>Так что в начале декабря <a title="Launchpad gwibber/vkontakte-ru-plugin branch" href="https://code.edge.launchpad.net/~seriy-pr/gwibber/vkontakte-ru-plugin">взялся за работу</a> и через 2 месяца рабочая протестированная версия плагина была готова. На данный момент я уже отправил запрос о включении плагина в официальную ветку Gwibber и буквально сегодня разработчики отметили его для включения в <a title="Gwibber 2.91.5 milestone" href="https://launchpad.net/gwibber/+milestone/2.91.5">релиз 2.91.5</a>.<br />
Описание функционала, инструкция для желающих протестировать плагин в работе уже сейчас под катом&#8230;<span id="more-612"></span></p>
<h3>Доступный функционал</h3>
<p>На данный момент работает:</p>
<ul>
<li>Загрузка текстовых постов из новостей</li>
<li>Загрузка видео &#8212; постов</li>
<li>Загрузка постов &#8212; ссылок</li>
<li>Загрузка постов  с фото и граффити</li>
<li>Отправка сообщений на свою стену</li>
<li>Комментирование постов</li>
<li>&#171;Мне нравится&#187; (сердечко)</li>
<li>Удаление моих постов</li>
</ul>
<p>Хочется добавить:</p>
<ul>
<li>Поддержку &#171;ретвитов&#187; (&#171;Мне нравится&#187;+&#187;Рассказать друзьям&#187;) Пока архитектура Gwibber не позволяет это сделать</li>
<li>Поддержку mentions (упоминание). Вконтакте выглядит как ссылка &#171;ответить на моей странице&#187;. В Gwibber сейчас отображается как &#171;[id535397|Сергей Прохоров﻿﻿], &#171;. Примитивную поддержку сейчас добавить ничего не мешает.</li>
<li>Поддержку личных сообщений (Пока что в сомнениях нужно ли это. В любом случае будет отдельная галочка в настройках аккаунта)</li>
</ul>
<p>Известные проблемы:</p>
<ul>
<li>После смены IP адреса появляется сообщение об ошибке <strong>&#171;Unknown method passed&#187;</strong>. Дело в том, что авторизационный &#171;токен&#187; API вконтакте привязан к IP адресу (видимо для защиты от взлома аккаунта) и после каждой смены IP его нужно обновлять. Делать это в фоновом режиме в текущей реализации самого Gwibber сейчас нельзя. Особенно доставляет тот факт, что сообщение об ошибке ни о чем не говорит&#8230; Так что нажимаем &#171;редактировать&#187; и заново проходим процедуру авторизации, жмем F5 для получения последних сообщений.</li>
</ul>
<h3>Инструкция по установке</h3>
<p>Прежде всего хочу отметить, что пользоваться этой инструкцией стоит только если очень хочется протестировать плагин прямо сейчас, т.к. скорее всего через месяцок-другой, надеюсь, плагин войдет в официальный релиз. Итак, от слов перейдем к делу.</p>
<h4>Подготовка</h4>
<p><strong>UPD:</strong> для natty этот пункт можно пропустить, т.к. там установлена новая версия Gwibber.</p>
<p><strong>Важно!</strong> Не пропустите! Т.к. поддержка плагинов появилась только в ветке 2.91.x, а в Ubuntu Maverick установлена версия 2.32.x, то необходимо сперва установить последнюю версию из <a title="Gwibber trunk PPA" href="https://launchpad.net/~gwibber-daily/+archive/ppa">девелоперского PPA</a> &#171;deb http://ppa.launchpad.net/gwibber-daily/ppa/ubuntu maverick main #Gwibber-Daily PPA&#187; командами</p>
<pre class="brush: bash; title: ; notranslate">sudo add-apt-repository ppa:gwibber-daily/ppa
sudo apt-get update
sudo apt-get upgrade</pre>
<p>Эти команды обновят основные модули Gwibber. <strong>Важно!</strong> Т.к. все протоколы теперь поставляются в виде отдельных пакетов, нужные протоколы необходимо устанавливать самостоятельно. Если этого не сделать, то Gwibber не запустится, а при запуске <code>gwibber</code> из консоли увидим</p>
<pre>Traceback (most recent call last):
  File "/usr/bin/gwibber", line 87, in
    client.Client()
  File "/usr/lib/python2.6/dist-packages/gwibber/client.py", line 621, in __init__
    self.w = GwibberClient()
.........
  File "/usr/lib/pymodules/python2.6/mako/runtime.py", line 278, in
    return lambda *args, **kwargs:callable_(self.context, *args, **kwargs)
  File "base_mako", line 251, in render_image
  File "base_mako", line 192, in profile_url
  File "base_mako", line 829, in render_profile_url
KeyError: u'twitter'</pre>
<p>Посмотреть список протоколов можно командой</p>
<pre class="brush: bash; title: ; notranslate">aptitude search gwibber-service-+</pre>
<p>Установим минимум &#8212; протоколы facebook и twitter:</p>
<pre class="brush: bash; title: ; notranslate">sudo aptitude install gwibber-service-{twitter,facebook}</pre>
<p>После этого можете попробовать запустить Gwibber и убедиться что версия обновилась.<br />
<img class="alignnone size-full wp-image-615" title="Gwibber about" src="http://seriyps.ru/blog/wp-content/uploads/2011/01/gwibber_new1.png" alt="Gwibber about" width="392" height="250" /></p>
<h4>Установка плагина Vkontakte.ru</h4>
<h5>UPD 2011-05-22: Вариант номер ноль. Используйте его! &#8212; установка из PPA</h5>
<p>Для поддержки плагина создан PPA на Launchpad. Можно установить плагин, подключив этот PPA:</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-add-repository ppa:gwibber-vkontakte-plugin/ppa
sudo apt-get update
sudo aptitude install gwibber-service-vkontakte</pre>
<p>Обновляться теперь будет автоматически!</p>
<h5>Вариант номер раз &#8212; установка из DEB пакета</h5>
<p>Добрый товарищ <a href="http://forum.ubuntu.ru/index.php?action=profile;u=7909">ZwS (Антон Судак?)</a> с форума Ubuntu.ru <a href="http://forum.ubuntu.ru/index.php?topic=65621.msg1004248#msg1004248">собрал .DEB пакет</a>, многие уже писали что установили этот пакет и у них все успешно заработало. Вот ссылки для скачивания DEB пакета для установки плагина<br />
<span style="text-decoration: line-through;"><strong>(<a href="http://www.mediafire.com/?5ct1wzc2gkajxp4">оригинальная</a>), (<a href="http://dl.seriyps.ru/soft/gwibber-service-vkontakte_2.91.3~bzr941-0_all.deb">мое зеркало</a>)</strong> md5 ﻿﻿e3ce23c5328fec6b54c2d549a4870812</span><br />
<strong>UPD:</strong> новая версия <strong>(<a href="http://www.mediafire.com/?z2ye2u9chtda9vu">оригинальная</a>), (<a href="http://dl.seriyps.ru/soft/gwibber-service-vkontakte_3.0.0~bzr966-0_all.deb">мое зеркало</a>)</strong> md5 d9cdb8299eebf8d7145dd219a3f75219</p>
<p>Просто скачиваете файл, запускаете, все подтверждаете, перезапускаете Gwibber, готово. Преимущества такого подхода &#8212; легко удалить если что-то сломается (<code>sudo aptitude remove gwibber-service-vkontakte</code>) и если выйдет официальная версия плагина, то она без проблем установится поверх этой.</p>
<h5>Вариант номер два (им пользуюсь я) &#8212; установка симлинков из bzr исходного кода</h5>
<p>Пользуюсь потому что так можно запускать код написанный прямо сейчас, но просто так им пользоваться не советую.</p>
<p>Устанавливаем bazaar</p>
<pre class="brush: bash; title: ; notranslate">sudo aptitude install bzr</pre>
<p>Загружаем исходники Gwibber из моего репозитория Launchpad</p>
<pre class="brush: bash; title: ; notranslate">bzr branch lp:~seriy-pr/gwibber/vkontakte-ru-plugin</pre>
<p>После этого главная магия &#8212; делаем симлинки на некоторые кукски моего кода в директории откуда Gwibber их подхватит:</p>
<pre class="brush: bash; title: ; notranslate">sudo ln -s /home/$USER/vkontakte-ru-plugin/gwibber/microblog/plugins/vkontakte/ /usr/share/gwibber/plugins/
sudo ln -s /home/$USER/vkontakte-ru-plugin/ui/icons/breakdance/16x16/vkontakte.* /usr/share/gwibber/ui/icons/breakdance/16x16/
sudo ln -s /home/$USER/vkontakte-ru-plugin/ui/icons/breakdance/22x22/vkontakte.* /usr/share/gwibber/ui/icons/breakdance/22x22/
sudo ln -s /home/$USER/vkontakte-ru-plugin/ui/icons/breakdance/scalable/vkontakte.* /usr/share/gwibber/ui/icons/breakdance/scalable/</pre>
<p>И тогда должно заработать (только это небезопасно т.к. содержимое /home/$USER/vkontakte-ru-plugin доступно для записи). Если удалить директорию vkontakte-ru-plugin из домашней папки то работать перестанет. Чтобы этого избежать можно в предыдущем списке команд заменить команды &#171;ln -s&#187; на &#171;cp&#187;<br />
Преимущества &#8212; для НЕразработчика &#8212; вам будет доступна самая последняя-распоследняя версия плагина. Недостатки &#8212; относительно сложно, небезопасно, могут возникнуть проблемы при обновлении.<br />
Если после этого у вас Gwibber вдруг перестанет стартовать, можно подчистить следы деятельности командами</p>
<pre class="brush: bash; title: ; notranslate">sudo rm -r /usr/share/gwibber/plugins/vkontakte
sudo rm -r /usr/share/gwibber/ui/icons/breakdance/*/vkontakte*</pre>
<h5>Способ номер три (я не проверял, но есть люди у которых он работает) &#8212; установка из &#171;исходного кода&#187; с помощью setup.py</h5>
<p>Gwibber поддерживает distutils, соответственно его можно установить непосредственно из исходного кода с помощью файла setup.py. Преимущества и недостатки у этого метода примерно такие &#8212; же как у второго, но в случае неудачи подчистить следы будет сложнее. Сам я этот метод не проверял, поэтому скопирую краткое резюме из <a href="http://metall-corn.blogspot.com/2011/01/gwibber.html">инструкции, приведенной товарищем M.CoRN в его блоге</a> (мои благодарности ему):</p>
<pre class="brush: bash; title: ; notranslate">bzr branch lp:~seriy-pr/gwibber/vkontakte-ru-plugin
sudo apt-get install python-dbus python-gtk2 python-gconf python-notify python-simplejson python-egenix-mxdatetime python-distutils-extra python-feedparser
cd vkontakte-ru-plugin
sudo python setup.py install</pre>
<p>Если решите воспользоваться этой инструкцией, настоятельно рекомендую воспользоваться ее оригиналом, там есть дополнительные комментарии и рекомендации на случай появления ошибок.</p>
<h3>Настройка учетной записи вконтакте в Gwibber</h3>
<p>Ну тут как обычно все. Редактировать -&gt; Учетные записи (или запустить приложение &#171;gwibber-accounts&#187;) -&gt; Добавить -&gt; в выпадающем списке выбрать &#171;<a href="http://seriyps.ru/blog/wp-content/uploads/2011/01/vkontakte.png"><img title="vkontakte" src="http://seriyps.ru/blog/wp-content/uploads/2011/01/vkontakte.png" alt="" width="16" height="16" /></a> Vkontakte&#187; -&gt; Добавить -&gt; Выставьте галочки (&#171;Получать сообщения&#187; &#8212; чтобы получать сообщения вообще, &#171;Посылать сообщения&#187; &#8212; чтобы можно было отправлять сообщения и комментарии, &#171;Receive groups&#187; &#8212; это уже моя самодеятельность, если отмечено, будет загружать новости от групп, помимо новостей от друзей) -&gt; Авторизовать -&gt; Вводим логин-пароль, выставляем все галочки, жмем &#171;Разрешить&#187;. Если все прошло успешно, закрываем окно, жмем F5 для обновления и пользуемся!</p>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2011/01/gwibber_authorized.png"><img class="alignnone size-full wp-image-618" title="gwibber_authorized" src="http://seriyps.ru/blog/wp-content/uploads/2011/01/gwibber_authorized-e1296425380518.png" alt="" width="370" height="214" /></a> <a href="http://dl.seriyps.ru/img/vk_gwibber.png"><img class="alignnone" title="Vkontakte gwibber в действии" src="http://dl.seriyps.ru/img/vk_gwibber.png" alt="" width="284" height="311" /></a></p>
<h3>Что дальше?</h3>
<p>Если есть какие-то пожелания/советы/отчеты об ошибках милости прошу в комментарии. Если хотите помочь и у вас есть аккаунт на Launchpad, отпишитесь тут ﻿<a href="https://bugs.launchpad.net/gwibber/+bug/572753">https://bugs.launchpad.net/gwibber/+bug/572753</a> и тут <a href="https://code.launchpad.net/~seriy-pr/gwibber/vkontakte-ru-plugin/+merge/47651">https://code.launchpad.net/~seriy-pr/gwibber/vkontakte-ru-plugin/+merge/47651</a> что у вас все работает или наоборот ничего не работает, так этот плагин быстрее попадет в официальную поставку.</p>
<p>Как водится, выражаю благодарность <a href="https://launchpad.net/~hanzhin-stas">Stanislav Hanzhin</a>, <a href="https://launchpad.net/~sergeyreym">sergeyreym</a> за активное участие, советы и багрепорты,  Nazar Vinnichuk и остальным разработчикам <a href="https://launchpad.net/rhythmbox-plugin-vkontakte">Rhythmbox&#8217;s plugin for Vkontakte.ru</a> &#8212; их наработки послужили основой для плагина, <a href="http://forum.ubuntu.ru/index.php?action=profile;u=7909">ZwS (Антон Судак?)</a> за .DEB пакет, ну и всем остальным кто принимал и принимает посильное участие.</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2011/01/31/plugin-vkontakte-ru-dlya-gwibber/feed/</wfw:commentRss>
		<slash:comments>49</slash:comments>
		</item>
		<item>
		<title>Отчет о конференции ADD-2010 в Ярославле</title>
		<link>http://seriyps.ru/blog/2010/09/29/otchet-o-konferencii-add2010-v-yaroslavle/</link>
		<comments>http://seriyps.ru/blog/2010/09/29/otchet-o-konferencii-add2010-v-yaroslavle/#comments</comments>
		<pubDate>Wed, 29 Sep 2010 12:07:11 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[Общекомпьютерное]]></category>
		<category><![CDATA[ADD]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[map-reduce]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[VCS]]></category>
		<category><![CDATA[конференция]]></category>
		<category><![CDATA[отзыв]]></category>
		<category><![CDATA[Ярославль]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=575</guid>
		<description><![CDATA[Побывал 23-24 сентября на конференции Application developer days в Ярославле. Вот решил написать краткий отчет. Сперва об организационных моментах. Организация В целом организация неплохая. Неудобно было только то, что добираться в Ярославль к началу конференции было практически не на чем (не считая собственного транспорта). Поэтому пришлось выезжать за день до начала конференции. С жильем решили [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-595" title="bf-logo_small" src="http://seriyps.ru/blog/wp-content/uploads/2010/09/bf-logo_small.gif" alt="" width="148" height="156" />Побывал 23-24 сентября на конференции <strong><a href="http://it-conf.ru/ru/content/267.htm" target="_blank">Application developer days</a></strong> в Ярославле. Вот решил написать краткий отчет.<span id="more-575"></span> Сперва об организационных моментах.</p>
<h2>Организация</h2>
<p>В целом организация неплохая. Неудобно было только то, что добираться в Ярославль к началу конференции было практически не на чем (не считая собственного транспорта). Поэтому пришлось выезжать за день до начала конференции. С жильем решили не выпендриваться и поселились в Профилактории Железнодорожник, который расположен в пяти минутах ходьбы от места проведения конференции и ЖД вокзала (и в 2-х минутах от кладбища).</p>
<p>Само мероприятие проходило в ДК Железнодорожник.</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr valign="TOP">
<td width="50%"><a href="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4613.jpg"><img class="alignnone size-thumbnail wp-image-577" title="IMG_4613" src="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4613-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>Профилакторий «Железнодорожник»</td>
<td width="50%"><a href="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4616.jpg"><img class="alignnone size-thumbnail wp-image-578" title="IMG_4616" src="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4616-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>ДК «Железнодорожник»</td>
</tr>
<tr valign="TOP">
<td width="50%"><a href="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4602.jpg"><img class="alignnone size-thumbnail wp-image-579" title="IMG_4602" src="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4602-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>ДК изнутри. Холл перед секцией А</td>
<td width="50%"><a href="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4604.jpg"><img class="alignnone size-thumbnail wp-image-580" title="IMG_4604" src="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4604-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>ДК изнутри. Холл перед секцией А</td>
</tr>
</tbody>
</table>
<h2>Доклады</h2>
<p>Сама по себе конференция общего профиля, т.е. не тематическая. Просто посвящена программированию и программистам. Доклады шли в три потока, соответственно по секциям A, B и C. Зал секции A раза в 3 больше других, в нем предполагается проводить доклады, на которые придет больше всего слушателей (почему-то все время был заполнен процентов на 10-20). Секция B — секция для докладов с аудиторией поменьше (тут места практически всегда не хватало) и секция C — это зал совещаний с круглым столом, здесь читали некоторые доклады и проводили непосредственно круглые столы.</p>
<p>С программой конференции можно ознакомиться по ссылке <a href="http://it-conf.ru/ru/content/331.htm">http://it-conf.ru/ru/content/331.htm</a></p>
<h3>День первый</h3>
<p>После церемонии открытия конференции и отпаивания кофе с пирожками, первый доклад на который мы решили пойти:</p>
<h3>Стас Фомин, «Золотая середина. Открытые системы поддержки разработки»</h3>
<p>Вообще, докладчик довольно примечательный, эмоциональный. Для иллюстрации доклада использовал не презентацию PP а какие-то Mind Maps, было немного непривычно.</p>
<p>Рассматривал варианты выбора <strong>систем поддержки разработки</strong> (багтрекеры, Wiki, VCS). Противопоставлялись <strong>коммерческие</strong> системы и <strong>открытые</strong>. Плюсы коммерческих систем — коммерческая поддержка и, как правило, более широкий функционал, у открытых — открытый код и возможность расширять и дописывать системы самостоятельно.</p>
<p>Так же обсуждался выбор между <strong>интегрированными</strong> системами — комбайн «все в одном», когда и Wiki и трекер и прочие компоненты это один проект (такие как Redmine, Trac и т.п.)   и <strong>специализированные</strong> системы собранные и собственноручно склееные из отдельных компонентов. В первом варианте указывают на то, что компоненты такого «комбайна» будут уступать по функционалу специализированным решениям (Wiki редмайна будет уступать Mediawiki а трекер BugZill-е). Таким образом докладчик высказался в пользу последнего варианта, рассказал как в своей компании они связывали <strong>MediaWiki</strong>, <strong>BugZilla</strong> и <strong>SVN</strong>, сказал, что эту связку они планируют выложить на SourceForge в свободный доступ.</p>
<p><strong>От себя/вывод:</strong> я все же считаю, что объем работы по интеграции отдельных систем будет довольно большой и оправдан только для действительно крупных команд. Лично меня Redmine устраивает абсолютно всем.</p>
<h3>Олег царев, Кирилл Коринский, «Сравнительный анализ хранилищ данных»</h3>
<p>Выступление примечательно тем, что его читают два докладчика (когда по очереди, когда одновременно).</p>
<p>Начали с оценки требований к серверу на котором может храниться база графа друзей на FaceBook, Vkontakte и Мой мир. Пришли к выводу, что на одном сервере такая база не сможет храниться физически из-за ограничений на пропускную способность RAM, соответственно не обойтись без распределения БД&#8230; и через несколько минут кто-то из слушателей сообщил, что только что написал на коленке программу-эмулятор, прогнал ее и получил результат в 200 раз отличающийся от результатов докладчика. Забавно.</p>
<p>Далее лично я (как, думаю и все остальные) ожидали какого-то реального сравнительного обзора существующих решений хранилищ данных, холиваров SQL/NoSQL, рекомендаций в каких случаях какую БД стоит использовать, но на самом деле я даже не понял, что происходило на второй части доклада — докладчики постоянно друг друга перебивали, немного обсудили CAP теорему, толком не рассмотрели ни одной БД и пришли к выводу, что «<strong>серебрянной пули нет, для каждой проблемы нужно подбирать свое решение</strong>». Привет Капитану Очевидность ((.</p>
<p><strong>От себя/вывод:</strong> для меня доклад запомнился как «разочарование конференции». Все-таки ожидал какого-то практического обзора, опыта внедрения, конкретики короче,а получил абстрактного коня в вакууме и вывод от КО. К тому же докладчики постоянно друг друга перебивали, что только еще больше портило впечатление. Все надежды на круглый стол SQL vs NoSQL&#8230;</p>
<h3>Круглый стол, «Системы управления версиями»</h3>
<p>Первый круглый стол. Обсуждаем системы контроля версий. Вспомнили наиболее популярные сейчас системы: <strong>Subversion</strong>, <strong>GIT</strong>, <strong>Mercurial</strong>, <strong>Bazaar</strong> и даже коллекции патчей. Обсуджали модели разработки с блокировкой доступа к файлам (<strong>locking</strong>) и со слиянием (<strong>merging</strong>). Дискуссия завязалась довольно живая, мне даже показалось, что не обошлось без троллинга, т.к. 90% времени говорили 2 или 3 человека.</p>
<p>Насчет <strong>merging vs locking</strong>: метод с блокировкой неудобен тем, что над файлом одновременно может работать только один человек. Если он вдруг заболеет/уйдет в отпуск и забудет снять блокировку, то доступ к файлу кому-то еще получить будет проблематично. В то же время о merging говорили, что сам процесс слияния довольно сложный и может стать причиной множества багов. Проскользнула мысль, что locking эффективен в команде низкоквалифицированных разработчиков/Junior Developer-ов или студентов, т.к. <strong>меньше шанс что-то сломать при слиянии</strong>.</p>
<p><em>Subversion</em> ругали за то, что в нем особенно сильно проявляются <strong>проблемы слияния ветвей</strong> и что реализовано это в нем крайне примитивно. На этом фоне GIT смотрится гораздо приятнее. Из плюсов Subversion/централизованных VCS — централизованный контроль прав доступа, удобство составления плана релизов и то, что централизованные репозитории не дают разработчикам расслабиться (т.к. все коммиты попадают в центральный репозиторий и за этим процессом может наблюдать начальство). Таким образом <strong>Subversion хорош в основном для корпоративных разработок</strong>.</p>
<p><em>Распределенные системы</em> хороши простотой установки и использования, концепцией локальных ветвей и микрокоммитов, более продвинутым слиянием веток, высокой скоростью работы за счет уменьшения работы с сетью и взаимодействия с центральным репозиторием ну и возможность коммитить даже не имея интернета. Из минусов отметили&#8230; отсутствие центрального репозитория. Отметили что <strong>DVCS лучше подходят для OpenSource и некоммерческой разработки</strong>.</p>
<p>Немного касались платформ для разработки. Поговорили о <strong>Launchpad, GitHub, GoogleCode</strong>.</p>
<p><strong>От себя/вывод:</strong> еще раз подтвердилась мысль о том, что использовать Git в качестве основного репозитория в компании не очень удобно, SVN с этой задачей справляется достаточно хорошо. А для своих проектиков Git и другие DVCS — самое то. Хотя на работе я все равно использую git-svn: на рабочем месте использую Git, а потом экспортирую коммиты в корпоративный SVN. Довольно удобно, я уже привык.</p>
<h3>Максим Лапшин, «Разработка видеохостинга на Erlang»</h3>
<p>Пожалуй этот доклад мне понравился больше всего. Хороший докладчик, рассказывал о разработанном им сервере для потокового вещания аудио/видео <strong>ErlyVideo</strong> <a href="http://erlyvideo.org/">http://erlyvideo.org/</a> и о языке <strong>Erlang</strong> в целом.</p>
<p><em>Erlang</em> — функциональный интерпретируемый язык программирования enterprise уровня с  динамической типизацией и простым синтаксисом. Основные преимущества — <strong>легковесные независимые потоки/нити</strong>, простота создания <strong>параллельных программ </strong>и поддержка <strong>горячего обновления кода</strong>. На нем написан самый популярный Jabber сервер ejabberd и еще множество различных хорошо масштабируемых отказоустойчивых сервисов. В частности, докладчик разрабатывал на Erlang бэкенд для лидирующей в рейтинге приложений Вконтакте игры &#171;Лицемер&#187;.</p>
<p>Сам видеосервер успешно работает на нескольких видеохостингах и уделывает всех конкурентов по производительности и стабильности.</p>
<p><strong>От себя/вывод:</strong> все-таки разрабатывать параллельные и асинхронные программы на объектно ориентированных языках менее эффективно, чем на функциональных. Думаю в ближайшем будущем попробовать поучить Erlang. Заинтересовало. До этого из функциональных ЯП работал только с XSLT и впечатления остались исключительно положительные.</p>
<h3>Андрей Аксенов, «3D — графика на трех пальцах»</h3>
<p><em>Андрей Аксенов</em> больше всего прославился как разработчик поискового сервера <strong>Sphinx</strong>, на этой конференции про Sphinx не прочитал ни одного доклада, зато рассказал об <strong>основах 3D графики</strong>.</p>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4599.jpg"><img class="alignnone size-large wp-image-581" title="Андрей Аксенов, «3D — графика на трех пальцах»" src="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4599-1024x673.jpg" alt="Андрей Аксенов, «3D — графика на трех пальцах»" width="614" height="404" /></a></p>
<p>Основная идея — все улучшения в современных техниках рендеринга представляют из себя микрооптимизации направленные не столько на реалистичность, сколько на улучшение восприятия. «<strong>Главное не чтобы было реалистично, главное чтобы было красиво</strong>».</p>
<p><strong>От себя/вывод:</strong> В вопросах 3D графики разбираюсь слабо, но для общего развития послушать можно.</p>
<h3>Алексей Алексеев, Николай Гребнев, «Предупреждение ошибок программиста с помощью статического анализа кода и доменной модели»</h3>
<p>Докладчики разрабатывают на C# или .NET с которыми я не знаком, поэтому понимал о чем говорят с трудом. Обсуждали ORM, Linq и еще что-то. Так ничего и не поняв, решил переместиться на параллельный доклад.</p>
<h3>Кирилл Коринский, «Информирование о загрузке базовых станций Yota»</h3>
<p>К сожалению, когда мы подошли доклад уже заканчивался. Что успел понять: нагрузки в их системе огромные, они написали и внедрили свою InMemory базу данных, которая отлично справляется с возложенными на нее задачами, и за время эксплуатации не было ни одного сбоя. Ну что ж, замечательно. Остается порадоваться.</p>
<h3>Елена Сагалаева, «Искусственный интеллект в играх»</h3>
<p><em>Елена Сагалаева </em>ведет довольно популярный блог посвященный разработке на  C++ <a href="http://alenacpp.blogpost.com/">http://alenacpp.blogpost.com/</a>, прочитала доклад о том, как создаются боты в компьютерных играх. Хоть игрушки и не мой профиль, но было довольно интересно.</p>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4600.jpg"><img class="alignnone size-large wp-image-582" title="Елена Сагалаева, «Искусственный интеллект в играх»" src="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4600-1024x693.jpg" alt="Елена Сагалаева, «Искусственный интеллект в играх»" width="614" height="416" /></a></p>
<p>Узнал что по настоящему «Искусственный интеллект» &#8212; <strong>нейронные сети</strong> в играх <strong>не</strong> используются, т.к. это не удобно по ряду причин. Основная — поведение обученной сети довольно трудно менять, поэтому в играх сейчас используют ботов работающих на обычных алгоритмах. Рассказали об алгоритмах поиска оптимального пути бота на карте, об алгоритмах следования за лидером, о приемах применяемых в компьютерных гонках.</p>
<p>Интересный вывод — бота надо сделать таким, чтобы человек у него все же выигрывал. Т.е. <strong>бот должен поддаваться, но делать это незаметно</strong>.</p>
<p><strong>От себя/вывод:</strong> просто довольно интересный обзорный доклад. В принципе получился коротковатый, можно было сделать подлиннее.</p>
<h3>День второй</h3>
<p>Думали на первую линейку докладов не ходить, но пересилили соблазн. Заинтересовал:</p>
<h3>Андрей Карпов, «Современный статический анализ кода»</h3>
<p><em>Андрей Карпов</em> — разработчик статического анализатора кода C++ для 64-битных и многопоточных программ <strong>PVS-studio</strong>. Много статей писал на Хабре о разработке на <strong>64-битной</strong> платформе и <strong>параллельном</strong> программировании <a href="http://habrahabr.ru/search/?q=viva64">http://habrahabr.ru/search/?q=viva64</a></p>
<p>Прочитал доклад о современном <strong>статическом анализе</strong>, о возможностях анализаторов кода, сделал краткий обзор современных анализаторов, приводил примеры нетривиальных ошибок в C++ коде. В целом весьма интересно. Только говорит очень быстро, такой поток слов мозг не всегда успевал обработать))</p>
<p><strong>От себя/вывод:</strong> как я понимаю, <strong>во все современные IDE встроен статический анализатор</strong>, так что его работу как-то не замечаешь и не задумываешься. А ведь без него было бы гораздо тяжелее. Открыл для себя, что статические анализаторы бывают и отдельно от IDE. Надо будет поискать какие решения существуют для PHP, Python, JavaScript. А ведь они помимо поиска ошибок умеют еще и за стилем кода следить (всякие там отступы/табуляции, где ставить открывающую скобку и т.п.) и отслеживать неоптимальные решения.</p>
<h3>Владимир Климонтович, «Apache Hadoop»</h3>
<p>Здесь рассказали о запатентованном Google алгоритме <strong>Map-Reduce</strong> и основанной на нем  распределенной базе данных <strong>Apache Hadoop</strong></p>
<p><strong><a href="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4606.jpg"><img class="alignnone size-large wp-image-583" title="Владимир Климонтович, «Apache Hadoop»" src="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4606-1024x674.jpg" alt="Владимир Климонтович, «Apache Hadoop»" width="614" height="404" /></a></strong></p>
<p>Сам алгоритм <em>Map-reduce</em> довольно прост, но чтобы понять всю его мощность и потенциал, надо немного вникнуть. Основное его преимущество — <strong>легкость масштабирования</strong>. Т.е. написав задачу для обсчета на map-reduce можно запустить ее хоть на одном, хоть на любом другом количестве серверов без изменения кода. Еще интересно было увидеть как <strong>SQL запросы выражаются с помощью map-reduce</strong>. Жаль что сам map-reduce в докладе был рассмотрен не так подробно — непосвященным было бы трудно понять. Неплохо было бы добавить несколько примеров и картинок и было бы вообще отлично.</p>
<p><em>Apache Hadoop</em> — нереляционная распределенная база данных основанная на принципе map-reduce. Для хранения своих баз использует собственную распределенную файловую систему. Предназначена для обработки <strong>огромных объемов данных на кластерах</strong>. На устраиваемом Yahoo соревновании по скоростной сортировке 100GB массива заняла первое место. На практике эта БД применялась в поисковике Yahoo для создания поискового индекса; на last.fm для подсчета рейтинга композиций (чартов) и еще много где. Сам докладчик сказал, что они успешно используют эту БД для анализа (на кластере) логов показов в сети контекстной рекламы, которых накапливается под сотню Гб в сутки.</p>
<p><strong>От себя/вывод:</strong> вообще map-reduce довольно интересная технология но, как я понимаю, реальные ее преимущества можно почувствовать только <strong>при больших объемах данных</strong> и распределенной архитектуре. Так что по мере появления необходимости буду вникать, а пока отложу на будущее. Опять же, процедуры для hadoop пишут на Java, с которой я на Вы.</p>
<h3>Круглый стол, «SQL vs NoSQL»</h3>
<p>Вот он, долгожданный холивар.</p>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4608.jpg"><img class="alignnone size-large wp-image-584" title="Круглый стол, «SQL vs NoSQL»" src="http://seriyps.ru/blog/wp-content/uploads/2010/09/IMG_4608-1024x682.jpg" alt="Круглый стол, «SQL vs NoSQL»" width="614" height="409" /></a></p>
<p>Обсуждение было довольно сбивчивым и к какому-то однозначному выводу прийти не смогли. Но все же, как мне показалось, <strong>верх одержали реляционные базы данных</strong> как более надежные, ынтырпрайзные и привычные. Прежде чем решаться использовать какую-то новую/экзотическую БД нужно 10 раз подумать. В качестве примера вспоминали уволенного начальника отдела разработки digg.com, т.к. под его руководством целый год безуспешно пытались перевести digg на <strong>Cassandra</strong>.</p>
<p>Вообще, основной аргумент <strong>против нереляционных бд</strong> была их недопиленность, недостаточная надежность, склонность падать и терять данные.</p>
<p>Довольно часто упоминался <strong>Яндекс маркет, </strong>т.к. у него довольно сложная структура данных со множеством различных атрибутов товаров, по которым необходимо делать фильтрацию, сортировку и пр., что довольно проблематично реализуется в рамках реляционных SQL БД. Представители Яндекса сознались, что в Маркете действительно используется <strong>самописная</strong> InMemory база данных.</p>
<p>Андрей Майоров рассказал об успешном использовании <strong>XML полей</strong> в MSSQL (оказывается по ним можно строить индексы и делать выборки/фильтрации с помощью XPath). XML поля имеются в MSSQL и Oracle.</p>
<p><strong>От себя/вывод: </strong>ждем когда допилят нереляционные БД до enterprise уровня, а пока продолжаем использовать старый добрый <strong>MySQL/Postgres</strong>. Хотя, конечно, в не самых ответственных или очень специфических случаях можно и пробовать прикручивать экзотику, но только если это на самом деле оправдано. Например <strong>Redis</strong> рекомендуют использовать в качестве менеджера очередей, <strong>Hadoop</strong> для распределенной обработки больших объемов информации. И еще — <strong>создание собственной БД</strong> для своего специфического проекта <strong>вполне реально</strong> и иногда оправдано (на примере Яндекс Маркета и Yota).</p>
<h3>Илья Кантор, «Удобная кросс-доменная авторизация»</h3>
<p><em>Илья Кантор</em> — создатель сайта <a href="http://javascript.ru/">http://javascript.ru</a>. Проводит мастер-классы по JavaScript и основанных на нем технологиях. Рассказал одновременно и как <strong>противостоять DDOS</strong> атакам, и как организовать <strong>кроссдоменную авторизацию</strong> и как реализовать <strong>персонализацию</strong> сайта для <strong>незарегистрированных</strong> пользователей.</p>
<p>Для отражения DDOS предлагается использовать связку <strong>Varnish</strong> и <strong>Redis</strong>. <em>Varnish</em> — это быстрый кеширующий прокси-сервер, позволяющий подключать свои модули, <em>Redis</em> — нереляционная key-value база данных, преимущественно InMemory. Суть трюка в том, что версия сайта для незарегистрированных пользователей (и, соответственно, ботов) загоняется в глубокий кеш Varnish-а, а персональные версии для зарегистрированных пользователей уже генерирует бэкенд. Главная хитрость заключается в том, что <strong>авторизация проверяется</strong> не на бэкенде, а непосредственно <strong>в Varnish</strong>. Клиент обращается к Varnish, varnish обращается к Redis (в котором хранятся сессии пользователей) для проверки залогинен ли пользователь. Если да — перенаправляет к бэкенду, если нет — отдает версию из своего кеша. Нагрузка на бэкенд снята, DDOS отражен.</p>
<p>Персонализация достигается за счет хранения сессий и прочих персональных данных на основе сессионной куки в Redis.</p>
<p>А кросс-доменная авторизация работает с использованием <strong>мастер-сервера авторизации</strong> с которого подключается специальный JavaScript файл, выставляющий авторизационную Cookie. Не все браузеры позволяют выставлять cookie с другого домена, для регулирования этих политик используются <strong>P3P</strong> HTTP заголовки. Но Safari не всегда доверяет этим заголовкам. В таком случае используется <strong>хак</strong> с отправкой POST запроса через IFRAME на мастер-домен.</p>
<p><strong>От себя/вывод: </strong>технологии довольно интересные и прогрессивные, думаю найдут применение в наших проектах. Насколько я помню, кросс-доменная авторизация используется на vkontakte.ru и vk.com.</p>
<h3>Илья Кантор, «Приватности в интернете нет» (секретный доклад)</h3>
<p>Доклад не анонсированный в программе конференции, занял половину обеденного времени). Было рассказано о способах идентификации в интернете не только с помощью Cookie. Довольно интересные и неочевидные способы идентификации через комбинации HTTP заголовков браузера, через Flash, Java, HTML5 LocalStorage и прочее.</p>
<p><strong>От себя/вывод:</strong> может пригодиться как для защиты от идентификации, так и для отслеживания или надежного «забанивания» пользователя.</p>
<h3>Евгений Кирпичев, «Многопоточное программирование»</h3>
<p>Рассказали о <strong>Линейной темпоральной логике</strong> (<strong>LTL</strong>), следование которой позволяет писать корректные параллельные программы. Есть <strong>анализаторы кода</strong>, позволяющие выявлять, используя LTL, потенциальные проблемы в параллельных программах (deadlocks etc.). Рассмотрены подходы и основные паттерны параллельной разработки (семафоры, мьютексы, блокировки). Не обошли стороной и асинхронное программирование. Мне показалось, что многовато математической теории, поэтому не все моменты были понятны.</p>
<p>Далее были рассмотрены возможности реализации параллельных программ на языках программирования <strong>Haskell</strong>, <strong>Erlang</strong>, <strong>Clojure</strong>,<strong> F#</strong>.</p>
<p><strong>От себя/вывод: </strong>все-таки параллельные и асинхронные программы гораздо аккуратнее выглядят и легче пишутся на языках, которые специально предназначены для написания таких программ. Приведенный пример на F# это наглядно подтвердил. Пожалуй, <strong>функциональные</strong> ЯП для параллельного программирования <strong>подходят больше</strong> других. Хотя есть и такие паттерны как, например, <strong>Deferred</strong>, которые позволяют довольно успешно писать параллельные программы на ОО языках без потери читаемости.</p>
<h2>Домой</h2>
<p>После было еще две линейки докладов, розыгрыши призов и закрытие конференции, но у нас были куплены билеты на поезд, так что на этом месте наше пребывание на конференции заканчивается. Всем спасибо, мы едем домой!</p>
<h2>Общие впечатления</h2>
<p>Понравилось что вокзал, гостиница и место проведения конференции расположены максимально близко, так что во время обеда успевали дойти до номера и передохнуть. Так же приятно порадовало что нас обеспечивали стабильным WiFi интернетом на протяжении всей конференции. Сам ДК Железнодорожник оказался весьма удачным местом для мероприятия — чистенькие отремонтированные залы, много свободного места, где можно пообщаться, пирожки и чай/кофе в неограниченном количестве. В общем атмосфера была дружелюбной и располагающей к общению.</p>
<p>Теперь негатив. Мне не понравилось то, что конференция была уж очень широкого профиля. Каждый рассказывал о том, о чем хотел. Секции тоже не тематические. На любой секции могли расказывать про БД, потом про Java, после про разработку игр, поэтому приходилось часто бегать из зала в зал.</p>
<p>На круглых столах не понравилось, что не было какого-то плана обсуждений, в результате дискуссия нередко переходила в область флейма на отвлеченные темы.</p>
<p>Еще немного подвел слабенький проектор в секции А — на многих интересных докладах трудно было разглядеть иллюстрации. Мелочь конечно, но отметить стоит.</p>
<p>Далее, обеды были ну совсем никакие. Спасли ситуацию только пирожки с кофе.</p>
<p>В общем и целом считаю, что конференция прошла удачно, но хотелось бы больше тематичности. Спасибо!</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2010/09/29/otchet-o-konferencii-add2010-v-yaroslavle/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Интеграция Redmine и Eclipse</title>
		<link>http://seriyps.ru/blog/2010/07/22/integraciya-redmine-i-eclipse/</link>
		<comments>http://seriyps.ru/blog/2010/07/22/integraciya-redmine-i-eclipse/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 08:38:11 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[mylyn]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[redmine]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=558</guid>
		<description><![CDATA[Вступление Большую часть времени разработчики проводят в двух местах &#8212; в IDE и в багтрекере/системе управления задачами (ну и, естественно, за гуглением/чтением всяких блогов, литературы etc). При этом, как правило, работая над конкретной задачей, разработчик использует весьма небольшое количество файлов проекта и возможностей IDE. Таким образом, все остальное окружение, не затронутое данной конкретной задачей, только [...]]]></description>
			<content:encoded><![CDATA[<h2>Вступление</h2>
<p><img class="alignright size-full wp-image-569" title="Eclipse-redmine_logos" src="http://seriyps.ru/blog/wp-content/uploads/2010/07/Eclipse-redmine_logos.png" alt="Логотипы eclipse и redmine" width="180" height="171" />Большую часть времени разработчики проводят в двух местах &#8212; в <strong>IDE</strong> и в <strong>багтрекере/системе управления задачами</strong> (ну и, естественно, за гуглением/чтением всяких блогов, литературы etc). При этом, как правило, работая над конкретной задачей, разработчик использует весьма небольшое количество файлов проекта и возможностей IDE. Таким образом, все остальное окружение, не затронутое данной конкретной задачей, только отвлекает и сбивает с толку. Помочь решить эту проблему призван замечательный плагин для не менее замечательной IDE Eclipse под названием mylyn.<span id="more-558"></span></p>
<p>Суть работы плагина следующая: вы создаете какое-либо задание (точь в точь как в багтрекере), например &#171;Пофиксить баг XXX&#187;, помечаете его как активное и начинаете как обычно над ним работать. При этом mylyn будет внимательно следить какие файлы вы открывали, сколько времени вы проводили над их правкой, какими функциями Eclipse пользовались. И затем на основе накопленной статистики начинает просто напросто часто используемые в данной задаче файлы подсвечивать более ярким и жирным цветом в списке файлов, затемняя неиспользуемые. Вроде даже некоторые элементы интерфейса также скрывает/выделяет, не замечал.  Это и есть основная фича. Кажется очень просто, но на самом деле крайне эффективна т.к. позволяет сконцентрироваться непосредственно над текущей задачей.</p>
<p>Вторая фича &#8212; то что задания можно создавать не только непосредственно в Eclipse, можно загружать тикеты напрямую используя вашу систему управления задачами. Мало того, Mylyn позволяет оперировать тикетами в системе управления задачами непосредственно из Eclipse: создавать тикеты, редактировать опции (%выполнения, оцененное время, статус), добавлять комментарии. К тому же он умеет считать затраченное на выполнение задачи время! Для этого используются специальные адаптеры (коннекторы) mylyn для различных систем управления задачами, т.н. &#171;﻿﻿Task Repository Connectors&#187;, которые взаимодействуют с системой через REST или какое то другое API либо вообще парся веб-страничку тикета. Существуют множество <a href="http://wiki.eclipse.org/index.php/Mylyn/Extensions#Task_Repository_Connectors">коннекторов для распространенных систем</a>, таких как Bugzilla, Jira, Mantiss, Trac и многих других. Причем некоторые из них можно установить непосредственно из интерфейса Eclipse, для чего нужно открыть Window &gt; Show view &gt; Task list , в появившемся блоке списков задач кликнуть по иконке New task &gt; add repository&#8230;  &gt; Install more connectors. К сожалению, в этом списке отсутствует коннектор для Redmine, поэтому придется повозиться дополнительно.</p>
<h2>Подключение Eclipse mylyn к redmine</h2>
<p>Для редмайн так же существует mylyn конектор, его <a title="redmin-mylyncon" href="http://sourceforge.net/projects/redmin-mylyncon/">проект расположен на SourceForge </a>. Помимо установки самого коннектора необходимо установить плагин для редмайн. На сайте проекта есть <a title="установка redmine mylyn коннектора" href="http://sourceforge.net/apps/mediawiki/redmin-mylyncon/index.php?title=Installation">подробная инструкция по установке</a>, я могу далее просто описать свой опыт.</p>
<h4>Установка плагина redmine</h4>
<p>Довольно простая. Для этого на серверепереходим в директорию с установленным redmine и выполняем</p>
<pre class="brush: bash; title: ; notranslate">ruby script/plugin install -x http://redmin-mylyncon.svn.sourceforge.net/svnroot/redmin-mylyncon/redmine_mylyn_connector/tags/CURRENT/redmine_mylyn_connector</pre>
<p>В общем то все, переходим по адресу /admin/plugins вашего редмайна и видим &#171;Mylyn Connector plugin&#187; &#8212; значит все прошло хорошо. Если нет &#8212; попробуйте перезапустить Redmine.</p>
<p>UPD 2011.06.03: Помимо установки плагина, нужно включить Redmine <a title="Как включить REST API Redmine" href="http://www.redmine.org/projects/redmine/wiki/Rest_api#Authentication">REST API</a>. Для этого нужно перейти в ﻿<em>Administration -&gt; Settings -&gt; Authentication </em>и поставить галку на <em>Enable REST API.</em></p>
<p>Для обновления плагина можно воспользоваться командой</p>
<pre class="brush: bash; title: ; notranslate">ruby script/plugin update</pre>
<h4>﻿﻿Установка Eclipse mylyn конектора Redmine</h4>
<p>Для начала нужно подключить Update site для плагина. Адрес<em> http://redmin-mylyncon.sourceforge.net/update-site/N/</em> о том как устанавливать дополнения в Eclipse я уже писал в <a title="установка плагинов в eclipse" href="http://seriyps.ru/blog/2009/07/06/izuchayu-python/">этой статье</a>. Если вкратце &#8212; открываем<em> <span style="font-style: normal;">Help &gt; Install New Software &gt; Add </span></em>в окошке в поле <strong>Name</strong> вводим что то вроде &#171;Redmine mylyn connector&#187;, в поле <strong>Location</strong> &#187; <em>http://redmin-mylyncon.sourceforge.net/update-site/N/</em>&#187; и жмем ok. Далее после загрузка списка плагинов отмечаем галочкой &#171;Mylyn Connector: Redmine&#187;, щелкаем Next-ы, рестартуем eclipse&#8230; Мы уже у финишной черты!</p>
<h4>Подключение redmine проектов к mylyn</h4>
<p>Теперь мы можем загрузить тикеты из существующего redmine проекта в mylyn и затем обновлять/редактировать их прямо из eclipse. Для этого в табе <strong>&#171;Task list&#187;</strong> (Window &gt; Show view &gt; Task list если уже забыли) щелкаем по иконке New task &gt; add repository&#8230;</p>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2010/07/redmine-mylynconn.png"><img class="alignnone size-thumbnail wp-image-560" title="redmine-mylynconn" src="http://seriyps.ru/blog/wp-content/uploads/2010/07/redmine-mylynconn-150x150.png" alt="добавление redmine репозитория тикетов к mylyn" width="150" height="150" /></a></p>
<p>В этом окошке выбираем появившийся теперь &#171;Redmine&#187;, жмем <strong>Next</strong>. В следующем окне вводим параметры подключения к веб-серверу Redmine (&#171;репозиторий тикетов&#187; в терминах mylyn).</p>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2010/07/redmine-mylynconn2.png"><img class="alignnone size-thumbnail wp-image-561" title="redmine-mylynconn2" src="http://seriyps.ru/blog/wp-content/uploads/2010/07/redmine-mylynconn2-150x150.png" alt="Настройка подключения mylyn к веб-серверу redmine" width="150" height="150" /></a></p>
<p>Здесь в поле <strong>Server</strong> вводим адрес, на котором у вас живет redmine, например &#171;http://redmine.example.com/&#187;; поле <strong>Label</strong> &#8212; понятное для вас название этого репозитория (будет показываться в списке доступных репозиториев); <strong>User id</strong> и <strong>Password</strong> соответственно ваши логин и пароль от учетки в redmine. Остальные опции можно оставить по умолчаню.</p>
<p>Жмем <strong>Finish</strong> и попадаем на страницу создания запроса на получение тикетов. По сути эта страница соответствует таковой по адресу &#171;http://redmine.example.com/projects&#187; с фильтрами со страницы &#171;﻿http://redmine.example.com/projects/myproject/issues&#187; &#8212; какие задачи загружать с сервера а какие нет.</p>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2010/07/redmine-mylynconn3.png"><img class="alignnone size-thumbnail wp-image-562" title="redmine-mylynconn3" src="http://seriyps.ru/blog/wp-content/uploads/2010/07/redmine-mylynconn3-150x150.png" alt="Выбор тикетов с фильтрами" width="150" height="150" /></a></p>
<p>Выбираем в выпадающем списке <strong>&#171;Select a project or create a Cross-Project-Query&#187;</strong> какой-либо из проектов вашего redmine (либо оставляем как есть &#8212; тогда подгрузятся тикеты для всех проектов). В поле <strong>Query title</strong> вводим что-то осмысленное, например название проекта. Проверяем фильтры (например можно попросить загружать только тикеты назначенные мне или только открытые тикеты) и жмем Finish</p>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2010/07/redmine-mylynconn4.png"><img class="alignnone size-thumbnail wp-image-563" title="redmine-mylynconn4" src="http://seriyps.ru/blog/wp-content/uploads/2010/07/redmine-mylynconn4-150x150.png" alt="Список загруженных из redmine тикетов в mylyn" width="150" height="150" /></a></p>
<p>Тадам! Думаю не стоит уточнять, что таким образом можно делать несколько запросов к одному репозиторию тикетов.</p>
<p>Теперь щелкаем по любому тикету в списке и попадаем на такую страничку</p>
<p><a href="http://seriyps.ru/blog/wp-content/uploads/2010/07/redmine-mylynconn5.png"><img class="alignnone size-thumbnail wp-image-564" title="redmine-mylynconn5" src="http://seriyps.ru/blog/wp-content/uploads/2010/07/redmine-mylynconn5-150x150.png" alt="Окно редактирования параметров тикета mylyn" width="150" height="150" /></a></p>
<p>Как видите, здесь мы можем редактировать любые свойства тикета так же, как если бы мы делали это напрямую через веб-интерфейс редмайна. Дизайн может показаться странным, но со временем привыкаешь.Чтобы сделать задание активным, нужно кликнуть по черному кружочку (на скриншоте обвел красным) и сразу начнется сбор статистики. Все просто!</p>
<p>Удачных экспериментов!</p>
<h2>Почитать</h2>
<p><a href="http://www.eclipse.org/mylyn/">Сайт mylyn</a><br />
<a href="http://en.wikipedia.org/wiki/Mylyn">Статья в wikipedia</a><br />
<a href="http://habrahabr.ru/blogs/eclipse/72632/">Преимущества mylyn в статье на хабре</a><br />
<a href="http://sourceforge.net/projects/redmin-mylyncon/">Сайт redmine &#8212; mylyn коннектора</a> (есть <a href="http://sourceforge.net/apps/mediawiki/redmin-mylyncon/index.php?title=Main_Page">wiki</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2010/07/22/integraciya-redmine-i-eclipse/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Basic HTTP авторизация для Nginx</title>
		<link>http://seriyps.ru/blog/2010/05/30/basic-http-avtorizaciya-dlya-nginx/</link>
		<comments>http://seriyps.ru/blog/2010/05/30/basic-http-avtorizaciya-dlya-nginx/#comments</comments>
		<pubDate>Sun, 30 May 2010 18:23:25 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[linux на сервере]]></category>
		<category><![CDATA[authorization]]></category>
		<category><![CDATA[crypt]]></category>
		<category><![CDATA[htpasswd]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[виртуалхост]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=511</guid>
		<description><![CDATA[В принципе это тривиальная операция описанная в документации к Nginx, но немного усложняет этот процесс необходимость создавать htpasswd файл, причем в самом Nginx средств для его создания нет (и это правильно), но предлагается создавать его используя утилиту htpasswd  входящую в состав Apache. Что самое смешное, на многих серверах, где используется Nginx, апача нет и не [...]]]></description>
			<content:encoded><![CDATA[<p>В принципе это тривиальная операция <a href="http://sysoev.ru/nginx/docs/http/ngx_http_auth_basic_module.html" target="_blank">описанная в документации к Nginx</a>, но немного усложняет этот процесс необходимость создавать htpasswd файл, причем в самом Nginx средств для его создания нет (и это правильно), но предлагается создавать его используя утилиту htpasswd  входящую в состав Apache. <span style="color: #808080;">Что самое смешное, на многих серверах, где используется Nginx, апача нет и не ожидается. Более того, большинство администраторов хостингов, &#171;познавших&#187; для себя Nginx начинают нескрываемо недолюбливать апач и верят, что наступит тот час, когда для Nginx наконец сделают аналог htaccess и апач, исправно служивший им долгие годы, наконец-то сгинет в небытие.</span> Чтобы исправить сей досадный факт, добавлю в статью онлайн-формочку для генерации htpasswd фйла.<br />
<span id="more-511"></span><br />
Давайте для примера создадим отдельный поддомен для хранения секретной информации с доступом по логину/паролю и в нагрузку в ней  будут директория для доступа к которой понадобится дополнительная пара логин/пароль и директория с включенным листингом файлов тоже с отдельным доступом. Т.е. структура примерно такая:<br />
/ (доступ к файлам по _логин-пароль_1)<br />
&#8212;otherpass/ (доступ к файлам по _логин-пароль_2)<br />
&#8212;listed/ (включен автоиндекс файлов, т.е. можнго просмотреть какие файлы тут лежат, доступ к файлам по _логин-пароль_3)</p>
<h2>Создадим виртуалхост Nginx</h2>
<p>Допустим, для поддомена adminka.example.com. Для этого создадим файл</p>
<pre class="brush: bash; title: ; notranslate">sudo nano /etc/nginx/sites-available/adminka.example.com</pre>
<p>со следующим содержимым:</p>
<pre>server {
	listen   80;
	server_name  adminka.example.com;
	access_log  /var/log/nginx/adminka_example_com.log;#можно написать /var/log/nginx/$host.log но придется заранее создать лог-файл и выставить на него правильные права
	root   /var/www/$host/htdocs;
	index  index.html index.htm index.php;
}</pre>
<p>Ок, сохраняем, делаем этот хост доступным (включаем в конфиг нджинкса):</p>
<pre class="brush: bash; title: ; notranslate">sudo ln -s /etc/nginx/sites-available/adminka.example.com /etc/nginx/sites-enabled/adminka.example.com</pre>
<p>Создаем директории для htdocs</p>
<pre class="brush: bash; title: ; notranslate">mkdir /var/www/{adminka.example.com,adminka.example.com/htdocs,adminka.example.com/htdocs/{otherpass,listed}</pre>
<p>Если кто не понял, эта команда делает то же, что и 4 следующие:</p>
<pre class="brush: bash; title: ; notranslate">mkdir /var/www/adminka.example.com
mkdir /var/www/adminka.example.com/htdocs
mkdir /var/www/adminka.example.com/htdocs/otherpass
mkdir /var/www/adminka.example.com/htdocs/listed</pre>
<p>Рестартим Nginx</p>
<pre class="brush: bash; title: ; notranslate">sudo service nginx configtest
sudo service nginx restart</pre>
<p>Проверяем: <a href="http://adminka.example.com/">http://adminka.example.com/</a><br />
Ага</p>
<blockquote><p>403 Forbidden<br />
nginx/0.7.64</p></blockquote>
<p>Пароли не просит, листинг директории у нас не включен и index файла мы не создавали. То же самое для директорий  otherpass и listed. Соответственно получаем 403 ошибку &#171;доступ запрещен&#187;.</p>
<h2>Добавим листинг (если нужен)</h2>
<p>Мы договорились, что в директории listed у нас разрешен просмотр содержимого директории&#8230; Редактируем конфиг</p>
<pre class="brush: bash; title: ; notranslate">sudo nano /etc/nginx/sites-available/adminka.example.com</pre>
<pre>server {
<span style="color: #808080;">	listen   80;
	server_name  adminka.example.com;
	access_log  /var/log/nginx/adminka_example_com.log;
	root   /var/www/$host/htdocs;
	index  index.html index.htm index.php;</span>
	location /listed/ {
		autoindex on;
	}
}</pre>
<p>Сохраняем, перезапускаем, пробуем: <a href="http://adminka.example.com/">http://adminka.example.com/listed/</a><br />
Ага, работает:</p>
<blockquote><p>Index of /listed/<br />
_________<br />
../<br />
_________</p></blockquote>
<p>Но где же обещанные пароли? Спокойно, сейчас все будет!</p>
<h2>Добавляем Basic HTTP authorization.</h2>
<p>Пароли для разных директорий будем хранить в разных htpasswd файлах за пределами htdocs. Например так:</p>
<pre>/var/www/adminka.example.com/
--/root_htpasswd
--/listed_htpasswd
--/otherpass_htpasswd</pre>
<pre>server {
<span style="color: #808080;">	listen   80;
	server_name  adminka.example.com;
	access_log  /var/log/nginx/adminka_example_com.log;
	root   /var/www/$host/htdocs;
	index  index.html index.htm index.php;</span>
	location / {
		auth_basic "Unauthorized"; # текст сообщения сервера с предложением ввести пароль
		auth_basic_user_file /var/www/$host/root_htpasswd; # путь к htpasswd файлу
	}
	location /listed/ {
		auth_basic "Unauthorized";
		auth_basic_user_file /var/www/$host/listed_htpasswd;
		autoindex on;
	}
	location /otherpass/ {
		auth_basic "Unauthorized";
		auth_basic_user_file /var/www/$host/otherpass_htpasswd;
		autoindex on;
	}
}</pre>
<p>Создаем htpasswd файлы (см. далее), сохраняем, перезапускаем, проверяем!</p>
<h2>Генерация хеша пароля</h2>
<p>HTTP авторизация в Nginx работает так же как и в Apache, т.е. с использованием htpasswd файла, но с тем лишь ограничением, что для шифрования пароля можно использовать только стандартный алгоритм DES с двухсимвольной солью. В Linux для этого используется C-функция crypt() (см <code>man 3 crypt</code>).</p>
<p>Можно использовать утилиту htpasswd из комплекта поставки Apache</p>
<pre class="brush: bash; title: ; notranslate">htpasswd -nd seriy
New password:
Re-type new password:</pre>
<pre>seriy:4lQ0JcanrGr9E</pre>
<p>Вывод этой утилиты состоит из 3-х частей: первая, до двоеточия &#171;seriy&#187; &#8212; это имя пользователя, &#171;4l&#187; &#8212; это двухсимвольная соль для функции crypt() и остальная часть &#171;Q0JcanrGr9E&#187; &#8212; это сам хеш пароля. Единственная проблема такого подхода &#8212; придется устанавливать apache.</p>
<p>Вот пара примеров кода для генерации htpasswd (<strong>your_password</strong> &#8212; ваш пароль, <strong>salt</strong> &#8212; соль для пароля, должна содержать 2(!!!) символа из набора &#171;./0-9A-Za-z&#187;):<br />
используя php:</p>
<pre class="brush: bash; title: ; notranslate">php -r 'echo crypt(&quot;your_password&quot;, &quot;salt&quot;);'</pre>
<p>используя Python:</p>
<pre class="brush: bash; title: ; notranslate">python -c 'import crypt; print crypt.crypt(&quot;your_password&quot;, &quot;salt&quot;)'</pre>
<p>Если кто предложит примеры на других языках &#8212; (perl, ruby) буду благодарен. Возможно для этого можно использовать утилиту mcrypt но я в ней не смог разобраться.</p>
<p>В завершение &#8212; вот <a href="http://seriyps.ru/crypt/htpasswd/">простенькая веб-формочка для генерации htpasswd</a> онлайн.</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2010/05/30/basic-http-avtorizaciya-dlya-nginx/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Настраиваем девелоперский DNS сервер</title>
		<link>http://seriyps.ru/blog/2010/05/06/nastraivaem-developerskij-dns-server/</link>
		<comments>http://seriyps.ru/blog/2010/05/06/nastraivaem-developerskij-dns-server/#comments</comments>
		<pubDate>Thu, 06 May 2010 07:12:41 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[linux на сервере]]></category>
		<category><![CDATA[bind]]></category>
		<category><![CDATA[bind9]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[named]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[домен]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=513</guid>
		<description><![CDATA[Рассмотрим эволюцию организации работы веб-разработчика с несколькими проектами на разных адресах и поможем поскорее перескочить через первые ступеньки! Все на localhost Когда ты в одиночку разрабатываешь один единственный веб-сервис или сетевое приложение, то, как правило, вполне хватает локального домена localhost. Но что происходит, когда появляется необходимость разрабатывать и поддерживать одновременно два или более совершенно разных [...]]]></description>
			<content:encoded><![CDATA[<p>Рассмотрим эволюцию организации работы веб-разработчика с несколькими проектами на разных адресах и поможем поскорее перескочить через первые ступеньки!</p>
<h2>Все на localhost</h2>
<p>Когда ты в одиночку разрабатываешь один единственный веб-сервис или сетевое приложение, то, как правило, вполне хватает локального домена <em>localhost</em>. Но что происходит, когда появляется необходимость разрабатывать и поддерживать одновременно два или более совершенно разных приложения? Сперва ты пытаешься рассовывать разные приложения по подпапкам одного домена вроде <em>http://localhost/app1/ http://localhost/app2/</em> и т.д. Ок, при более-менее простых приложениях такой вариант еще может работать. Но когда возникает необходимость в привязке приложения к корню сайта в относительных внутренних ссылках, когда необходимы специфические настройки веб-сервера (например специфические реврайт-правила), то сложность и запутанность полученной системы крайне резко возрастает, начинают появляться различные баги и замедляется процесс разработки.</p>
<h2>Файл hosts</h2>
<p>Позже, изрядно помучавшись с однодоменным расположением проектов, вдруг узнаешь про существование волшебного файлика hosts (<em>/etc/hosts</em>) с помошью которого можно создавать для себя дополнительные &#171;локалхосты&#187;, т.е. получаем возможность любое конкретное доменное имя направить на любой конкретный IP адрес. Отлично! Теперь можно разнести все свои &#171;локалхосты&#187; по отдельным &#171;поддоменам&#187; типа <em>app1.loc app2.loc</em> просто прописав в <em>/etc/hosts</em> (<em>WINDOWS\system32\drivers\etc\hosts</em> для виндов) всего пару строк<br />
127.0.0.1 app1.loc<br />
127.0.0.1 app2.loc<br />
Выглядит просто и понятно, все записи под рукой, можно легко добавить и удалить нужный домен, изменения, как правило, вступают в силу мгновенно. В принципе этим можно ограничиться если у тебя не так много проектов, меняются они нечасто и ты работаешь над ними неторопясь и ОДИН. Но есть у такого подхода 2 существенных недостатка:</p>
<ol>
<li>Для того чтобы к имени <em>app1.loc</em> добавить поддомен, например <em>static.app1.loc</em> допустим, для хранения статических файлов, приходится создавать в файле hosts дополнительную запись типа <em>127.0.0.1&nbsp;static.app2.loc</em> т.к. hosts файл не поддерживает wildcard формы записи &#8212; прописать в нем <em>127.0.0.1&nbsp;*.app1.loc</em> нельзя!<br />
Такую ситуацию еще можно терпеть если у вас действительно нужно добавить всего 1-2 поддомена, но что, если ваше приложение предоставляет своим пользователям отдельные поддомены? http://user.app1.loc, http://pi_es.seriyps.ru/, http://seriyps.habrahabr.ru/ ? Отладка такого проекта с использованием файла hosts становится практически невыполнимой задачей. Опять же при росте количества проектов файл hosts забивается мусором и в нем становится трудно что-то найти.</li>
<li>Если вы разрабатываете ваше приложение не в одиночку а целым офисом, в котором стоит девелоперский веб-сервер, то для того чтобы дать коллеге ссылку на домен из вашего файла hosts вам как минимум нужно будет убедиться что этот адрес есть и в его файле hosts. Согласитесь, это даже звучит смешно!</li>
</ol>
<h2>Свой девелоперский DNS сервер</h2>
<p>Ну вот мы и добрались до самого праведного способа организации  разработки интернет-приложения для доменов &#8212; это использование своего  DNS сервера. Имеется в виду конечно не &#171;каждому девелоперу &#8212; по DNS серверу&#187; а установка централизованного DNS сервера для офиса. Хотя даже для единоличной разработки свой DNS все равно удобнее hosts файла хотя бы из за наличия wildcards. Собственно преимущества такого подхода очевидны:</p>
<ol>
<li>Проект разрабатывается в той среде, в которой он будет использоваться в продакшене. Никаких посторонних файлов и настроек веб-сервера как в случае с расположением проектов в поддиректориях localhost</li>
<li>Настоящие доменные ЗОНЫ со всеми типами записей в т.ч. и wildcard&#8230; @, *, MX, CNAME и пр.</li>
<li>Все пользователи, прописавшие себе этот DNS (а если он включается автоматом по DHCP то все еще больше упрощается) смогут открывать ваши ссылки не задумываясь &#171;a прописал-ли я ее себе в hosts файл..&#187;</li>
</ol>
<h2>Устанавливаем и настраиваем DNS сервер.</h2>
<p>Вступление у меня получилось длинным а само описание настройки выглядит куда скромнее, и это весьма символично.. Ведь, как оказалось, настроить простой DNS сервер с одной девелоперской зоной можно за 5 минут а откладывать на потом это можно бесконечно долго. Давайте наконец приступим!</p>
<h3>Настройка простейшей dev зоны для DNS сервера BIND9 (named) на Ubuntu/Debian</h3>
<p>Т.к. мы настраиваем DNS для небольшой сети &#171;для своих&#187;, можно пренебречь некоторыми мерами безопасности. Например, мы не будем запускать bind в chroot окружении и не будем ограничивать подключение к ним с различных IP. К тому же для named уде при установке создаются вполне приемлемые правила для apparmor.<br />
Для начала установим сам bind</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get install bind9</pre>
<p>В Ubuntu/Debian конфигурационные файлы Bind хранятся в директории <em>/etc/bind</em>, файлы, создаваемые при работе Bind хранятся в <em>/var/cache/bind</em> , главный конфигурационный файл bind находится по адресу <em>/etc/bind/named.conf</em> . В принципе, все опции можно вносить в него, но рекомендуется использовать для этого подключаемые файлы: <em>named.conf.options</em> &#8212; для настроек сервера и <em>named.conf.local</em> &#8212; для добавления зон. Таким образом нас интересуют именно эти файлы. Кстати, их синтаксис похож на C код, поэтому даже можно использовать подсветку синтаксиса C. Приступим:<br />
Открываем файл <em>/etc/bind/named.conf.options</em> и приводим его содержимое к виду</p>
<pre class="brush: cpp; title: ; notranslate">options {
        directory       &quot;/var/named&quot;;
	//раскомментировать строчки ниже, если хотим кешировать ответы DNS провайдера.. может немного &quot;ускорить интернет&quot;
	// forwarders {
	// 	192.0.2.1; IP адреса DNS провайдера из &quot;cat /etc/resolv.conf&quot; при подключенном интернете
	// 	192.0.2.2;
	// };
};
</pre>
<p><strong>directory</strong> &#8212; указывает на директорию, в которой хранятся файлы сервера, такие как кеш, в <strong>forvarders</strong> можно добавить адреса DNS серверов вашего провайдера для кеширования их ответов и таким образом несколько сократить сетевые издержки на DNS запросы. Существует еще куча опций, но в нашем простейшем сервере они не нужны.<br />
Прекрасно, общие настройки сделаны. Уже сейчас можно использовать наш сервер в качестве кеширующего DNS. Но нас интересует возможность создания и администрирования собственной зоны!<br />
Открываем <em>/etc/bind/named.conf.local</em> и пишем в него</p>
<pre class="brush: cpp; title: ; notranslate">zone &quot;dev&quot; {
	type master;
	file &quot;/etc/bind/db.dev&quot;;

};</pre>
<p><strong>type master</strong> означает что мы являемся единственным авторитетным источником информации о зоне dev, <strong>file</strong> указывает на расположение файла с информацией о зоне. Остается только создать этот файл<br />
<em>/etc/bind/db.dev</em></p>
<pre>@ IN SOA dev. root.dev.    ( ; dev. - имя зоны, root.dev. - e-mail администратора зоны, в котором @ заменено на . т.е. это было root@dev но лучше вставить настоящий e-mail
        20100506        ; Серийный номер зоны. Обычно - текущая дата
        3h              ; обновление каждые 3 часа
        1h              ; повтор каждый час
        1w              ; информация хранится 1 неделю
        1d    )         ; TTL записи - 1 день

@   IN    NS    dev.        ; сервер имен. Рекомендую оставить как тут
@   IN    A  198.51.100.1       ; A - запись - IP адрес сервера для данной зоны (ваш девелоперский сервер). @ для имени домена означает "корень зоны"
*   IN    CNAME  @              ; CNAME запись. По сути - символическая ссылка. * для имени домена означает "любой поддомен".
                                  ; Т.е. при обращении на любой поддомен в зоне dev будет возвращаться IP 198.51.100.1
database IN A 198.51.100.2      ; Но поддомен database.dev будет расположен на другом IP адресе
</pre>
<p>Не забывайте ставить завершающие точки в имени домена!<br />
Сохраняем, заставляем bind перечитать конфигурацию</p>
<pre class="brush: bash; title: ; notranslate">sudo service bind9 reload</pre>
<p>проверяем</p>
<pre class="brush: bash; title: ; notranslate">nslookup any.dev</pre>
<pre>Server:		127.0.0.1
Address:	127.0.0.1#53

any.dev	canonical name = dev.
Name:	dev
Address: 198.51.100.1</pre>
<pre class="brush: bash; title: ; notranslate">nslookup database.dev</pre>
<pre>Server:		127.0.0.1
Address:	127.0.0.1#53

Name:	database.dev
Address: 198.51.100.2</pre>
<p>В случае возникновения каких-то проблем смотрим syslog &#8212; как правило bind сообщает об ошибках именно туда.<br />
Понятно что таким-же образом можно создавать или переопределять любые другие зоны &#8212; добавляется блок zone в <em>named.conf.local</em> и создается соответствующий файл с информацией зоны.</p>
<h2>Использование DNS сервера</h2>
<p>Сервер есть, осталось его подключить!</p>
<h3>Ubuntu</h3>
<p>Если вы не пользуетесь NetworkManager-ом, то достаточно <strong>в самое начало</strong> файла <em>/etc/resolv.conf</em> прописать ваш DNS сервер.<br />
Если NetworkManager используется, открываем &#171;Изменить соединения&#187;, выбираем нужное соединение (проводное, VPN, etc), открываем вкладку &#171;Параметры IPv4&#8243; и заменяем &#171;Автоматически (DHCP)&#187; на &#171;Автоматически (DHCP, только адрес)&#187;, затем в поле &#171;Серверы DNS&#187; вписываем первым IP вашего DNS сервера и дальше через запятую ip адреса из <em>/etc/resolv.conf</em><br />
Переподключаем сеть.</p>
<h3>Windows</h3>
<p>В свойствах соединения в настройках TCP/IP прописываем первым наш DNS и после DNS провайдера.</p>
<p>Удачных экспериментов!<br />
Почитать:<br />
<a href="http://www.isc.org/software/bind">Официальный сайт bind</a><br />
<a href="http://www.opennet.ru/base/net/bind_cache_dns.txt.html">Кеширующий DNS сервер для локальной сети на основе BIND 9</a><br />
<a href="http://unix-notes.ru/2009/09/14/ustanovka-bind-named-na-centos/">Установка Bind (named) на CentOS</a><br />
<a href="http://sudouser.com/ustanovka-i-nastrojka-dns-servera-bind9-ubuntu-debian-howto.html">Установка и настройка DNS сервера bind9 Ubuntu-Debian HOWTO</a></p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2010/05/06/nastraivaem-developerskij-dns-server/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Замена для ifconfig, route, arp, etc.: утилиты iproute2</title>
		<link>http://seriyps.ru/blog/2010/02/02/zamena-dlya-ifconfig-route-arp-etc-utility-iproute2/</link>
		<comments>http://seriyps.ru/blog/2010/02/02/zamena-dlya-ifconfig-route-arp-etc-utility-iproute2/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 09:48:33 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[linux на сервере]]></category>
		<category><![CDATA[Общекомпьютерное]]></category>
		<category><![CDATA[ifconfig]]></category>
		<category><![CDATA[iproute2]]></category>
		<category><![CDATA[route]]></category>
		<category><![CDATA[сеть]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=496</guid>
		<description><![CDATA[Вот недавно познакомился с этим набором утилит&#8230; Этот пакет утилит представляет из себя замену таким заслужившим почет и уважение утилитам, как route, ifconfig, arp, netstat (т.н. ﻿﻿net-tools). ﻿Особенно хочу в нем отметить структуру ввода команд &#8212; похоже на работу с GIT, но еще гибче &#8212; можно вместо названия команды ввести любое количество первых букв и, [...]]]></description>
			<content:encoded><![CDATA[<p>Вот недавно познакомился с этим набором утилит&#8230;</p>
<p>Этот пакет утилит представляет из себя замену таким заслужившим почет и уважение утилитам, как route, ifconfig, arp, netstat (т.н. ﻿﻿net-tools).</p>
<p>﻿Особенно хочу в нем отметить структуру ввода команд &#8212; похоже на работу с GIT, но еще гибче &#8212; можно вместо названия команды ввести любое количество первых букв и, если не возникнет конфликтов, команда отработает как положено. Ну это так, лирическое отступление.</p>
<p>Вообще-же, если по честному, то есть мнение, что ﻿﻿net-tools утилиты сейчас фактически существуют только для обратной совместимости. Плюс к этому, они не всегда корректно показывают и обрабатывают интерфейсы, настроенные утилитами более нового iproute2.</p>
<p>В то-же время iproute2 мало того, что полностью покрывают функционал net-tools утилит, но и поддерживают значительное количество новых возможностей сетевой подсистемы Linux!</p>
<p>Пара примеров под катом..</p>
<p><span id="more-496"></span><br />
получим список сетевых адресов нашей системы<br />
<code>ip addr</code><br />
(вывод будет немного похож на вывод ifconfig)<br />
Получим таблицу маршрутов<br />
<code>ip route</code><br />
(результат похож на route -n)<br />
добавим адрес 192.168.35.110/24 на сетевой интерфейс eth0<br />
<code>sudo ip addr add 192.168.35.110/24 dev eth0</code><br />
теперь наш компьютер будет принимать запросы сразу по двум IP адресам с одной сетевой карты! Т.е. у нас фактически теперь 2 IP адреса.<br />
Хочу отметить, что ifconfig, например, этого факта не заметит и будет по-прежнему показывать только один адрес для eth0. Хотя соединения по﻿ .35.110 будут прекрасно приниматься и обрабатываться. Так что снова используем ip addr [show]<br />
Удалим этот адрес<br />
<code>sudo ip addr del 192.168.35.110/24 dev eth0</code></p>
<p>Это только коротенький список примеров, довольно общирный мануал можно найти в переводе <a href="http://gazette.linux.ru.net/rus/articles/lartc/index.html" target="_blank">Linux Advanced Routing &amp; Traffic Control HOWTO</a></p>
<p>Как видите, &#171;интерфейс&#187; тут интуитивно понятный, крайне дружелюбный и выполненный в одном стиле (вот уж не думал, что скажу такое когда-нибудь о консольной программе). Новых полезных возможностей просто гора, так что если вы все еще кипя&#8230; используете ifconfig и route, не теряйте время напрасно! Начните изучать и применять на практике iproute2 сейчас! Не пожалеете.</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2010/02/02/zamena-dlya-ifconfig-route-arp-etc-utility-iproute2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Импорт GIT репозитория в пустой SVN</title>
		<link>http://seriyps.ru/blog/2010/01/15/import-git-repozitoriya-v-pustoj-svn/</link>
		<comments>http://seriyps.ru/blog/2010/01/15/import-git-repozitoriya-v-pustoj-svn/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 09:41:10 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[git-svn]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=466</guid>
		<description><![CDATA[В статье кратко описано как импортировать существующий GIT репозиторий в чистенький SVN со всей историей коммитов и пр. Первый вопрос, который напрашивается &#8212; ЗАЧЕМ? Отвечаю &#8212; просто проект разрабатывался в моем локальном репозитории, а после заказчик попросил разместить его в SVN. Можно, конечно, сделать это все одним большим Initial коммитом, но хочется чтоб история тоже [...]]]></description>
			<content:encoded><![CDATA[<p>В статье кратко описано как импортировать существующий GIT репозиторий в чистенький SVN со всей историей коммитов и пр.</p>
<p>Первый вопрос, который напрашивается &#8212; ЗАЧЕМ?</p>
<p>Отвечаю &#8212; просто проект разрабатывался в моем локальном репозитории, а после заказчик попросил разместить его в SVN. Можно, конечно, сделать это все одним большим Initial коммитом, но хочется чтоб история тоже импортировалась. <span id="more-466"></span>Так вот, допустим имеется SVN репозиторий https://svn.example.com/repos/someproject/ со стандартной иерархией</p>
<p>https://svn.example.com/repos/someproject/</p>
<p>&#8212;-/trunk<br />
&#8212;-/tags<br />
&#8212;-/branches</p>
<p>и локальный git репозиторий ~/workspace/someproject/ в котором находятся папочки</p>
<p>~/workspace/someproject/<br />
&#8212;-/.git<br />
&#8212;-/lib<br />
&#8212;-/config<br />
&#8212;-/&#8230;..</p>
<p>И мы хотим в SVN получить структуру</p>
<p>https://svn.example.com/repos/someproject/<strong>trunk/</strong></p>
<p>&#8212;-/lib<br />
&#8212;-/config<br />
&#8212;-/&#8230;..</p>
<p>Для работы с SVN из GIT устанавливаем пакет git-svn</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get install git-svn</pre>
<p>Если делать по стандартной инструкции</p>
<pre class="brush: bash; title: ; notranslate">cd ~/workspace/someproject/
git-svn clone https://svn.example.com/repos/someproject/trunk/ .
git svn rebase
git-svn dcommit</pre>
<p>То появляется ошибка</p>
<blockquote><p><strong>Use of uninitialized value in concatenation (.) or string at /usr/bin/git-svn line 411.<br />
Committing to  &#8230;</strong><br />
<strong> Unable to determine upstream SVN information from HEAD history</strong></p></blockquote>
<p>Для исправления положения, после этой попытки, делаем следующее:<br />
Убеждаемся, что версия GIT не ниже, чем 1.6.3</p>
<pre class="brush: bash; title: ; notranslate">git --version</pre>
<p>Если так, то командуем
<pre class="brush: bash; title: ; notranslate">git branch -a</pre>
<p> который должен вывести что-то наподобие</p>
<blockquote><p>* master<br />
  <strong>remotes/git-svn</strong></p></blockquote>
<p>Обратим внимание на строку remotes/git-svn (может отличаться)</p>
<p>Командуем:</p>
<pre class="brush: bash; title: ; notranslate">git rebase --onto &lt;strong&gt;remotes/git-svn&lt;/strong&gt; --root master</pre>
<p>И вуаля:</p>
<pre class="brush: bash; title: ; notranslate">git-svn dcommit</pre>
<p>работает!! Коммиты пошли отправляться в SVN.</p>
<p>Если теперь выполнить</p>
<pre class="brush: bash; title: ; notranslate">git log</pre>
<p> То в каждом коммите будет дополнительно строка типа git-svn-id: https://svn.example.com/repos/someproject/trunk@49 78ca4877-544d-4e5c-8d06-6abf935*****</p>
<p>Еще раз, все команды по-порядку:</p>
<pre class="brush: bash; title: ; notranslate">cd ~/workspace/someproject/ #переходим в папку проекта (в которой находится папка .git)
git-svn clone https://svn.example.com/repos/someproject/trunk/ . #&quot;копируем&quot; SVN репозиторий (на сам. деле при этом соответствующим образом конфигурируется GIT
git branch -a #смотрим название ветки remotes/blablabla
git rebase --onto remotes/git-svn --root master # remotes/git-svn берем из предыдущей команды
git-svn dcommit # копируем GIT репозиторий в SVN со всей историей коммитов и пр.
</pre>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2010/01/15/import-git-repozitoriya-v-pustoj-svn/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Учим Redmine рассылать почту через Gmail</title>
		<link>http://seriyps.ru/blog/2010/01/15/uchim-redmine-rassylat-pochtu-cherez-gmail/</link>
		<comments>http://seriyps.ru/blog/2010/01/15/uchim-redmine-rassylat-pochtu-cherez-gmail/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 03:19:47 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[redmine]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[smtp]]></category>
		<category><![CDATA[tls]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=479</guid>
		<description><![CDATA[Проблема в том, что если настроить уведомления по email через smtp стандартным методом: # File: config/email.yml production: delivery_method: :smtp smtp_settings: address: "smtp.gmail.com" port: '587' domain: "smtp.gmail.com" authentication: :plain user_name: "your_email@gmail.com" password: "your_password" То при попытке отправить пробный email http://redmine.example.com/admin/test_email, он выдает ошибку Во время отправки письма произошла ошибка (530 5.7.0 Must issue a STARTTLS command [...]]]></description>
			<content:encoded><![CDATA[<p>Проблема в том, что если настроить уведомления по email через smtp стандартным методом:</p>
<pre># File: config/email.yml
production:
  delivery_method: :smtp
  smtp_settings:
    address: "smtp.gmail.com"
    port: '587'
    domain: "smtp.gmail.com"
    authentication: :plain
    user_name: "your_email@gmail.com"
    password: "your_password"</pre>
<p>То при попытке отправить пробный email http://redmine.example.com/admin/test_email, он выдает ошибку<br />
<code>Во время отправки письма произошла ошибка (530 5.7.0 Must issue a STARTTLS command first. 16sm1075274ewy.14 )</code><br />
Причиной тому служит обязательное использование TLS шифрования при работе с почтовым сервером Gmail, которое Redmine из коробки не поддерживает.<br />
Добавить такой функционал несложно&#8230;<span id="more-479"></span><br />
Для начала установим плагин action_mailer_optional_tls<br />
Если у вас установлен GIT, то просто в папке с установленным redmine выполняете команду</p>
<pre class="brush: bash; title: ; notranslate">ruby script/plugin install git://github.com/collectiveidea/action_mailer_optional_tls.git</pre>
<p>Иначе переходите на сайт http://github.com/collectiveidea/action_mailer_optional_tls , щелкаете Download source и распаковываете архив в vendor/plugins/ (чтобы получилась папка vendor/plugins/action_mailer_optional_tls с файлами init.rb и т.п.)</p>
<p>Приводите конфиг к виду</p>
<pre># File: config/email.yml
production:
  delivery_method: :smtp
  smtp_settings:
    address: "smtp.gmail.com"
    port: '587'
    domain: "gmail.com"
    authentication: :plain
    user_name: "your_email@gmail.com"
    password: "your_password"
    <strong>tls: true</strong></pre>
<p>Или, если пользуетесь службой Google apps для вашего домена <strong>example.com</strong>, то</p>
<pre># File: config/email.yml
production:
  delivery_method: :smtp
  smtp_settings:
    address: "smtp.gmail.com"
    port: '587'
    domain: "<strong>example.com</strong>"
    authentication: :plain
    user_name: "your_email@<strong>example.com</strong>"
    password: "your_password"
    <strong>tls: true</strong></pre>
<p>Перезапускаете сервер, например так (смотря как вы настраивали):</p>
<pre class="brush: bash; title: ; notranslate">sudo service mongrel_cluster restart</pre>
<p>И пользуетесь!</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2010/01/15/uchim-redmine-rassylat-pochtu-cherez-gmail/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Установка Redmine на Ubuntu 9.10 под Nginx часть 2</title>
		<link>http://seriyps.ru/blog/2010/01/14/ustanovka-redmine-na-ubuntu-9-10-pod-nginx-chast-2/</link>
		<comments>http://seriyps.ru/blog/2010/01/14/ustanovka-redmine-na-ubuntu-9-10-pod-nginx-chast-2/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 02:10:00 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[linux на сервере]]></category>
		<category><![CDATA[WEB, Интернет]]></category>
		<category><![CDATA[Программирование]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=456</guid>
		<description><![CDATA[Продолжение статьи Установка Redmine на Ubuntu 9.10 под Nginx Настройка Ruby веб-сервера Mongrel Сам по себе Nginx работать с Redmine не может, т.к. fcgi для redmine фактически нет, поэтому для начала настроим mongrel, и будем проксировать на него запросы из Nginx. (На самом деле я не знаю, зачем нужно настраивать mongrel, когда есть встроенный сервер [...]]]></description>
			<content:encoded><![CDATA[<p>Продолжение статьи <a href="http://seriyps.ru/blog/2010/01/14/ustanovka-redmine-na-ubuntu-9-10-pod-nginx/">Установка Redmine на Ubuntu 9.10 под Nginx</a><span id="more-456"></span></p>
<h2>Настройка Ruby веб-сервера Mongrel</h2>
<p>Сам по себе Nginx работать с Redmine не может, т.к. fcgi для redmine фактически нет, поэтому для начала настроим mongrel, и будем проксировать на него запросы из Nginx. (На самом деле я не знаю, зачем нужно настраивать mongrel, когда есть встроенный сервер webrick, но везде пишут про mongrel, я решил &#171;не выделяться слишком&#187;)</p>
<p>Так вот, устанавливаемые с помощью gem исполняемые файлы устанавливаются в папку /var/lib/gems/1.8/bin/, которая не включена в стандартный PATH, соответственно просто вызывать их из командной строки не получится. Чтобы это исправить, есть несколько путей. Сперва предлагаю сделать</p>
<pre class="brush: bash; title: ; notranslate">export PATH=$PATH&quot;:/var/lib/gems/1.8/bin/&quot;</pre>
<p> &#8212; это добавит нужный путь в переменную PATH до окончания сессии. Уже сейчас можно запустить mongrel &#8212; находясь в домашней директории /home/redmine выполните</p>
<pre class="brush: bash; title: ; notranslate">mongrel_rails start –p 3000 -e production</pre>
<p>По адресу <a href="http://localhost:3000/">http://localhost:3000/</a> снова должен работать редмайн.</p>
<p>Если все ок &#8212; делаем доступными бинарники из /var/lib/gems/1.8/bin/ перманентно. Можно сделать их доступными для всех пользователей, сделав символические ссылки</p>
<pre class="brush: bash; title: ; notranslate">sudo ln -s /var/lib/gems/1.8/bin/mongrel_rails /usr/bin/mongrel_rails
sudo ln -s /var/lib/gems/1.8/bin/rails /usr/bin/rails
sudo ln -s /var/lib/gems/1.8/bin/mongrel_cluster_ctl /usr/bin/mongrel_cluster_ctl</pre>
<p>Можно добавить экспорт пути в PATH в файле /etc/profile</p>
<pre class="brush: bash; title: ; notranslate">echo 'export PATH=$PATH&quot;:/var/lib/gems/1.8/bin/&quot;' &amp;gt;&amp;gt; /etc/profile</pre>
<p>Но я бы посоветовал просто добавить экспорт этого пути в PATH только для юзера redmine. Находясь в его домашнем каталоге выполните</p>
<pre class="brush: bash; title: ; notranslate">echo 'export PATH=$PATH&quot;:/var/lib/gems/1.8/bin/&quot;' &amp;gt;&amp;gt; .bashrc</pre>
<p> И перелогиньтесь.</p>
<p>Теперь сгенерируем конфиг-файл для работы mongrel с redmine</p>
<pre class="brush: bash; title: ; notranslate">mongrel_rails cluster::configure -e production -p 3000 -a 127.0.0.1 -N 2 -P /var/run/mongrel_cluster/mongrel.pid -c /home/redmine --user redmine --group redmine</pre>
<p> Где <em>-e production</em> рабочее окружение Redmine, <em>-p 3000</em> порт, на который будет слушать Mongrel, <em>-a 127.0.0.1</em> IP адрес, на котором он будет принимать запросы, <em>-N 2</em> количество запущенных процессов Mongrel, <em>-P /var/run/mongrel_cluster/mongrel.pid</em> адрес для записи pid файла  <em>-c /home/redmine</em> домашняя директория, <em>&#8212;user redmine &#8212;group redmine</em> имя и группа пользователя, от имени которого будет работать mongrel (настоятельно рекомендую эти настройки не менять!! разве что изменить количество запущенных процессов &#8212; каждый процесс занимает отдельный порт, начиная с указанного в -p и дальше). Советую попробовать
<pre class="brush: bash; title: ; notranslate">mongrel_rails cluster::configure --help</pre>
<p>Для того, чтобы сервер запускался при перезапуске компьютера, сделаем следующее: создадим каталог /etc/mongrel_cluster и скопируем туда полученный конфиг</p>
<pre class="brush: bash; title: ; notranslate">sudo mkdir /etc/mongrel_cluster
sudo cp /home/redmine/config/mongrel_cluster.yml /etc/mongrel_cluster/redmine.yml</pre>
<p>Скопируем init.d файл для mongrel  в /etc/init.d</p>
<pre class="brush: bash; title: ; notranslate">sudo cp /var/lib/gems/1.8/gems/mongrel_cluster-1.0.5/resources/mongrel_cluster /etc/init.d/
sudo chmod +x /etc/init.d/mongrel_cluster</pre>
<p>И, на всякий случай, добавим в этот файл в начале (после комментариев, перед строкой CONF_DIR=/etc/mongrel_cluster) строчку <em>export PATH=$PATH&#187;:/var/lib/gems/1.8/bin/&#187;</em> и исправим <em>USER=mongrel</em> на <em>USER=redmine</em></p>
<p>Пробуем:</p>
<pre class="brush: bash; title: ; notranslate">sudo service mongrel_cluster start</pre>
<p>Сервис должен запуститься и работать на 3000 порту.</p>
<p>Обновляем rc.d правила для автоматического запуска и остановки mongrel</p>
<pre class="brush: bash; title: ; notranslate">sudo update-rc.d mongrel_cluster defaults</pre>
<p>Теперь Mongrel будет самостоятельно запускаться при старте компьютера!</p>
<h2>Настройка NGINX для проксирования Mongrel</h2>
<p>В принципе практически ничем не отличается от настройки проксирования Apache, разве что, если у вас запущено больше одного процесса mongrel, нужно настроить апстрим для балансировки нагрузки:<br />
<code>
<pre>
upstream mongrel {
  server 127.0.0.1:3000;
  server 127.0.0.1:3001;
#и т.д., в зависимости от количества запущенных Mongrel
}
server {
        listen       80;
        server_name  <strong>redmine.yoursite</strong>.ru;
        root    /home/redmine/public;
        location / {
                try_files $uri @fallback;
        }
        location @fallback {
                proxy_pass     http://mongrel/;
                proxy_connect_timeout 15;
                proxy_redirect  off;
                proxy_set_header        Host    $host;
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}</pre>
<p></code>Сохраняем, перезапускаем Nginx, идем по адресу http://redmine.yoursite.ru</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2010/01/14/ustanovka-redmine-na-ubuntu-9-10-pod-nginx-chast-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Установка Redmine на Ubuntu под Nginx</title>
		<link>http://seriyps.ru/blog/2010/01/14/ustanovka-redmine-na-ubuntu-9-10-pod-nginx/</link>
		<comments>http://seriyps.ru/blog/2010/01/14/ustanovka-redmine-na-ubuntu-9-10-pod-nginx/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 02:05:59 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[linux на сервере]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[redmine]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=431</guid>
		<description><![CDATA[Redmine &#8212; это довольно популярная в последнее время платформа для управления проектами и отслеживания ошибок. По идее, его установка &#8212; стандартная процедура, но мне, как совершенно незнакомому с Ruby и тонкостями установки Ruby софта пришлось повозиться. Кроме того, в большинстве инструкций описывается использование Apache в качестве веб-сервера. У меня для этой цели будет использован Nginx Подготовка [...]]]></description>
			<content:encoded><![CDATA[<p>Redmine &#8212; это довольно популярная в последнее время платформа для управления проектами и отслеживания ошибок. По идее, его установка &#8212; стандартная процедура, но мне, как совершенно незнакомому с Ruby и тонкостями установки Ruby софта пришлось повозиться.</p>
<p>Кроме того, в большинстве инструкций описывается использование Apache в качестве веб-сервера. У меня для этой цели будет использован Nginx</p>
<p><span id="more-431"></span></p>
<h2>Подготовка системы</h2>
<p>Для начала установим минимально необходимые для работы Ruby пакеты</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get install ruby rubygems ruby1.8-dev libgemplugin-ruby libgemplugin-ruby1.8  libruby-extras libruby1.8-extras rubygems1.8 libsqlite3-ruby libopenssl-ruby</pre>
<p>Пакеты <em>ruby,  ruby1.8-dev, libruby-extras, libruby1.8-extras</em> нужны для работы самого руби,<em> rubygemslib, gemplugin-ruby, libgemplugin-ruby1.8, rubygems1.8</em> нужны для установки Ruby библиотек из самого руби (эт такой руби-пакетный менеджер), <em>libopenssl-ruby</em> &#8212; для SSL, <em>libsqlite3-ruby</em> &#8212; для работы с sqlite3 базой данных. Хочу заметить, что это НЕОБХОДИМЫЙ МИНИМУМ пакетов.</p>
<p>Далее устанавливаем необходимые для работы Redmine Ruby &#8212; библиотеки через встроенный пакетный менеджер <em>gem</em></p>
<pre class="brush: bash; title: ; notranslate">sudo gem install -v=2.3.5 rails
sudo gem install i18n
sudo gem install mysql mongrel mongrel_cluster</pre>
<p><em>mysql</em> &#8212; C-библиотека для работы с MySQL базой данных (см UPD), <em>rails</em> &#8212; знаменитые RubyOnRails (таблица совместимости различных версий redmine с версиями rails есть <a href="http://www.redmine.org/projects/redmine/wiki/RedmineInstall#Ruby-38-Ruby-on-Rails-38-Rack" title="redmine + rails">тут</a>), <em>mongrel</em> и <em>mongrel_cluster</em> &#8212; родной веб-сервер для Ruby веб-приложений, <em>i18n</em> &#8212; библиотека для перевода интерфейса.</p>
<h2>Создание учетных записей</h2>
<p>В принципе, этот шаг можно пропустить и использовать существующего пользователя, например www-data, но я крайне рекомендую все-же не полениться и, ради безопасности, проделать и эту часть инструкции.</p>
<p>Создаем нового пользователя с домашней директорией /home/redmine , и именем redmine</p>
<pre class="brush: bash; title: ; notranslate">sudo useradd -d /home/redmine -m -s /bin/bash redmine ; sudo passwd redmine</pre>
<p>После ввода этой команды придумайте пароль для нового пользователя и введите его в появившемся запросе.</p>
<p>Переключаемся на созданного пользователя</p>
<pre class="brush: bash; title: ; notranslate">sudo su redmine ; cd ~</pre>
<p>.</p>
<h2>Загрузка и настройка Redmine</h2>
<p>Если у вас есть GIT, то</p>
<pre class="brush: bash; title: ; notranslate">git clone git://github.com/edavis10/redmine.git</pre>
<p>Если нет:</p>
<pre class="brush: bash; title: ; notranslate">svn co http://redmine.rubyforge.org/svn/trunk redmine</pre>
<p>Можно в общем-то и tarball скачать тут http://rubyforge.org/frs/?group_id=1850:</p>
<pre class="brush: bash; title: ; notranslate">wget http://rubyforge.org/frs/download.php/75097/redmine-1.2.1.tar.gz
tar -xzf redmine-1.2.1.tar.gz</pre>
<p>Перемещаем полученные файлы в корень домашней директории и подчищаем мусор</p>
<pre class="brush: bash; title: ; notranslate">mv redmine/* . ; rm -r redmine</pre>
<p>Теперь нужно настроить соединение Redmine с базой данных&#8230; Redmine поддерживает работу с базами данных sqlite, mysql и postgre-sql. MySQL у меня на сервере есть, но его версия 5.1. Проблема в том, что текущая версия Ruby библиотеки не поддерживает работу с версией 5.1 сервера MySQL, поэтому я решил использовать sqlite3 базу данных. Так вот, копируем пример конфиг-файла</p>
<pre class="brush: bash; title: ; notranslate">cp config/database.yml.example config/database.yml</pre>
<p>И редактируем этот конфиг</p>
<pre class="brush: bash; title: ; notranslate">nano config/database.yml</pre>
<p>Меняем строки <em>production</em> на что-то вроде <em>backup_production</em> а строку <em>test_sqlite3</em> на <em>production</em>, сохраняем. Т.е. вся база данных будет храниться в sqlite3 файле <em>db/test.db</em> (создастся автоматически)</p>
<p>После создаем некое рандомное значение, необходимое для кодирования Cookies</p>
<pre class="brush: bash; title: ; notranslate">rake config/initializers/session_store.rb</pre>
<p>Генерируем структуру базы данных</p>
<pre class="brush: bash; title: ; notranslate">rake db:migrate RAILS_ENV=&quot;production&quot;</pre>
<p>Загружаем и импортируем в базу данных стандартные данные</p>
<pre class="brush: bash; title: ; notranslate">RAILS_ENV=production rake redmine:load_default_data</pre>
<p>Выставляем необходимые права доступа</p>
<pre class="brush: bash; title: ; notranslate">mkdir tmp public/plugin_assets sudo chown -R redmine:redmine files log tmp public/plugin_assets sudo chmod -R 755 files log tmp public/plugin_assets</pre>
<p>В принципе, теперь можно попробовать запустить:</p>
<pre class="brush: bash; title: ; notranslate">ruby script/server webrick -e production</pre>
<p>При этом запустится простенький веб-сервер по адресу <a href="http://localhost:3000/">http://localhost:3000/</a> Можно открыть в браузере, зайти под учеткой admin/admin, сменить пароль на нормальный. Для остановки сервера жмем Ctrl+C. Если хотите использовать redmine локально &#8212; на этом можно остановиться, а для совместной работы через интернет нужно настроить веб-сервер для работы с Ruby и Redmine. Как это сделать &#8212; <a href="http://seriyps.ru/blog/2010/01/14/ustanovka-redmine-na-ubuntu-9-10-pod-nginx-chast-2/">см во 2-й части</a></p>
<p><strong>UPD:</strong> для использования Redmine с базой данных MySQL необходимо установить драйвер MySQL для Ruby т.к. без этого будет выскакивать сообщение &#171;!!! The bundled mysql.rb driver has been removed from Ruby 2.2&#8243;. Т.е. выполняем</p>
<pre class="brush: bash; title: ; notranslate">sudo gem install mysql</pre>
<p>Если при этом у вас появляется сообщение об ошибке типа</p>
<blockquote><p>ERROR:  Error installing mysql:<br />
ERROR: Failed to build gem native extension.</p>
<p>/usr/bin/ruby1.8 extconf.rb<br />
checking for mysql_query() in -lmysqlclient&#8230; no<br />
checking for main() in -lm&#8230; yes<br />
&#8230;&#8230;&#8230;..<br />
*** extconf.rb failed ***</p></blockquote>
<p>То нужно немного настроить окружение:</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get install build-essential libmysqlclient-dev</pre>
<p>Возможно понадобится libmysql-cil-dev пакет. После этого повторяем sudo gem install mysql и спокойненько пользуемся MySQL в качестве БД для Redmine.</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2010/01/14/ustanovka-redmine-na-ubuntu-9-10-pod-nginx/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Nginx + PHP-fcgi на Ubuntu</title>
		<link>http://seriyps.ru/blog/2009/11/06/nginx-php-fcgi-na-ubuntu/</link>
		<comments>http://seriyps.ru/blog/2009/11/06/nginx-php-fcgi-na-ubuntu/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 11:22:40 +0000</pubDate>
		<dc:creator>P.S.</dc:creator>
				<category><![CDATA[linux на сервере]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php-cgi]]></category>
		<category><![CDATA[php5-fcgi]]></category>
		<category><![CDATA[сервер]]></category>

		<guid isPermaLink="false">http://seriyps.ru/blog/?p=388</guid>
		<description><![CDATA[Если быть точным, опишу переход с режима работы Nginx &#60;-&#62; Apache backend на Nginx &#60;-&#62; php-fcgi backend. Т.е. об отказе от промежуточного, в общем-то бесполезного слоя в виде апача между Nginx (http сервер) и PHP (application сервер) Отдельно хочу заметить, что в этом руководстве мы обойдемся без компиляции чего-бы то ни было Что имеем на [...]]]></description>
			<content:encoded><![CDATA[<p>Если быть точным, опишу переход с режима работы <em>Nginx &lt;-&gt; Apache backend</em> на <em>Nginx &lt;-&gt; php-fcgi backend</em>.</p>
<p>Т.е. об отказе от промежуточного, в общем-то бесполезного слоя в виде апача между <strong>Nginx</strong> (http сервер) и <strong>PHP </strong>(application сервер)</p>
<p>Отдельно хочу заметить, что в этом руководстве мы обойдемся <span style="text-decoration: underline;">без компиляции</span> чего-бы то ни было</p>
<p><span id="more-388"></span><strong>Что имеем на данный момент:</strong></p>
<p>Имеется домен с поддоменами, сервер на Ubuntu 9.10 с веб-сервером Nginx, который слушает 80 порт, и Апач с mod-php, висящий на localhost:8080 (в качестве прокси-бэкенда нгинкса). Для коннекта к апачу в <em>/etc/nginx/sites-enabled</em> лежит симлинк на файлик <em>100apache_proxy</em> следующего содержания:</p>
<pre style="overflow: auto;">server {
listen       80;
server_name  <strong>seriyps.ru *.seriyps.ru localhost</strong>;
access_log  /var/log/nginx/apache_proxy.access.log;
location / {
	proxy_pass      http://localhost:8080;#проксируем данные на апач
	proxy_connect_timeout 15;#время ожидания ответа от апача - 15 секунд, можно больше
	proxy_redirect  off;
	proxy_set_header	Host    $host;#Ставим HTTP заголовок Host
	proxy_set_header	X-Real-IP $remote_addr;#Заголовок X_Real-Ip т.к. внешние запросы принимает NGINX а апачу достаются в качестве IP только 172.0.0.1
	proxy_set_header	X-Forwarded-For $proxy_add_x_forwarded_for;#то-же самое
}</pre>
<p><strong>В итоге хотим</strong>:</p>
<p>ПЛАВНО перейти с использования apache прослойки на полное использование nginx&lt;-&gt;php-fcgi с минимальными простоями сервера.</p>
<p>Приступим!</p>
<h2>Настройка PHP для работы в режиме fast-CGI</h2>
<p>Для начала поставим пакет php5-cgi (он нужен для использования PHP отдельно от apache)</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get install php5-cgi</pre>
<p>Затем ставим <a href="http://redmine.lighttpd.net/projects/spawn-fcgi" target="_blank">пакетик spawn-fcgi</a> Эта утилитка нужна для удобного управления fast-cgi процессами независимо от веб-сервера.</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get install spawn-fcgi</pre>
<p>После чего создаем скрипт для запуска <em>php5-fcgi</em> процесса через <em>spawn-fcgi</em></p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/sh
### BEGIN INIT INFO
# Provides:          php5-fcgi
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the php5-cgi in fast-cgi mode
# Description:       configure and starts php5-cgi processes in fast-cgi mode using spawn-fcgi
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin
SCRIPTNAME=&quot;/etc/init.d/php5-fcgi&quot;

FCGI_PIDFILE=&quot;/var/run/spawn-php5-fcgi.pid&quot;
## Абсолютный путь до spawn-fcgi
FCGI_DAEMON=&quot;/usr/bin/spawn-fcgi&quot;

## php переключится на этого юзера и группу (делать такими-же, как у апача)
USER=www-data
GROUP=www-data
## Абсолютный путь до  php
FCGI_PROGRAM=&quot;/usr/bin/php5-cgi&quot;
## Количество запущенных процессов PHP-fcgi, см http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:PerformanceFastCGI#How-many-PHP-processes-do-I-need
PHP_FCGI_CHILDREN=10
## максимальное количество запросов, которое обработает отдельный PHP - fcgi процесс до своего перезапуска
PHP_FCGI_MAX_REQUESTS=1000
## TCP порт, который будет слушать php-fcgi
FCGI_PORT=&quot;9000&quot;
## IP адреса, по которым будет доступен PHP-fcgi (через запятую)
FCGI_IP=&quot;127.0.0.1&quot;

test -x $FCGI_PROGRAM || exit 0
test -x $FCGI_DAEMON || exit 0

set -e

export PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS

. /lib/lsb/init-functions

case &quot;$1&quot; in
  start)
        log_daemon_msg &quot;Starting spawn-fcgi&quot;
        if ! $FCGI_DAEMON -a $FCGI_IP -p $FCGI_PORT -f $FCGI_PROGRAM -u $USER -g $GROUP -C $PHP_FCGI_CHILDREN -P $FCGI_PIDFILE; then
            log_end_msg 1
        else
            log_end_msg 0
        fi
        RETVAL=$?
  ;;
  stop)
        log_daemon_msg &quot;Killing all spawn-fcgi processes&quot;
	start-stop-daemon --stop --pidfile $FCGI_PIDFILE --signal 2 &amp; log_end_msg 0 || log_end_msg 1
        #if killall --signal 2 php5-cgi &gt; /dev/null 2 &gt; /dev/null; then
        #    log_end_msg 0
        #else
        #    log_end_msg 1
        #fi
        RETVAL=$?
  ;;
  restart|force-reload)
        $0 stop
        #sleep 1
        $0 start
  ;;
  *)
        echo &quot;Usage: $SCRIPTNAME {start|stop|restart|force-reload}&quot; &gt;&amp;2
        exit 1
  ;;
esac

exit $RETVAL
</pre>
<p>Этот скрипт &#8212; несколько адаптированная версия скрипта из примера в документации сервера lighttpd <a href="http://redmine.lighttpd.net/projects/lighttpd/wiki/ScriptsUbuntu" target="_blank">http://redmine.lighttpd.net/projects/lighttpd/wiki/ScriptsUbuntu</a> приспособленная для работы с rc.d правилами Ubuntu/Debian. Можно сделать попроще &#8212; см <a href="http://redmine.lighttpd.net/projects/spawn-fcgi/wiki/Basic_Ideas" target="_blank">http://redmine.lighttpd.net/projects/spawn-fcgi/wiki/Basic_Ideas</a> но в таком случае за перезапуском PHP при загрузке придется следить самостоятельно</p>
<p>Сохраняем этот скрипт как <em>/etc/init.d/php5-fcgi</em> и даем права на исполнение:</p>
<pre class="brush: bash; title: ; notranslate">sudo chmod +x /etc/init.d/php5-fcgi</pre>
<p>Обновляем правила <em>rc.d</em> для автоматического запуска <em>php5-fcgi</em> при старте системы:</p>
<pre class="brush: bash; title: ; notranslate">sudo update-rc.d php5-fcgi defaults</pre>
<p>Запускаем:</p>
<pre class="brush: bash; title: ; notranslate">sudo service php5-fcgi start</pre>
<p>spawn-fcgi: child spawned successfully: PID: 23620</p>
<p>Проверяем:</p>
<pre class="brush: bash; title: ; notranslate">ps xa | grep php5-cgi</pre>
<p>Должен выдать что-то вроде</p>
<pre>23620 ?        Ss     0:00 /usr/bin/php5-cgi
23622 ?        S      0:00 /usr/bin/php5-cgi
23623 ?        S      0:00 /usr/bin/php5-cgi
23624 ?        S      0:00 /usr/bin/php5-cgi
23625 ?        S      0:00 /usr/bin/php5-cgi
23626 ?        S      0:00 /usr/bin/php5-cgi
23627 ?        S      0:00 /usr/bin/php5-cgi
23628 ?        S      0:00 /usr/bin/php5-cgi
23629 ?        S      0:00 /usr/bin/php5-cgi
23630 ?        S      0:00 /usr/bin/php5-cgi
23631 ?        S      0:00 /usr/bin/php5-cgi</pre>
<p>Если вы видите то-же самое, значит, скорее всего, все сделано правильно! Обратите внимание на процесс <em>23620 ? Ss 0:00 /usr/bin/php5-cgi</em> &#8212; это что-то наподобие мастер-процесса, он является родителем для остальных процессов <em>php5-cgi</em>. Убиваем его &#8212; убиваем все процессы <em>php5-cgi</em>.<br />
Первая часть настройки закончена!</p>
<h2>Настройка Nginx для работы с php-fcgi</h2>
<p>Тут все просто (если не нужно настраивать url-rewrite правила).<br />
В папочке <em>/etc/nginx/sites-available</em> создаем файлик, например <em><strong>20yourdomain.com</strong></em> примерно следующего содержания:</p>
<pre>#/etc/nginx/sites-available/<strong>20yourdomain.com</strong>
server {
	listen   80;
	server_name  <strong>yourdomain.com</strong>;

	access_log  /var/log/nginx/<strong>yourdomain_com</strong>.log;
	root   /var/www/<strong>yourdomain.com</strong>;
	index  index.php index.html index.htm;

	# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9090
	#
	location ~ \.php$ {
		fastcgi_pass   127.0.0.1:9000;
		fastcgi_index  index.php;
		fastcgi_param  SCRIPT_FILENAME  /var/www/<strong>yourdomain.com</strong>$fastcgi_script_name;
		include fastcgi_params;
	}
	# deny access to .htaccess files, if Apache's document root
	# concurs with nginx's one
	location ~ /\.ht {
		deny  all;
	}

}</pre>
<p>(места, выделенные <strong>жирным шрифтом</strong> замените на ваши данные)</p>
<p>Создаем на него символическую ссылку в <em>/etc/nginx/sites-enabled</em></p>
<pre class="brush: bash; title: ; notranslate">sudo ln -s /etc/nginx/sites-available/&lt;strong&gt;20yourdomain.com &lt;/strong&gt;/etc/nginx/sites-enabled/&lt;strong&gt;20yourdomain.com&lt;/strong&gt;</pre>
<p>Проверяем правильность конфига</p>
<pre class="brush: bash; title: ; notranslate">sudo service nginx configtest</pre>
<p>Testing nginx configuration: the configuration file /etc/nginx/nginx.conf syntax is ok<br />
configuration file /etc/nginx/nginx.conf test is successful<br />
nginx.</p>
<p>Готово! перезапускаем Nginx</p>
<pre class="brush: bash; title: ; notranslate">sudo service nginx restart</pre>
<p>и наслаждаемся! При необходимости проделываем эту процедуру для каждого поддомена, добавляем правила URL-rewrite и наслаждаемся еще больше.</p>
]]></content:encoded>
			<wfw:commentRss>http://seriyps.ru/blog/2009/11/06/nginx-php-fcgi-na-ubuntu/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

