<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2russianfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>codeart.ru</title>
	
	<link>http://www.codeart.ru</link>
	<description>Для тех, кто видит WEB иначе</description>
	<pubDate>Thu, 17 May 2012 15:50:53 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/codeart" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="codeart" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">codeart</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fcodeart" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://lenta.yandex.ru/settings.xml?name=feed&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fcodeart" src="http://lenta.yandex.ru/i/addfeed.gif">?????? ? ??????.?????</feedburner:feedFlare><item>
		<title>Мой вариант функции get_host_from_url, написанной на erlang</title>
		<link>http://www.codeart.ru/2012/05/17/moj-variant-funkcii-get_host_from_url-napisannoj-na-erlang/</link>
		<comments>http://www.codeart.ru/2012/05/17/moj-variant-funkcii-get_host_from_url-napisannoj-na-erlang/#comments</comments>
		<pubDate>Thu, 17 May 2012 15:47:45 +0000</pubDate>
		<dc:creator>Evgeny Sergeev</dc:creator>
		
		<category><![CDATA[Главная]]></category>

		<category><![CDATA[erlang]]></category>

		<category><![CDATA[прогаммирование]]></category>

		<guid isPermaLink="false">http://www.codeart.ru/?p=1630</guid>
		<description><![CDATA[Я совсем новичок в функциональном программирований, поэтому вполне возможно склонен к изобретению велосипедов. В связи с чем хочу поделиться своими мыслями по написанию простейшей функции, которая извлекает из урла имя хоста.  Очень интересно послушать конструктивную критику, в выражениях можно не стесняться :-).

Итак, начнем с формализации поставленной задачи. 
Во-первых, при написании функции будем исходить из [...]]]></description>
			<content:encoded><![CDATA[<p>Я совсем новичок в функциональном программирований, поэтому вполне возможно склонен к изобретению велосипедов. В связи с чем хочу поделиться своими мыслями по написанию простейшей функции, которая извлекает из урла имя хоста.  Очень интересно послушать конструктивную критику, в выражениях можно не стесняться :-).<br />
<span id="more-1630"></span></p>
<p>Итак, начнем с формализации поставленной задачи. </p>
<p>Во-первых, при написании функции будем исходить из того, что на вход всегда подается урл, заданный в виде строки. Пусть erlang сам вываливается с исключительной ситуацией, когда на вход попадает какой-нибудь другой примитив, например массив. </p>
<p>Во-вторых, будем исходить из того, что если на вход поступила строка, то это обязательно валидный урл, а не что-нибудь иное. Поэтому проверку на корректность урла делать так же не будем.</p>
<p>Теперь о том, что мы будем делать. Вот небольшая спецификация того, как должна работать функция:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">get_host_from_url<span class="br0">&#40;</span><span class="st0">&quot;http://www.codeart.ru&quot;</span><span class="br0">&#41;</span> <span class="co1">// [&quot;www.codeart.ru&quot;]</span><br />
get_host_from_url<span class="br0">&#40;</span><span class="st0">&quot;http://www.codeart.ru/some/tail/here&quot;</span><span class="br0">&#41;</span> <span class="co1">// [&quot;www.codeart.ru&quot;]</span><br />
get_host_from_url<span class="br0">&#40;</span><span class="st0">&quot;www.codeart.ru&quot;</span><span class="br0">&#41;</span> <span class="co1">// [&quot;www.codeart.ru&quot;]</span><br />
get_host_from_url<span class="br0">&#40;</span><span class="st0">&quot;www.codeart.ru/some/tail/here&quot;</span><span class="br0">&#41;</span> <span class="co1">// [&quot;www.codeart.ru&quot;]</span><br />
get_host_from_url<span class="br0">&#40;</span><span class="st0">&quot;/some/tail/here&quot;</span><span class="br0">&#41;</span> <span class="co1">// empty (примечание: empty - это атом, а не строка)</span><br />
get_host_from_url<span class="br0">&#40;</span><span class="st0">&quot;http://&quot;</span><span class="br0">&#41;</span> <span class="co1">// empty</span><br />
get_host_from_url<span class="br0">&#40;</span><span class="st0">&quot;&quot;</span><span class="br0">&#41;</span> <span class="co1">// empty</span><br />
get_host_from_url<span class="br0">&#40;</span>undefined<span class="br0">&#41;</span> <span class="co1">// empty</span></div>
</div>
<p>По-хорошему по данной спецификации нужно написать небольшой тест, но в рамках данной заметки я этого делать не буду. Давайте представим, что при реальной разработке я его написал.  А здесь просто опустил :-).</p>
<p>Переходим к самой функции. Начнем обработку с простейшего варианта - когда вместо урла передается значение undefined:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">get_host_from_url<span class="br0">&#40;</span>undefined<span class="br0">&#41;</span> -&gt;<br />
&nbsp; empty;</div>
</div>
<p>Теперь добавим обработку урлов, которые начинаются с префикса &#8220;http://&#8221;:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">get_host_from_url<span class="br0">&#40;</span>Url<span class="br0">&#41;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; <span class="kw1">case</span> re:run<span class="br0">&#40;</span>Url,<span class="st0">&quot;http:<span class="es0">\/</span><span class="es0">\/</span>([^/]*)&quot;</span>, <span class="br0">&#91;</span><span class="br0">&#123;</span>capture,<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, list<span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> of<br />
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>match, <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#125;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; empty;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>match, Host<span class="br0">&#125;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Host;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nomatch -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; empty<br />
&nbsp; &nbsp; &nbsp; &nbsp; end.</div>
</div>
<p>Нетрудно заметить, что регулярное выражение, которое используется в функции выше, не охватывает случаи, когда в урле отсутствует префикс &#8220;http://&#8221;. Я не особый любитель сложных регулярных выражений, поэтому не буду даже пытаться искать вариант при котором в рамках одной регулярки можно обрабатывать два варианта строк - с &#8220;http://&#8221; и без.  Вместо этого я хочу сделать дополнительную функцию.</p>
<p>И вот здесь я не знаю как поступить наилучшим образом. Мне в голову пришло такое решение - я создал дополнительную функцию следующего вида:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">get_host_from_url<span class="br0">&#40;</span>without_http, Url<span class="br0">&#41;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> re:run<span class="br0">&#40;</span>Url, <span class="st0">&quot;([^/]*)&quot;</span>, <span class="br0">&#91;</span><span class="br0">&#123;</span>capture, <span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, list<span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> of<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>match, <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#125;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; empty;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>match, Host<span class="br0">&#125;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Host;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nomatch -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; empty<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end</div>
</div>
<p>Данная функция должна обрабатывать урлы, у которых нет префикса &#8220;http://&#8221;. Нетрудно заметить, что данная функция не обрабатывает &#8220;чистые&#8221; урлы - у которых имя хоста совпадает с именем урла. Но если урл чистый, то для него никаких проверок не требуется, поэтому я сделал следующую функцию:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">get_host_from_url<span class="br0">&#40;</span>without_tail, Url<span class="br0">&#41;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Url.</div>
</div>
<p>В итоге у меня получился следующий код:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">get_host_from_url<span class="br0">&#40;</span>undefined<span class="br0">&#41;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; empty;<br />
get_host_from_url<span class="br0">&#40;</span>Url<span class="br0">&#41;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; <span class="kw1">case</span> re:run<span class="br0">&#40;</span>Url,<span class="st0">&quot;http:<span class="es0">\/</span><span class="es0">\/</span>([^/]*)&quot;</span>, <span class="br0">&#91;</span><span class="br0">&#123;</span>capture,<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, list<span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> of<br />
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>match, <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#125;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; empty;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>match, Host<span class="br0">&#125;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Host;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nomatch -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get_host_from_url<span class="br0">&#40;</span>without_http, Url<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _ -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; empty<br />
&nbsp; &nbsp; &nbsp; &nbsp; end.</p>
<p><span class="me1">get_host_from_url</span><span class="br0">&#40;</span>without_http, Url<span class="br0">&#41;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> re:run<span class="br0">&#40;</span>Url, <span class="st0">&quot;([^/]*)&quot;</span>, <span class="br0">&#91;</span><span class="br0">&#123;</span>capture, <span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, list<span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> of<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>match, <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#125;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; empty;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>match, Host<span class="br0">&#125;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Host;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nomatch -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get_host_from_url<span class="br0">&#40;</span>without_tail, Url<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br />
get_host_from_url<span class="br0">&#40;</span>without_tail, Url<span class="br0">&#41;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Url.</div>
</div>
<p>Хочу обратить внимание, что когда я описывал функции по отдельности в секции &#8220;nomatch&#8221; я указывал значение &#8220;empty&#8221;,  а в итоговом варианте я сделал вызов соответствующих функций. </p>
<p>Лично мне полученный код очень нравится. Достаточно прозрачный и чистый. Возможно несколько многословный, но красивый :-). Очень интересно услышать ваше мнение, и, конечно же, любая критика приветствуется. </p>
<p>P.S.  я вижу, что в коде есть дублирование и от него, естественно, надо избавиться. Я пока вижу вариант с вынесением обработки регулярного выражения в отдельную функцию, которая выглядит как-то так:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">get_host_from_url<span class="br0">&#40;</span>by_regexp, RegExp, Url<span class="br0">&#41;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> re:run<span class="br0">&#40;</span>Url, RegExp, <span class="br0">&#91;</span><span class="br0">&#123;</span>capture, <span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, list<span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> of<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>match, <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#125;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; empty;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>match, Host<span class="br0">&#125;</span> -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Host;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nomatch -&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; empty<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end.</div>
</div>
<img src="http://feeds.feedburner.com/~r/codeart/~4/TXypJNR-z4s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeart.ru/2012/05/17/moj-variant-funkcii-get_host_from_url-napisannoj-na-erlang/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Конкурс на создание первого дефейса провалился</title>
		<link>http://www.codeart.ru/2012/05/16/konkurs-na-sozdanie-pervogo-defejsa-provalilsya/</link>
		<comments>http://www.codeart.ru/2012/05/16/konkurs-na-sozdanie-pervogo-defejsa-provalilsya/#comments</comments>
		<pubDate>Wed, 16 May 2012 14:42:54 +0000</pubDate>
		<dc:creator>Evgeny Sergeev</dc:creator>
		
		<category><![CDATA[Офтопик]]></category>

		<category><![CDATA[defaceit]]></category>

		<guid isPermaLink="false">http://www.codeart.ru/?p=1628</guid>
		<description><![CDATA[Знаю, что задержался с подведением итогов по конкурсу на лучший дефейс, который закончился еще 06.05.2012г. Но все же лучше поздно чем никогда. Итак, должен признать, что конкурс с треском провалился. За месяц не было сделано ни одного дефейса. 
Как мне кажется, причин тому несколько. Во-первых, я сам не проявил активности в привлечении внимания к конкурсу. [...]]]></description>
			<content:encoded><![CDATA[<p>Знаю, что задержался с подведением итогов по <a href="http://www.codeart.ru/2012/4/2/konkurs-3000-rublej-za-luchshij-defejs/">конкурсу на лучший дефейс</a>, который закончился еще 06.05.2012г. Но все же лучше поздно чем никогда. Итак, должен признать, что конкурс с треском провалился. За месяц не было сделано ни одного дефейса. </p>
<p>Как мне кажется, причин тому несколько. Во-первых, я сам не проявил активности в привлечении внимания к конкурсу. Одна заметка и сравнительно мелкий приз - это в общем-то слабая попытка, которая не может быть засчитана. Во-вторых, идея дефейсов до сих пор не имеет четкой и понятной формы. Пространные объяснения о том, что мол нужно сделать нечто, меняющее внешний вид или работу моего виджета ровным счетом ничего не объясняет, а только запутывает. К сожалению, я до сих пор не могу объяснить в двух словах, что такое дефейс и с чем его едят.</p>
<p>Что-ж, отрицательный опыт - это тоже опыт. В следующий раз я подойду более основательно к организации конкурса. Сейчас активно работаю над переводом defaceit.ru на erlang и ChicagoBoss. После перевода обязательно запущу еще один конкурс, и там учту все свои ошибки. <img src='http://www.codeart.ru/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/codeart/~4/p30nye4B9Wc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeart.ru/2012/05/16/konkurs-na-sozdanie-pervogo-defejsa-provalilsya/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Оказалось, что chef-solo для меня удобнее чем chef-server</title>
		<link>http://www.codeart.ru/2012/05/16/okazalos-chto-chef-solo-dlya-menya-udobnee-chem-chef-server/</link>
		<comments>http://www.codeart.ru/2012/05/16/okazalos-chto-chef-solo-dlya-menya-udobnee-chem-chef-server/#comments</comments>
		<pubDate>Wed, 16 May 2012 03:33:07 +0000</pubDate>
		<dc:creator>Evgeny Sergeev</dc:creator>
		
		<category><![CDATA[Обзоры]]></category>

		<category><![CDATA[chef]]></category>

		<category><![CDATA[Утилиты разработки]]></category>

		<guid isPermaLink="false">http://www.codeart.ru/?p=1624</guid>
		<description><![CDATA[Напомню, что не так давно начал разбираться с утилитами управления конфигурацией сервера, в частности с Chef. Я попробовал как централизованный вариант, когда конфигурация располагается на сервере. Так и локальный вариант, когда все необходимые &#8220;рецепты&#8221; располагаются непосредственно по месту установки. В итоге пришел к выводу, что второй вариант предпочтительнее и далее несколько слов почему.

Есть такое слово [...]]]></description>
			<content:encoded><![CDATA[<p>Напомню, что не так давно начал разбираться с утилитами управления конфигурацией сервера, <a href="http://www.codeart.ru/2012/05/09/problemy-pri-ustanovke-php-fpm-cherez-chef-server/">в частности с Chef</a>. Я попробовал как централизованный вариант, когда конфигурация располагается на сервере. Так и локальный вариант, когда все необходимые &#8220;рецепты&#8221; располагаются непосредственно по месту установки. В итоге пришел к выводу, что второй вариант предпочтительнее и далее несколько слов почему.<br />
<span id="more-1624"></span></p>
<h2>Есть такое слово &#8220;простота&#8221;</h2>
<p>Изначально использование утилит конфигурирования должно облегчать жизнь, а не усложнять. В случае с централизованным вариантом возникает куча мелочей, которые нужно постоянно держать в голове. Например, нужно разбивать серверы на группы, создавать для них роли, раздавать права, распределять рецепты и т.д. и т.п. </p>
<p>Безусловно, все эти мелочи далеко не бесполезны, каждая из них позволяет сократить затраты на сопровождение инфраструктуры в будущем. НО! Все это имеет смысл только в случае если количество серверов, которыми нужно управлять, исчисляется если не сотнями, то десятками точно. В противном случае управлять конфигурацией становится мучительно больно. Нет, правда! Когда у тебя всего десяток серверов, которые похожи друг на друга как братья близнецы, то совсем не хочется создавать все эти роли, раздавать права и т.д. </p>
<p>Короче, я так и не смог для себя найти комфортного варианта работы с chef-server. Например, я так и не понял как должен осуществляться деплой конфигурации в промышленных масштабах. Для того чтобы конфигурация применилась на сервере нужно запустить команду &#8220;chef-client&#8221;. Единственный вариант, при котором не нужно заходить на сервер для запуска этой команды, - это запуск chef-client по расписанию. Но тогда не понятно как быть с повторным применением рецептов. Да и вообще, как-то некрасиво все это <img src='http://www.codeart.ru/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2>Есть такое слово &#8220;контроль&#8221;</h2>
<p>Зато гораздо интереснее мне показалось использование chef-solo. Здесь для развертывания конфигурации нужно &#8220;доставить&#8221; рецепты на целевой сервер и запустить команду chef-solo, скормив ей при этом необходимую конфигурацию. Несмотря на то, что в данном случае так же нужно запускать команду на сервере данная схема мне показалась более прозрачной. Хотя бы потому что я сам могу решать каким механизмом доставить необходимые рецепты на сервер. Так же я сам могу подготовить наборы рецептов, которые будут представлять из себя своеобразные пакеты установки. Я могу иметь несколько таких пакетов, для развертывания системы. Так же я могу иметь пакеты для обновления уже установленного программного обеспечения и т.д. Каждый пакет - это просто архив, который закидывается и исполняется на сервере.</p>
<p>В итоге у меня родилась следующая схема. На стороне сервера по расписанию запускается скрипт, который проверяет наличие новых архивов с рецептами (пакетов). В случае если пакет найден, то скрипт его распаковывает и выполняет. После чего удаляет пакет или перемещает в специальную директорию для исполненных пакетов. В конце можно так же добавить отправку отчета об успешной установке пакета. </p>
<p>Сам пакет готовится на моей локальной машине и закидывается на сервер через ssh, здесь так же можно написать небольшой скрипт, который будет раскладывать пакеты на нужное количество серверов. <img src='http://www.codeart.ru/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> В итоге получается более прозрачная и контролируемая схема, чем вариант с использованием chef-server.</p>
<p>Сразу оговорюсь, что данный вариант, пожалуй, подходит для небольшого количества серверов. В случае сильного разрастания инфраструктуры могут возникнуть трудности. Тогда можно будет и к централизованному варианту перейти <img src='http://www.codeart.ru/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2>Есть такое слово &#8220;расширяемость&#8221;</h2>
<p>Еще одна идея с chef-solo связана с &#8220;синхронизацией&#8221; локальной виртуалки для разработки и боевого сервера. Здесь так же можно автоматизировать за счет применения скриптов. Скажем, сначала пакет закидывается на виртуалку. Происходит его инсталляция, прогон всех тестов и в случае успеха последних деплой пакета на боевой сервер. В итоге имеем соответствие на боевом и тестовом сервере, которая работает в полуавтоматическом режиме. Что совсем даже неплохо. </p>
<img src="http://feeds.feedburner.com/~r/codeart/~4/__A3obV0puw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeart.ru/2012/05/16/okazalos-chto-chef-solo-dlya-menya-udobnee-chem-chef-server/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Проблемы с Vi и клавишами управления курсором (стрелки) в Ubuntu</title>
		<link>http://www.codeart.ru/2012/05/12/problemy-s-vi-i-klavishami-upravleniya-kursorom-strelki-v-ubuntu/</link>
		<comments>http://www.codeart.ru/2012/05/12/problemy-s-vi-i-klavishami-upravleniya-kursorom-strelki-v-ubuntu/#comments</comments>
		<pubDate>Sat, 12 May 2012 15:00:24 +0000</pubDate>
		<dc:creator>Evgeny Sergeev</dc:creator>
		
		<category><![CDATA[Вопрос/Ответ]]></category>

		<guid isPermaLink="false">http://www.codeart.ru/?p=1622</guid>
		<description><![CDATA[Наткнулся на странные грабли - в режиме редактирования в Vi не работают клавиши управления курсором. Вместо ожидаемого перемещения в указанном направлении вставляется латинская буква и перенос строки, буква меняется в зависимости от нажатой клавиши. Я нашел как можно восстановить нормальное поведение, но так и не понял в чем корень проблемы. Может кто-нибудь пояснить в чем [...]]]></description>
			<content:encoded><![CDATA[<p>Наткнулся на странные грабли - в режиме редактирования в Vi не работают клавиши управления курсором. Вместо ожидаемого перемещения в указанном направлении вставляется латинская буква и перенос строки, буква меняется в зависимости от нажатой клавиши. Я нашел как можно восстановить нормальное поведение, но так и не понял в чем корень проблемы. Может кто-нибудь пояснить в чем дело?</p>
<p>Решение следующее: в ~/.exrc добавить строку &#8220;set nocp&#8221;. Вроде как данная команда отменяет &#8220;строгую совместимость&#8221;. Но, блин, что такое &#8220;строгая совместимость&#8221;? В чем корень проблемы? В общем, мне совершенно это неясно. Надеюсь на вашу помощь!</p>
<img src="http://feeds.feedburner.com/~r/codeart/~4/sNOvzfXOGoE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeart.ru/2012/05/12/problemy-s-vi-i-klavishami-upravleniya-kursorom-strelki-v-ubuntu/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Проблемы при установке php-fpm через chef server</title>
		<link>http://www.codeart.ru/2012/05/09/problemy-pri-ustanovke-php-fpm-cherez-chef-server/</link>
		<comments>http://www.codeart.ru/2012/05/09/problemy-pri-ustanovke-php-fpm-cherez-chef-server/#comments</comments>
		<pubDate>Wed, 09 May 2012 15:54:43 +0000</pubDate>
		<dc:creator>Evgeny Sergeev</dc:creator>
		
		<category><![CDATA[Вопрос/Ответ]]></category>

		<category><![CDATA[chef]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<category><![CDATA[Утилиты разработки]]></category>

		<guid isPermaLink="false">http://www.codeart.ru/?p=1613</guid>
		<description><![CDATA[Продолжаю знакомство с разными утилитами, которые должны облегчить мне жизнь. Вчера разбирался с Vagrant, сегодня начал разбираться с Chef. Chef - это утилита для управления конфигурацией сервера. Обычно применяется для однотипной настройки большого количества серверов, например может применяться в облачных средах. Далее немного о Chef и проблемах в установке php-fpm.

Самое большое преимущество Chef в том, [...]]]></description>
			<content:encoded><![CDATA[<p>Продолжаю знакомство с разными утилитами, которые должны облегчить мне жизнь. Вчера разбирался с Vagrant, сегодня начал разбираться с <a href="http://wiki.opscode.com/display/chef/About">Chef</a>. Chef - это утилита для управления конфигурацией сервера. Обычно применяется для однотипной настройки большого количества серверов, например может применяться в облачных средах. Далее немного о Chef и проблемах в установке php-fpm.<br />
<span id="more-1613"></span><br />
Самое большое преимущество Chef в том, что можно один раз написать интеграционные скрипты и затем тупо запусткать их на всех своих серверах. Сегодня я покопался как с chef solo, так и с chef server. Первый используется для деплоя конфигурации непосредственно на сервере, а второй позволяет организовать централизованное управление конфигурациями всех ваших серверов. </p>
<p>Правда во втором случае приходится завести Chef Account на сервере разработчика. Серверное решение можно использовать бесплатно в случае если обслуживается менее пяти узлов, в остальных случаях придется платить деньги. Причем, самый дешевый вариант стоит 120$ и позволяет управляет конфигурацией 20 узлов. </p>
<p>Я пока использую бесплатный план, в ознакомительных целях, но потом планирую перейти на что-то более существенное, так как 5 узлов - это совсем никуда не годится.</p>
<p>Основная заморочка в централизованном управлении вашими серверами - это безопасность. Лично у меня голова едет от всех этих публичных, приватных ключей, которые еще создаются отдельно для организации и пользователя. В общем,  если планируете работать с централизованным вариантом, придется разобраться  с этим вопросом. Я ничего рассказывать не буду, так как все подробно написано на официальном сайте.</p>
<p>Для того чтобы устанавливать софт на сервер у Chef есть готовые скрипты, которые называются рецепты. В этих скриптах подробно описано какие шаги должны быть выполнены при установке той или иной программы. В моем случае я захотел установить php-fpm, данный рецепт имеет зависимость от рецепта dotdep, поэтому пришлось стянуть оба рецепта. </p>
<p>В процессе отработки этих рецептов у меня возникла ошибка и после чего процесс установки завершился. Опытным путем было установлена, что проблема возникает в процессе работы команды:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">sudo apt-get install php5-fpm</div>
</div>
<p>При этом apt-get валится со следующей ошибкой:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">The following packages have unmet dependencies:<br />
&nbsp; php5-fpm: Depends: libssl0<span class="nu0">.9</span><span class="nu0">.8</span> <span class="br0">&#40;</span>&gt;= <span class="nu0">0.9</span>.8m<span class="nu0">-1</span><span class="br0">&#41;</span> but <span class="nu0">0.9</span>.8k-7ubuntu8<span class="nu0">.5</span> is to be installed<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PreDepends: dpkg <span class="br0">&#40;</span>&gt;= <span class="nu0">1.15</span><span class="nu0">.7</span><span class="nu0">.2</span><span class="br0">&#41;</span> but <span class="nu0">1.15</span><span class="nu0">.5</span>.6ubuntu4<span class="nu0">.1</span> is to be installed</div>
</div>
<p>Не буду ходить вокруг да около, а сразу скажу, что после долгого разбирательства было установлено, что рецепт dotdep добавляет свой apt репозиторий. При попытке установить php-fpm из данного репозитория возникает конфликт зависимостей между установленными и новыми пакетами. Я так и не смог понять каким образом можно поправить данную проблему, не трогая сами рецепты. Поэтому я просто переписал рецепт dotdeb. В результате у меня получился следующий скрипт:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">execute <span class="st0">&quot;apt-get update&quot;</span>.</p>
<p><span class="me1">execute</span> <span class="st0">&quot;sudo apt-get install -y python-software-properties&quot;</span>.</p>
<p><span class="me1">execute</span> <span class="st0">&quot;sudo add-apt-repository ppa:brianmercer/php5&quot;</span> <span class="kw1">do</span><br />
&nbsp; &nbsp; action :run<br />
&nbsp; &nbsp; notifies :run, resources<span class="br0">&#40;</span>:execute =&gt; <span class="st0">&quot;apt-get update&quot;</span><span class="br0">&#41;</span>, :immediately<br />
<span class="kw1">end</span></div>
</div>
<p>Который я успешно запихал в dotdeb/recipes/default.rb. После данного вмешательства установка php-fpm прошла на ура.</p>
<p>Завтра буду пробовать ставить nginx, хочу чтобы он собирался из исходников. Сегодня мельком глянул готовый рецепт, вроде есть там такая возможность. В общем, завтра посмотрю что к чему. За сим откланиваюсь.</p>
<img src="http://feeds.feedburner.com/~r/codeart/~4/4YiFOXtN23Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeart.ru/2012/05/09/problemy-pri-ustanovke-php-fpm-cherez-chef-server/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Как установить Vagrant на Ubuntu 12.04</title>
		<link>http://www.codeart.ru/2012/05/08/kak-ustanovit-vagrant-na-ubuntu-1204/</link>
		<comments>http://www.codeart.ru/2012/05/08/kak-ustanovit-vagrant-na-ubuntu-1204/#comments</comments>
		<pubDate>Tue, 08 May 2012 03:35:30 +0000</pubDate>
		<dc:creator>Evgeny Sergeev</dc:creator>
		
		<category><![CDATA[Вопрос/Ответ]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<category><![CDATA[Vagrant]]></category>

		<category><![CDATA[Утилиты разработки]]></category>

		<guid isPermaLink="false">http://www.codeart.ru/?p=1603</guid>
		<description><![CDATA[По наводке одного моего хорошего друга и коллеги - Димы Пяткова aka Dkrnl начал разбираться с Vagrant. Думаю, здесь будет уместно пояснить, что Vagran - это утилита, работающая из командной строки и позволяющая управлять виртуальными машинами на базе VirtualBox. Хотя сами разработчики позиционируют этот продукт несколько иначе, но на самом деле все обстоит именно так [...]]]></description>
			<content:encoded><![CDATA[<p>По наводке одного моего хорошего друга и коллеги - <a href="http://dpyatkov.ru/">Димы Пяткова aka Dkrnl</a> начал разбираться с <a href="http://vagrantup.com/">Vagrant</a>. Думаю, здесь будет уместно пояснить, что Vagran - это утилита, работающая из командной строки и позволяющая управлять виртуальными машинами на базе VirtualBox. Хотя сами разработчики позиционируют этот продукт несколько иначе, но на самом деле все обстоит именно так как я описал. </p>
<p>В принципе, я давно уже использую VirtualBox в процессе разработки своих проектов. Это действительно удобно. Но до сих пор у меня не было удобного механизма управления моими виртуальными машинами, поэтому Vagrant пришелся весьма кстати. Я думаю, что вам эта утилита так же окажется полезной, поэтому хочу рассказать о том, как установить Vagrant на Ubuntu 12.04 LTS.<br />
<span id="more-1603"></span></p>
<h2>Установка Ruby и RubyGems</h2>
<p>Vagrant разработан на языке Ruby, поэтому без поддержки этого языка на вашей рабочей станции не обойтись:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">$ sudo apt-get install ruby1<span class="nu0">.8</span> ruby1<span class="nu0">.8</span>-dev rubygems1<span class="nu0">.8</span><br />
$ sudo ln -s /usr/bin/ruby1<span class="nu0">.8</span> /usr/bin/ruby</div>
</div>
<p>На всякий случай проверяем,что все установилось корректно:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">$ ruby -v<br />
ruby <span class="nu0">1.8</span><span class="nu0">.7</span> <span class="br0">&#40;</span><span class="nu0">2011</span><span class="nu0">-06</span><span class="nu0">-30</span> patchlevel <span class="nu0">352</span><span class="br0">&#41;</span> <span class="br0">&#91;</span>x86_64-linux<span class="br0">&#93;</span></div>
</div>
<h2>Установка VirtualBox</h2>
<p>Здесь все просто, <a href="http://www.virtualbox.org/">идем на официальный сайт</a>, качаем дистрибутив и следуем инструкциям по установке. Останавливаться на этом я не буду. </p>
<h2>Устанавливаем Vagrant</h2>
<p>Можно скачать vagrant  в deb пакете, но я предпочел установить его через утилиту gem:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">$ sudo gem install vagrant</div>
</div>
<h2>Создаем первую виртуальную машину</h2>
<p>Для удобства разработчиков на официальном сайте Vagrant есть несколько базовых образов, которые можно и нужно использовать для создания базовой системы. Далее можно дополнить к базовому образу все необходимые программы и в результате получить гостевую систему, пригодную для разработки. В последствии на базе гостевой системы можно так же создать образ, который распространять между пользователями Vagrant.</p>
<p>Я предпочитаю использовать в своих проектах Ubuntu 10.04 Lucid32. В принципе, никто не мешает подобрать другой образ, который наилучшим образом будет удовлетворять вашим потребностям и хотелкам.</p>
<p>Стоит отметить, что для связи с гостевой системой используется механизм Shared Folders, о котором я уже неоднократно писал. Идея в том, что папка из которой вы запускаете гостевую систему автоматически пробрасывается в виртуальную машину. Таким образом нет необходимости для каждого образа настраивать Shared Folders, что очень удобно!</p>
<p>Но давайте вернемся к тому как запустить первую виртуальную машину, созданную с помощью Vagrant:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">$ vagrant box add lucid32 http://files.vagrantup.com/lucid32.box<br />
$ vagrant init lucid32<br />
$ vagrant up</div>
</div>
<p>Пожалуй, нужно пояснить, что команда <strong>vagrant box add</strong> нужна для того, чтобы скачать базовый образ гостевой системы, у вас может быть несколько образов разных систем, но для большинства разработчиков базовый образ будет один. Образ нужно скачать только один раз - при создании первой гостевой системы, потом он будет браться из локального хранилища.</p>
<p>Команда <strong>vagrant init</strong> нужна для того чтобы создать конфигурационный файл Vagrantfile, в котором нужно будет описать все конфигурационные опции вашего проекта. Об этом файле более подробно я напишу позже. Отмечу, что данная команда выполняется единожды - при создании нового проекта Vagrant.</p>
<p>Ну и команда <b>vagrant up</b> нужна для запуска виртуальной системы. </p>
<h2>Используем SSH для подключения к гостевой системе</h2>
<p>Для подключения к гостевой системе используется протокол ssh, и делается это довольно просто:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">$ vagrant ssh</div>
</div>
<p>На этом установка Vagrant завершена. После этого вы можете заняться настройкой ваше гостевой системы. Это можно делать разными способами, я, например, решил использовать для этого утилиту <a href="http://wiki.opscode.com/display/chef/Chef+Solo">Chef Solo</a>, которая хорошо интегрируется с Vagrant.</p>
<img src="http://feeds.feedburner.com/~r/codeart/~4/Ne5SEGmo4qQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeart.ru/2012/05/08/kak-ustanovit-vagrant-na-ubuntu-1204/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Итоги акции “Провокация” за апрель</title>
		<link>http://www.codeart.ru/2012/05/07/itogi-akcii-%e2%80%9cprovokaciya%e2%80%9d-za-aprel/</link>
		<comments>http://www.codeart.ru/2012/05/07/itogi-akcii-%e2%80%9cprovokaciya%e2%80%9d-za-aprel/#comments</comments>
		<pubDate>Mon, 07 May 2012 03:46:54 +0000</pubDate>
		<dc:creator>Evgeny Sergeev</dc:creator>
		
		<category><![CDATA[Офтопик]]></category>

		<guid isPermaLink="false">http://www.codeart.ru/?p=1599</guid>
		<description><![CDATA[Публикую очередные данные по акции по кодовым названием &#8220;Провокация&#8221;. Напомню, что по условиям этой акции те блоги с которых на мой сайт пришло наименьшее количество людей получают обратную вечную ссылку. Итак, результаты за апрель такие:

1. Блог страницы свободного человека
2. Интернет маркетинг от очаровательной блондинки
3. Блог Тормоза
4. Блог Лобач.info (уже второй раз в это рейтинге)
5. Блог [...]]]></description>
			<content:encoded><![CDATA[<p>Публикую очередные данные по акции по кодовым названием &#8220;Провокация&#8221;. Напомню, что по условиям этой акции те блоги с которых на мой сайт пришло наименьшее количество людей получают обратную вечную ссылку. Итак, результаты за апрель такие:<br />
<span id="more-1599"></span><br />
1. <a href="http://blog.sitefreeman.com/">Блог страницы свободного человека</a><br />
2. <a href="http://www.epochta.ru/blog/">Интернет маркетинг от очаровательной блондинки</a><br />
3. <a href="http://brokenbrake.biz">Блог Тормоза</a><br />
4. <a href="http://lobach.info/">Блог Лобач.info</a> (уже второй раз в это рейтинге)<br />
5. <a href="http://anton.shevchuk.name/">Блог Антона Шевчука</a></p>
<p>Кроме рейтинга еще пару новостей, которые не хочется пихать в отдельный блог.</p>
<p>Во-первых, я таки переполз с Fedora Linux и KDE на Ubuntu и Unity. Пока очень даже нравится. Приятно, что все девайся заработали прямо из коробки, даже usb-микрофон, с которым в Федоре пришлось покопаться.</p>
<p>Во-вторых, не могу не похвастаться тем, что приобрел себе новый фотик - Sony Alpha 77, c китовым объективом 16-50 SSM/2.8. Аппарат очень нравится, первую неделю вообще не выпускал его из рук. Фотал все подряд. <img src='http://www.codeart.ru/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/codeart/~4/TSCoV-ZnOrQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeart.ru/2012/05/07/itogi-akcii-%e2%80%9cprovokaciya%e2%80%9d-za-aprel/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Впечателения от Amazon Simple Queue Service (SQS)</title>
		<link>http://www.codeart.ru/2012/04/27/vpechateleniya-ot-amazon-simple-queue-service-sqs/</link>
		<comments>http://www.codeart.ru/2012/04/27/vpechateleniya-ot-amazon-simple-queue-service-sqs/#comments</comments>
		<pubDate>Fri, 27 Apr 2012 12:13:16 +0000</pubDate>
		<dc:creator>Evgeny Sergeev</dc:creator>
		
		<category><![CDATA[Обзоры]]></category>

		<guid isPermaLink="false">http://www.codeart.ru/?p=1590</guid>
		<description><![CDATA[Amazon предлагает кучу сервисов, которые на первый взгляд выглядят полезными. Например, сервис сообщений, который позволяет поместить в очередь сообщение и затем забрать его любым приложением, находящимся в облаке или за его пределами. Смысл в том, что данный сервис позволяет организовать обмен сообщениями между несколькими приложениями. Но возникает вопрос где в реальной жизни можно использовать данный [...]]]></description>
			<content:encoded><![CDATA[<p>Amazon предлагает кучу сервисов, которые на первый взгляд выглядят полезными. Например, сервис сообщений, который позволяет поместить в очередь сообщение и затем забрать его любым приложением, находящимся в облаке или за его пределами. Смысл в том, что данный сервис позволяет организовать обмен сообщениями между несколькими приложениями. Но возникает вопрос где в реальной жизни можно использовать данный сервис.<br />
<span id="more-1590"></span><br />
Если сказать коротко, то обмен сообщениями через общую очередь сообщений мне бы пригодились для проектов SnappySnoop и Defaceit. Думаю, что мало кто помнит о моем проекте SnappySnoop, поэтому позволю себе немного рассказать о том что это за проект такой.</p>
<p>SnappySnoop - это сервис мнений и комментариев. Основная идея состоит в том, что каждый может оставить свой комментарий на любом сайте, даже если сам сайт не имеет механизмов для размещения комментариев. Реализация состоит в том, чтобы подгрузить на сайт JavaScript, который загрузит комментарии и отобразит их на сайте. Фактически все комментарии храняться на сайте SnappySnoop, а отбор нужных комментариев обеспечивается на основе полного урла страницы, на которой запущен скрипт. Не трудно понять, что серверная часть данной задачи представляет из себя самую обычную очередь. </p>
<p>Идея Defaceit немного другая, она заключается в том, что на Defaceit размещаются JavaScript приложения, которые могут быть модифицированы путем подгрузки небольших дополняющих скриптов (дефейсов). Чтобы лучше понять, что из себя представляет дефейс рекомендую еще раз перечитать пост <a href="http://www.codeart.ru/2012/04/02/konkurs-3000-rublej-za-luchshij-defejs/">про конкурс на лучший дефейс</a>. </p>
<p>В виду того, что дефейсы - это обычные JavaScript программы, то они работают на стороне клиента и для того чтобы они могли обрабатывать данные, размещенные на сервере, им нужен миханизм доступа к этим самым данным. Нетрудно догадаться, что одним из вариантов серверного хранилища может быть очередь. </p>
<p>В общем, готовая очередь сообщений, с продуманным интерфейсом и возможностью терпеть большие нагрузки мне бы очень пригодилась. Поэтому не удивительно, что первым делом я начал свои эксперементы с Amazon SQS. </p>
<p>Что здесь хочется отметить. Практически для всех популярных языков (включая Erlang) существуют библиотеки, которые позволяют работать с Amazon SQS. </p>
<p>Для работы необходимо иметь Public и Private Secure Keys, а так же знать ункальный URL для доступа к очереди. Фактически чтение и запись в очередь может быть выполена из любой точки  сети Интерент. Но внешний трафик стоит денег, в отличии от  сайтов, размещенных в облаке. Последним досутп к очереди будет бесплатным (при условии что они находятся в одном датацентре с очередью сообщений). </p>
<p>Сами данные могут размещаться как с помощью Get, так и с помощью Post запросов. Ответ будет оформлен в виде XML документа, в котором будет содержаться информация о результатах выполнения заданной операции. </p>
<p>В принципе можно работать с содержимым очереди с помощью JavaScript. Но здесь есть одна проблема - ограничения безопасности самого браузера. Если очередь размещена в рамках того же домена, что и сайт на котором запущен JavaScript, то нет никаких проблем с использованием XMLHttpRequest. Мы просто отправляем Ajax запросы и получаем необходимые ответы.</p>
<p>Все портится когда мы выходим за рамки одного и того же домена. Здесь пока остается только один вариант взаимодейтсвия - JSONP. Т.е. ответ сервера должен быть оформлен в JSON формате, да еще быть обернутым с помощью callback функции. А как раз такого варианта Amazon SQS не предлагает. Поэтому использование очереди для кроссдоменного взаимодействия невозможен. </p>
<p>Еще одна особенность - это необходимость иметь свой публичный и секретный ключ, который есть только у пользователей Amazon. Т.е. писать в очередь могут только пользователи сервисов от Amazon. Правда, тут есть возможность настроить анонимный доступ, но я им не пользовался пока и на сколько там все гладко сказать не могу.</p>
<p>С библиотеками тоже не все так просто, есть официальные библиотеки, которые работают без нареканий, но количество языков весьма ограничено - Java, PHP, Ruby. А есть библиотеки неофициальные, которые поддерживаются сообществом неравнадушных людей. Естественно, что никто не гарантирует работоспособность последних. </p>
<p>Для Erlang я нашел библиотеку, которая уже давно не поддерживается и для того, чтобы начать с ней работу пришлось немного допилить код. Но в любом случае подправить код лучше, чем писать его с нуля.</p>
<p>В целом сервис хороший. Имеет удобные средства управления: позволяет управлять правами доступа к очереди, просматривать сообщения, удалять и добавлять очереди и т.д. Потенциально имеет устойчивость к высоким нагрузкам (проверить, естественно, не могу). Так же есть неплохая документация.</p>
<p>Но есть один большой недостаток, который для меня имеет решающее значение. Как я уже говорил - нельзя обращаться к очереди из браузера средствами JavaScript. Здесь, возможно, решением будет создание небольшого прокси-скрипта, который будет размещаться на моем сервере и с одной стороны получать JSONP запросы, а с другой обращаться к очереди, конвертируя результат в нужный формат. Но мне кажется, что уж проще сделать свой собственный простенький сервис сообщений, чем городить такой огород.</p>
<img src="http://feeds.feedburner.com/~r/codeart/~4/xU7lJD46bhc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeart.ru/2012/04/27/vpechateleniya-ot-amazon-simple-queue-service-sqs/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ubuntu instance на Amazon EC2 или как можно выкинуть 350$ на ветер</title>
		<link>http://www.codeart.ru/2012/04/24/ubuntu-instance-na-amazon-ec2-ili-kak-mozhno-vykinut-350-na-veter/</link>
		<comments>http://www.codeart.ru/2012/04/24/ubuntu-instance-na-amazon-ec2-ili-kak-mozhno-vykinut-350-na-veter/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 13:31:34 +0000</pubDate>
		<dc:creator>Evgeny Sergeev</dc:creator>
		
		<category><![CDATA[Офтопик]]></category>

		<guid isPermaLink="false">http://www.codeart.ru/?p=1581</guid>
		<description><![CDATA[Уже писал про то, что хочу поиграться с Amazon Elastic Cloud. Сегодня, наконец-то, дошли руки до того чтобы создать свой инстанс. Так как за день набегался, то пошел простым путем - запустил на YouTube ролик  по запуску Ubuntu Instance и тупо выполнил все шаги. В процессе установки затупил и в итоге потерял 350$. Сейчас [...]]]></description>
			<content:encoded><![CDATA[<p>Уже писал про то, что хочу поиграться с Amazon Elastic Cloud. Сегодня, наконец-то, дошли руки до того чтобы создать свой инстанс. Так как за день набегался, то пошел простым путем - запустил на YouTube ролик  по запуску Ubuntu Instance и тупо выполнил все шаги. В процессе установки затупил и в итоге потерял 350$. Сейчас расскажу как все получилось.<br />
<span id="more-1581"></span><br />
Ситуация следующая, при создании инстанса на EC2 можно выбрать готовый образ, который называется Amazon Machine Image (AMIs). Я наивно полагал, что это просто некий образ готовой гостевой системы. Но на самом деле в AMI может входить не только образ системы, но и некоторые дополнительные вещи. Например, Premium Support, которая в зависимости от тарифва (Bronze, Silver, Gold и т.д.) может стоить разных денег. Думаю, что вам не составит труда догадатсья, что, как самый последний лох на этой планете, я купил почти самую дорогую Silver поддержку, которая стоит 350$. Нет, я не жалуюсь, ведь все могло быть хуже - я мог купить  Gold поддержку, которая еще дороже! </p>
<p>Не буду кривить душой и говорить, что во всем виноват буржуи, помешанные на прибыли. На самом деле, система меня мило предупредила, что у меня нет подписик на Premium Support и предложила перейти на страницу, где я смогу подключить данную услугу. В принципе, там было все подробно расписано, правда на буржуйском языке, но это сути дела не меняет. Так как я немного устал за день, то как-то сразу не сообразил, что за Premium Support я приобретаю. В итоге, подтвердив свое желание (о котором я даже не знал), я тут же получил СМС от банка, в котором говорилось что с моего счета списана определенная сумма денег&#8230; Всего-то навсего 350 баксов. В пересчете на русские деньги, естественно. После этого усталость сняло как рукой. Я еще раз внимательно прочитал, что именно подключаю и как-то сразу обратил внимание на то, что услуга Premium Support далеко не бесплатная. Но было уже поздно.</p>
<p>Одно радует, что у меня подключен SMS банкинг и я сразу узнал, что у меня сняли деньги с карты. А так бы мог и не заметить, что ежемесяно теряю кругленькую сумму на услугу, которая мне нафиг сейчас не нужна. <img src='http://www.codeart.ru/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Будьте внимательны и не повторяйте моих ошибок.</p>
<img src="http://feeds.feedburner.com/~r/codeart/~4/33WK-9QfXxs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codeart.ru/2012/04/24/ubuntu-instance-na-amazon-ec2-ili-kak-mozhno-vykinut-350-na-veter/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

