Browse Month: February 2009

monit tips -httpd-

monit を使って、httpd (Apache HTTP Server) のプロセスが落ちたときに自動的に再起動するようにしている。まれに httpd が落ちるときがあって、monit が httpd を再起動しようとしたとき次のようなログがでていてうまく再起動できない現状に遭遇した。

[JST Feb 10 01:13:59] error    : ‘httpd’ failed to start
[JST Feb 10 01:13:59] info     : ‘httpd’ trying to restart
[JST Feb 10 01:13:59] info     : ‘httpd’ start: /etc/init.d/httpd
[JST Feb 10 01:14:59] error    : ‘httpd’ process is not running
[JST Feb 10 01:14:59] info     : ‘httpd’ trying to restart
[JST Feb 10 01:14:59] info     : ‘httpd’ start: /etc/init.d/httpd
[JST Feb 10 01:14:59] error    : ‘httpd’ failed to start

 

よくよく調べてみると、一度 monit から httpd を起動したとき /var/lock/subsys/httpd ファイルや /var/run/httpd.pid ファイルが生成されない状態になって、monit が /var/run/httpd.pid がないので httpd が動いているのにも関わらず httpd を起動し続けていたことが原因。

/etc/init.d/httpd を修正しようと思ったが、monit の設定ファイルを次のように書き換えて対応したら、今のところは問題がない様子。

変更前

check process httpd with pidfile /var/run/httpd.pid
      start program = “/sbin/service httpd start”
      stop program = “/sbin/service httpd stop”
      if failed host localhost port 80 protocol http
         and request “/healthcheck/heartbeat”
         for 3 cycles then restart

変更後

check process httpd with pidfile /var/run/httpd.pid
start program = “/sbin/service httpd restart”
stop program = “/sbin/service httpd stop”
if failed host localhost port 80 protocol http
  and request “/healthcheck/heartbeat”
  for 3 cycles then restart
 

さて、次は httpd が落ちる原因を調査して対策することにしよう。

wordpress プラグイン開発方法

まず、仕組みから簡単に説明すると、wordpress(wordpress mu も含む) は所々でフックを設定できるようになっています。例えば、エントリをした直後とか、ページに header タグを出力する直前など、たくさんのところでフックを設定することができます。プラグインは、このフックに登録して何らかの処理を実行するように開発していきます。

フックできる箇所の一覧は、Plugin API/Action ReferenceWordPress Hooksにまとまっています。 また、データベースに接続するときにもフックすることができます。一覧は、WordPress hools database にあります。日本語の解説もありますね。

プラグインは、必ず PHP で次のようなヘッダコメントを入れなければならない。

<?php/*

Plugin Name: Name Of The Plugin

Plugin URI: http://URI_Of_Page_Describing_Plugin_and_Updates

Description: A brief description of the plugin.

Version: The plugin's Version Number, e.g.: 1.0

Author: Name Of The Plugin Author

Author URI: http://URI_Of_The_Plugin_Author

*/

?>

次に、フックに登録するには、次のようになる。次の例は、管理ページのフッター部分が呼ばれるときのフックに登録する方法です。フッター部分が呼ばれたとき、hoge 関数が呼ばれるという意味です。

add_action(‘admin_footer’, ‘hoge’);

あとは、hoge 関数の中にプラグインでやりたい処理を書いていくわけだが、wordpress にはすでに組み込まれている関数群がある。この関数群の一覧は、Function Reference にまとまっていますので、この関数を使うと便利です。また、wordpress のソースコードを見ると分かりますが、global を使いまくりなので global 変数にアクセスすることもできます。つまり、何でもできるということになります。

例えば、wordpress で今開いているページの URI を知りたいときは、次のようになります。

global $pagenow;

echo $pagenow;

使われている global 変数は資料を探すよりもソースコードを grep した方が早いです。

自作プログラムをデーモンにする

自作のシェルスクリプトをデーモンにするプログラムに、start-stop-daemon というものがあるみたいです。しかし、これは CentOS では提供されていないので、何かいいのがないかなと思って調べてみたところ、start-stop-daemon を C 言語で実装し直したバージョンがあることが分かった。

さっそくインストールしてみた。

  1. プログラムを展開する
  2. gcc start-stop-daemon.c -o start-stop-daeemon してコンパイルするだけ

本番サーバに展開したかったので、RPM を作った。SPEC は start-stop-daemon,spec においておいた。

start-stop-daemon をインストールしたら、TokuLog にあるような簡単に sysinit スクリプトを書くだけでデーモンにできる。

これは、便利だわ。

yum-security

yum-security という、セキュリティアップデートのみチェックしてくれる yum のプラグインがあるというので、さっそく試してみた。

まずは、インストールしてみる。

$ sudo yum install yum-security

さっそく使ってみる。

$ sudo yum –security check-update

usage: yum [options] < grouplist, localinstall, groupinfo, localupdate, resolvedep, erase, deplist, groupremove, makecache, upgrade, provides, shell, install, whatprovides, groupinstall, update, repolist, groupupdate, info, search, check-update, list, remove, clean, grouperase >

Command line error: no such option: –security

なぜか、動かない。。。

yum の設定ファイルまわりを見直してみると、/etc/yum.conf と /etc/yum/yum.conf という二つのファイルがなぜか存在していて、/etc/yum/yum.conf の方にはプラグインを有効にする設定 「plugins=1」という設定がなかったため、プラグインが有効になっていなかった。

そこで、/etc/yum/yum.conf を削除して、もう一度試してみる。

$ sudo yum –security check-update
Loading “fastestmirror” plugin
Loading “security” plugin
Loading mirror speeds from cached hostfile
 * centos5-x86_64-extras: repos
 * centos5-x86_64-origs: repos
 * centos5-x86_64-updates: repos
 * centos5-x86_64-addons: repos
 * centos5-x86_64-base: repos
centos5-x86_64-extras     100% |=========================|  951 B    00:00     
centos5-x86_64-origs      100% |=========================|  951 B    00:00     
centos5-x86_64-updates    100% |=========================|  951 B    00:00     
centos5-x86_64-addons     100% |=========================|  951 B    00:00     
centos5-x86_64-base       100% |=========================|  951 B    00:00     
Excluding Packages from centos5-x86_64-updates
Finished
Excluding Packages from centos5-x86_64-base
Finished
Limiting package lists to security relevant ones
No packages needed, for security, 11 available

ちゃんと動いている様子。どうやら、puppet で間違えて /etc/yum/yum.conf に配置してしまったらしい。。。このことから /etc/yum/yum.conf の方が /etc/yum.conf よりも優先的に読み込まれる仕様になっていることが分かった。

yum-security のさらに詳しい使い方は、Red Hat Magazine に書かれている。CVE とかでも見れるので、これはかなり便利なツールだと思う。

yum-security をインストールすると、/etc/yum/pluginconf.d/security.conf というファイルがインストールされる仕組みになっている。

毎日チェックしてくれるように yum –security check-update の内容を logwatch に入れてみることにしようと思ったけれど logwatch はその名前のとおりログファイルをチェックしてメールで送るツールなので用途が違うことに気がついた。ちなみに、yum.log からインストールしたパッケージの情報を logwatch で送る方法は、このあたりに紹介されている。

yes コマンド

yes コマンドという、とても便利なコマンドがある。yes コマンドは、ハイプ経由することで  y の入力をハイプ経由のコマンドへ渡して自動的に入力してくれる。

例えば、次のような感じで使う。

$ yes | sudo yum install hogehoge

こうすると hogehoge パッケージを確認プロンプトなしでインストールしてくれる。yum コマンドには、-y オプションがあるので普通はこの使い方はしない。

yes コマンドは、てっきり y だけかと思ったいたが、man してみるとどうやら任意の文字列も渡せるようだ。

次のような感じでも使える。

$ yes “hogehoge” | command

こうすると、command というコマンドへ hogehoge という入力を渡してくれる。これは、便利なコマンドだ。

「クックパッド」の裏側にいってきた

Web デベロッパーの祭典に行ってきた。今回は、通路沸きに用意された比較的狭いスペースで開催された。

以下、メモと自分の勝手な感想をまとめておく。

クックパッドについて

  • 毎日の料理を楽しみにすることで心からの笑顔を増やす
  • 1998年にオープン
  • 去年のリニューアルのときに Rails で作り直した

使い方

  • レシピをのせる
  • レシピをさがす
サイトの規模感
  • 月間ユーザ数 547万人
  • Rails サイト中世界7位 (from rails 100 wiki)、まさか1位がscribd.comとは
  • 月間 2.8億 PV(PVでは、Rais サイト中世界3位)
  • 登録レシピ数: 47万品
  • トラフィックは、16-18時くらいがピーク(夕飯を作る前に調べるユーザが多いとのこと)
  • 秋からバレンタインにかけてトラフィックが伸びる(来週はピークだということで、最近はパフォーマンス向上に中心にやっていた)
  • ユーザ数: 547万人(すごい。。。)

インフラまわり

  • ロードバランサー、アプリケーション、データベースの、よくある3層構造
  • サーバ台数: ロードバランサー x 8, アプリケーション x 52, スレーブデータベース x 18, マスターデータ, 監視, ログなど
  • ロードバランサー: Apache 2.2.3 mod_proxy_balancer(2.2.3 ということは CentOS 5系なのかもしれない、この規模で mod_proxy_balancer か…)
  • アプリケーションサーバ: Ruby on Rails 2.0, mongrel 1.1.5 / mongrel_cluster 1.0.5(もちろん、複数プロセスで起動しているとのこt)
  • データベース: MySQL 5.0.45
  • Tritonn(全文検索用に使っているとのこと、かなりお気に入りらしい)
  • デプロイツール: capistrano(当然ですな)
  • god(mongrel でメモリリリークしたときに自動的に再起動するツール、like monit だが設定ファイルは Ruby で書けるツール、個人的には monit で統一しているが Rails ならこっちのほうがいいかもしれない)
  • 監視ツール: nagios(当然ですな)
  • モニタリング: munin(めずらしい)
  • パフォーマンス計測ツール: FiveRuns Manage(ページを表示するとさまざまなパフォーマンス測定をしてくれるツールらしい、初めて知った)

キャッシュ、クエリーチューニング

  • ページキャッシュしたデータを NFS に保存して、Apache から直接返している
  • フラグメンテーションキャッシュには、memcached を使っている
  • ユーザ毎に異なる表示をしているところや、アクセスログの統計、広告の挿入は、Ajax の1ページ1回のリクエストでまとめて行っている
  • クエリーチューニングには、FiveRuns TuneUp や MySQL のスロークエリーログを見ながら行っている
  • DBとメモリの関係で、リニューアル直後のDB構成は アプリケーション x 2GB、アプリケーション x 2GB, スレーブデータベース x 8GB、検索データベース x 4GBという仮想マシン構成だったがパフォーマンスがでないため、アプリケーション x 2GB, アプリケーション x 2GB, スレーブ + 検索データベース x 12GBに変更した、原因はメモリサイズ以上のデータベースサイズになっていたため
  • さらにデータベースサイズが大きくなると、物理メモリを増やして、物理メモリを増やせないときはテーブル分割を考えているとのこと

Rails での開発ノウハウ

  • プログラマーは、全員マックを使用してノウハウを共有してやすくしている(これはすごい、自分が好きな道具は使えないということか)
  • Emacsrails.el がデフォルトの開発環境とのこと(素晴らしすぎる!!!)
  • Subversiontrac
  • Redmine を最近から使っているとのこと
  • Shinjiko を使っている(Mondrian クローンコードレビューツール)
  • DBのレプリケーションを扱うため、マスターとスレーブの切替えとして acts_as_readonlyable を使用している
  • レシピの全文検索には、Tritonn を使用している
  • Tritonn のいいところは、MySQLを拡張しているのでテーブルをジョインできること、2インデックスを使える(通常の MySQL では1インデックス)。インデックスを張ったテーブルのファイルをそのままコピーできる(インデックスの作成時間を減らす)
  • 一部のユーザは自分専用のURLをもつため、routes.rb で全てのコントローラ名を検索して一致しない場合には専用のコントローラに渡している
  • 全ページのプレビュー機能(すべてのページで、任意の日付を指定してプレビューできる)は、 Time.nowを上書きして実現している、アクセス制限もつけている

クックパッドのものづくり

  • つくるものを決める
  • Best なことに集中する(やりたい(情熱を持ってとりくめること)、できる(世界で一番になれる)、やべるき(儲かること)、Better なことはやらない Best しかやらない)
  • ユーザの欲求に基づいた機能
  • EOGS(Emotion Oriented Goal Setting)
  • そのサービスに関わるキャストを立てる
  • キャスト毎の疑いようのない欲求を考える
  • 計画する
  • スケジュールの3分割の法則: 設計、開発、質を高める、という三つの工程にわける
  • クックパッドものづくり三原則
  • 無言実行: 公開前にサービスについての説明をしない
  • サービスを言葉で説明することができない
  • 公開前に事前告知しない(リニューアルときも事前告知しなかったとのこと、事前告知するメリットはあまりないとのこと)
  • 無言語化: 機能を言葉で説明しない
  • 一瞬で理解できるインタフェースじゃないと使われない、最大2秒以上理解するのにかかる機能はユーザは使ってくれない
  • ヘルプや FAQ を読ませるのはユーザに負担を強いるし、そもそも読まれない(ヘルプや FAQ を用意すればいいという考え方はよくないとのこと)
  • サービスに値段をつける: どんなサービスでも幾らかの価値があるか値段をつけて考える、無料だから大丈夫という考えでは負ける、ウェブ以外のサービスやモノは価値にたいして値段が付いている
  • クックパッドは当初有料だったが、時期的に早すぎたので無料にしたのこと
  • 設計する

サイトの設計の順番

設計に最低限必要なもの

ユーザに届けるべきもの

遷移、ページ詳細、DB構造、サイトマップ、が最低限必要なドキュメント

  • 開発する

Railsに乗る

リファクタリングし続けられる状態を保つ(いわゆるアジャイルな開発環境)

DRY(Don’t repeat yourself), YAGNI(You Aren’t Going to Need It) のバランスを意識する

 

 

  • 質を高める

ユーザに狙った価値を提供できているのかテストするためのもの

ユーザテストのときには質問には答えない、質問が出るインターフェースは失敗

顔マーケティング

ライバルに勝てる「ウリ」

エンジニア紹介

クックパッド開発者ブログがある。

 

このイベントは、当初満席だったのでキャンセル待ちで連絡しておいてよかった。インフラまわりの新しいツールも知ることができたし、クックパッドのものづくりに対する姿勢はとても勉強になった。そこには、一般ユーザ向けのサービスを作るための重要な施策がいくつもあった。

前の仕事では、初めて一般ユーザ向けのシステム開発を担当していたけれど、ヘルプや FAQ を用意すればいいと思ったことがあったことのが恥ずかしいと振り返りました。

ウェブサービスは無料なものがほとんどだけれど、無料だから使われるという考え方はよくないと言われたときにドキっとした。お金を払ってもいい価値があるサービスが成功するのだと感じた。

 

とても有意義な講演でありました。

今年参加したいカンファレンスなど

今年はあまり引きこもっていないので、いろいろなカンファレンスに参加したいと思う。もちろん、参加料がある場合はすべて自費、当然だ。

  • PacSec: 例年だと 7 月ころから格安で事前登録できる
  • InternetWeek: 例年だと 11 月ころに開催される
  • SecuritySolution: 2009/9/1 から 2009/9/2 開催予定
  • AVTOKYO: 今年も開催されるといいなぁ
  • Black Hat: PacSec と時期が近いかもしれない
  • Tokyo 2.0: かなり頻繁に開催されているので要チェック

Velocity 2009

インフラまわりのカンファレンス、Velocity は今年も開催される予定です。このカンファレンスは、昨年から始まったけれど、今年は行くかもしれません!


Velocity, the Web Performance and Operations Conference 2009

mod_log_rotate のススメ

Apache HTTP Server で、logrotate したくないとき、CustomLog や ErrorLog を日付別に出したい。調べてみると、次の二つのがメジャーのようだ。

どちらもパイプ経由でアクセスの多いサーバだと重いかなと懸念していたんだけれど、開発を依託している技術者から mod_log_rotate という Apache モジュールがあることを教えてもらった。
さっそく、Apache HTTP Server 2.2.11 で試していた。
インストールは、wiki にあるとおり、次のコマンドを実行するだけ
$ sudo apx -i -a -c mod_log_rotate.c
続いて、次のように設定する。
LoadModule log_rotate_module modules/mod_log_rotate.so
RotateLogs On
RotateLogsLocalTime On
RotateLogsLocalTime On がないと、ログのファイル名の日時が UTC になるので注意。あとは、CustomLog に次のような設定する。
 CustomLog “/var/log/httpd/access_log.%Y%m%d” combined
このように設定すると、/var/log/httpd/access_log.YYYYMMDD というファイル名になる。ErrorLog は、Apache の仕様でハンドリングできないということで ErrorLog の方は出力されないのが普通なので cronolog を使うことにした。rotatelogs は、ある時間ごとにアクセスログを切替える機能なのでアクセスログに日付をつけたいときは使えない。
mod_log_rotate も、本番に投入するため RPM にした。SPEC ファイルは、このあたりのをカスタマイズして使った。
VirtualHost を使っている場合は、必ず VirtualHost ごとに CustomLog の設定が必要なので要注意。設定しないと、access_log.[UINX タイムスタンプ] でアクセスログが出力されてしまう。
あとは、古いログを cron かなんかで削除してあげればよい。
もちろん、最良なのはアクセスログなど不要な情報は /dev/null にするのが当然だと思う。とはいってもどうしても必要なログはあるわけなので、そういうときは mod_log_rotate を使うのがいい感じ。
今のところ、大きな問題はないけれど0時ちょうどになると、次のようなログが出力されることだ。
[Mon Feb 02 00:00:00 2009] [error] (13)Permission denied: could not open transfe
r log file /dev/null.1233532800.
これは、mod_log_rotate.c を変更すればなおせそうな感じだけれど。今晩、様子をみてみることにする。
ちなみに、mod_log_rotate が組み込まれているときの設定したときは、次のように設定すればよい。
#
# mod_log_rotate
# http://www.hexten.net/wiki/index.php/Mod-log-rotate
#
<IfModule log_rotate_module>
    RotateLogs On
    RotateLogsLocalTime On
</IfModule>
  • 1
  • 2