<?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>Groove Labo &#187; capistrano</title>
	<atom:link href="http://labo.opengroove.com/blog/category/tools/capistrano/feed/" rel="self" type="application/rss+xml" />
	<link>http://labo.opengroove.com/blog</link>
	<description>株式会社オープングルーヴの開発者のブログ</description>
	<lastBuildDate>Tue, 28 Sep 2010 06:09:57 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>capistranoで定期処理を管理する</title>
		<link>http://labo.opengroove.com/blog/2008/07/18/capistrano%e3%81%a7%e5%ae%9a%e6%9c%9f%e5%87%a6%e7%90%86%e3%82%92%e7%ae%a1%e7%90%86%e3%81%99%e3%82%8b/</link>
		<comments>http://labo.opengroove.com/blog/2008/07/18/capistrano%e3%81%a7%e5%ae%9a%e6%9c%9f%e5%87%a6%e7%90%86%e3%82%92%e7%ae%a1%e7%90%86%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 08:15:03 +0000</pubDate>
		<dc:creator>sugimoto</dc:creator>
				<category><![CDATA[capistrano]]></category>

		<guid isPermaLink="false">http://labo.opengroove.com/blog/index.php/2008/07/18/capistrano%e3%81%a7%e5%ae%9a%e6%9c%9f%e5%87%a6%e7%90%86%e3%82%92%e7%ae%a1%e7%90%86%e3%81%99%e3%82%8b/</guid>
		<description><![CDATA[ウェブサービスを運営していると必ず、「定期的にやるべきこと」ってありますよね。 古くなったログの処理 負荷のかかる処理をバックグラウンドで定期的に 外部データの取得 たいていの場合、手動でやるわけにはいかないので、シェルスクリプトなんかをcronで実行するわけですが、サービスの拡大に伴って、サーバ数が増えた場合、どうするんでしょう? 全てのサーバーにcronを設定すると、全てのサーバーで同じ設定になっていることを確認しなければなりません。 cronの設定自体を自動化すれば、全てのサーバーで同じ設定になっていることが保証されますが。。。 そんなわけで、Ruby on Rails のdeplyツールとして使われているCapistranoを使って、cronをCapistranoサーバーから一括実行することにしてみました。 以下の手順では、ssh接続などの設定は省いています。 (実はこの設定でかなり苦労したところではありますが。。) 1. Capistranoのインストール gemでインストールします。 > gem install capistrano > cap --version Capistrano v2.4.0 2. capfileの作成 capfile はCapistranoの「レシピ」と呼ばれていて、Capistranoが実行するタスクの内容を記述します。Rubyをベースにした独自言語ですが、Rubyを知っている人にとってはほとんど同じです。 role :app, "app-server1", "app-server2" desc "テスト用のタスク" task "test_for_cron", :roles => :app do run "sh /path/to/cron/script.sh" end 3. cronの設定 cronの設定時には、-f オプションを使って、capfileの場所を明示的に示しましょう。 > crontab -e 0 12 * [...]]]></description>
			<content:encoded><![CDATA[<p>ウェブサービスを運営していると必ず、「定期的にやるべきこと」ってありますよね。</p>

<ul>
<li>古くなったログの処理</li>
<li>負荷のかかる処理をバックグラウンドで定期的に</li>
<li>外部データの取得</li>
</ul>

<p>たいていの場合、手動でやるわけにはいかないので、シェルスクリプトなんかをcronで実行するわけですが、サービスの拡大に伴って、サーバ数が増えた場合、どうするんでしょう?</p>

<p>全てのサーバーにcronを設定すると、全てのサーバーで同じ設定になっていることを確認しなければなりません。
cronの設定自体を自動化すれば、全てのサーバーで同じ設定になっていることが保証されますが。。。</p>

<p>そんなわけで、Ruby on Rails のdeplyツールとして使われているCapistranoを使って、cronをCapistranoサーバーから一括実行することにしてみました。</p>

<p>
以下の手順では、ssh接続などの設定は省いています。<br />
(実はこの設定でかなり苦労したところではありますが。。)
</p>

<h3>1. Capistranoのインストール</h3>

<p>gemでインストールします。</p>

<pre>
> gem install capistrano
> cap --version
Capistrano v2.4.0
</pre>

<h3>2. capfileの作成</h3>

<p>capfile はCapistranoの「レシピ」と呼ばれていて、Capistranoが実行するタスクの内容を記述します。Rubyをベースにした独自言語ですが、Rubyを知っている人にとってはほとんど同じです。</p>

<pre>
role :app, "app-server1", "app-server2"

desc "テスト用のタスク"
task "test_for_cron", :roles => :app do
  run "sh /path/to/cron/script.sh"
end
</pre>

<h3>3. cronの設定</h3>

<p>cronの設定時には、-f オプションを使って、capfileの場所を明示的に示しましょう。</p>

<pre>
> crontab -e
0 12 * * * cap -f /path/to/capfile test_for_cron > /dev/null 2> /var/log/capistrano/error.log
</pre>

<p>12時になったら、2つのアプリケーションサーバー</p>

<ul><li>app-server1</li><li>app-server2</li></ul>

<p>でスクリプト /path/to/cron/script.sh が実行されるようになりました。</p>

<p>なお、/path/to/cron/script.sh は各サーバー内に存在する必要があります。
サーバーが増えたら、role に足すだけで、そのサーバーでも実行されることになります。</p>

<p>ただ実行するだけでは面白くないので、実行したらメールを送ります。</p>

<h3>4. メール送信用タスクの作成</h3>

<p>メールはlocalhost で送りますが、Capistranoっぽく、localhostにリモート接続してみます。
(というか、どこにも接続せずにtaskを実行する方法が分からんだけ？)</p>

<pre>
desc "cronを実行したらメールを送信"
task "send_email", :host => "localhost" do
  fn = "/tmp/filename.txt"
  addresses = "email@address.com"
  time = Time.now.strftime("%Y/%m/%d %H:%M:%S")
  put @result.join("\n"), fn, :mode => 400
  run "mail -s 'cron has done on #{time}' #{addresses} < #{fn}"
  run "rm -f #{fn}"
end
</pre>

<h3>5. cron用のタスクで結果を取得するよう変更</h3>

<p>先ほど作成したタスクを修正して、実行結果をメール送信用タスクに渡せるようにします。</p>

<p>複数のサーバーで実行されることを想定して、結果は配列で渡します。</p>

</pre><pre>
desc "テスト用のタスク"
task "test_for_cron", :roles => :app do
  @result = []
  @result.push capture("sh /path/to/cron/script.sh")
end
</pre>

<h3>6. タスク実行後にメール送信タスクをhookする</h3>

<p>Capistranoには start, finish, before, after などのtriggerがあり、task実行の前後などに特定のタスクを実行することができます。
capflieのtaskの前に以下の設定を追加します。</p>

<pre>
on :finish, :send_email, :except => [:send_email]
</pre>

<p>これで、タスクの実行後に標準出力をメールで送信してくれます。</p>

<h4>参考</h4>

<ul>
<li><a href="http://www.capify.org/" title="Capistranoのページ">Capistranoのページ</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://labo.opengroove.com/blog/2008/07/18/capistrano%e3%81%a7%e5%ae%9a%e6%9c%9f%e5%87%a6%e7%90%86%e3%82%92%e7%ae%a1%e7%90%86%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

