ニフクラ ブログ

ニフクラやクラウドの技術について、エンジニアが語るブログです。

できる!ソーシャルアプリ(2) 「開発環境の充実はとっても嬉しいなって」

こんにちは、株式会社エクストーンの仲山です。
この連載では、ソーシャルアプリの企画から公開、運用までを通したTIPSを紹介します。

前回の記事では、 企画・設計段階として以下について紹介しました。

ソーシャルアプリの特徴

・リリース直後にアクセスが殺到する。
・SNSサイトのサーバを経由したアクセスがあり、タイムアウト制限が厳しい。
・一人あたりのPVが多いうえ、アクセスごとに処理結果を保存しなくてはいけない。

企画・設計段階での想定事項

・企画として想定するアクセス量からピーク時の秒間PVを算出し、サーバ性能の目標値とする。
・システムを構成する各サーバごとに、性能目標を試算する。
・アプリがヒットしすぎた場合の対策を考えておく。
・アプリがヒットしなかった場合の対策を考えておく。

今回は、少人数開発であることが多いソーシャルアプリの開発において、 個人別・用途別の開発環境を簡単に用意したり、 本番環境への移行をスムーズに行うための開発段階についてのTIPSとして、 ApacheのVirtualDocumentRoot機能と、システム管理ツールChefを紹介します。

少人数チームでのアプリ開発

とにかく動きの早いソーシャルアプリ業界では、企画から公開開始までが2ヶ月~3ヶ月程度で、 さらにアプリを公開した後も、飽きっぽいユーザに対して積極的に働きかけるため、 2週間~1ヶ月ごとにゲーム内企画を次々と投入する、というやり方が一般的です。

小回りのきく数人の小さなチームで開発を行う事が多く、 SubversionやGit等でブランチを活用し、 大規模な追加機能と細かい修正など複数の作業を並行で進めながら、 短い時間での開発サイクルを回すことになります。 そのため、複数の開発環境を柔軟にかつ、手間を掛けずに準備することが課題となります。

前回の記事で書いたとおり、ソーシャルアプリではSNSサイトが携帯電話とアプリサーバの間に入り、 SNSサイトのヘッダやフッタ等を付けて中継を行うようになっているため、 テスト段階からもSNSサイト、つまり社外のサーバから開発環境のサーバにアクセスができる必要があります。 開発用PCや社内ネットワークで行っているのと違い、それなりにセキュリティ等を含めて環境を整備しなくてはなりません。

複数の開発環境を用意したり、開発環境ごとのソフトウェア構成や設定を手っ取り早く準備するため、 Apacheを利用している場合に利用できるVirtualDocumentRootと、 サーバ環境を容易に同期できるシステム管理ツールChefを取り上げます。

ApacheのVirtualDocumentRoot

1台の開発用サーバ上で複数の開発環境を用意するには、 HTTPのバーチャルホストを利用するのが一般的です。 素直に設定するのであれば、ブランチ別にApacheのバーチャルホストの記述を増やしていくことになりますが、 「VirtualDocumentRoot」 を利用することで、その作業を大幅に軽減することができます。

ここでは、サーバが存在するIPアドレスを192.0.2.100、 バーチャルホストを設定するためのサブドメインを appdev.example.jp とします。 まず、DNSの example.jp のゾーンファイルに以下のように設定します。

*.appdev        IN A 192.0.2.100

続いて、Apacheには以下のようなバーチャルホスト設定を行います。

<VirtualHost *:80>
  ServerName appdev.example.jp
  ServerAlias *.appdev.example.jp
  VirtualDocumentRoot /home/appdev/%1/public_html
  CustomLog /var/log/apache2/access.log combined
</VirtualHost>

これで、ブラウザで「http://branch1.appdev.example.jp/index.html」を開くと、 サーバ上の /home/appdev/branch1/public_html がドキュメントルートとなり、 その下にある  /home/appdev/branch1/public_html/index.html が表示されます。 また、「http://branch2.appdev.example.jp/demo.php」であれば、 同じように /home/appdev/branch2/public_html/demo.php が表示されます。

この手法であれば、並行して開発が必要になった場合に、 別のディレクトリにソースコードを展開するだけで、DNSやApacheの設定変更無しで、 すぐに開発を行うことができます。 あるいは、ちょっとだけ違う複数のデザインを並べて比較したい、 といった企画側からの要望にもすぐ答えられるようになります。

このような、開発側と企画側で柔軟にやりとりをしながら開発を進められる環境が、 ソーシャルアプリのような開発では重要となります。

Chefを利用した開発環境の整備

開発が進んでくると、 負荷試験など共有の開発環境では無く別のサーバ上に開発環境をすぐ作りたい、 という場合が出てきます。 一般的には、サーバの構築用のシェルスクリプト等をあらかじめ用意しておき、 新しく追加したサーバ上でスクリプトを実行して環境をそろえたりします。

でも、あくまで開発中なので、 サーバ側に必要なライブラリが追加になったり、 PHPなどのサーバ設定ファイルが変更になったり、 あるいは不要なライブラリが見つかり削除が必要になったり、 そういったイレギュラーな構成変更が発生します。 用意したばっかりの空っぽのサーバ上のための環境構築スクリプトを作るのは簡単ですが、 既に稼働中のサーバの環境をそろえるのは、一気に面倒になります。

そこで、システム管理ツールの出番となります。 あらかじめサーバ上に必要なソフトウェアやその設定内容を「サーバのあるべき状態」として登録しておくことで、 システム管理ツールを動かしているサーバの環境を自動でそろえることができます。

実績の多いPuppetを使うことが多いのですが、 最近注目を集めているChefを使ってみます。 CentOS5上にChef環境を用意するためのYumレポジトリを用意したので、 それを使って手っ取り早く試してみます。

Chefクライアント環境のインストール

Chefは本来、集中管理するサーバを設置して運用するものですが、 chef-soloというChefに含まれるコマンドを利用することで、 サーバ無しで1台だけで試してみることができます。 このchef-soloを動かすため、まずはChefのクライアント環境をインストールします。

ニフティクラウドで適当にVMを作り、rootで接続したところで、以下のコマンドを実行します。
ただし、今回は64ビット版のみしかYumレポジトリを用意していないため、OSはCentOS 5.3 64bit Plainを選択してください。

[root@localhost ~]# rpm -ivh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm http://download.elff.bravenet.com/5/i386/elff-release-5-3.noarch.rpm (太字の部分を入力)
(表示内容は省略、以下も同様) [root@localhost ~]# wget -O/etc/yum.repos.d/xtonechef.repo http://yum.xtone.co.jp/chef/xtonechef.repo [root@localhost ~]# yum install -y chef rubygem-mysql

これで、chef-soloを含めたChefクライアントがインストールされました。

[注意事項]
今回利用している「xtonechef」のYumレポジトリは、ELFFのレポジトリを元に、 Chef本体や依存するライブラリのバージョンアップを行ったものを今回の記事用に公開しています。 定常的に提供しているものでは無いため、今後のバージョンアップが反映されない場合がありますのでご注意ください。 また、CentOS 5 (x86_64) のみの対応となります。

クックブックのダウンロード

ApacheやPHP、iptablesなどを具体的に設定するための方法を記した手順書を、Chefではレシピ(recipe)と呼び、 このレシピを集めたものをクックブック(cookbook)と呼んでいます。 実際には、クックブックに含まれるレシピをカスタマイズして利用することになりますが、 今回はChefの開発元が公開しているクックブックに、 ニフティクラウド環境向けの設定を含めたものを用意したので、それを利用します。 なお、クックブックをGithub上で管理しているため、Gitも併せてインストールします。

[root@localhost ~]# yum install -y git-core

[root@localhost ~]# mkdir -p /var/lib/chef

[root@localhost ~]# git clone https://github.com/nekoruri/cookbooks.git /var/lib/chef/cookbooks

これで、/var/lib/chef/cookbooks 以下にクックブックが保存されたので、 ここに含まれるレシピを利用してサーバを設定することができます。

サーバ環境の設定

それでは、実際にchef-soloを使ってサーバの環境を一気に設定してみます。
以下の内容を、node.jsonとして保存してください。

{
  "mysql":{
    "server_root_password":"PASSWORD"
  },
  "run_list": [
    "recipe[apache2]",
    "recipe[php]",
    "recipe[php::module_apc]",
    "recipe[php::module_mysql]",
    "recipe[php::module_curl]",
    "recipe[php]",
    "recipe[zsh]",
    "recipe[mysql::server]",
    "recipe[iptables]"
  ]
}

このファイルがchef-soloを実行するサーバの属性(attributes)で、 どのレシピを適用するかと、レシピに渡す情報(この例ではMySQLサーバのroot password)を記述します。 保存できたら、chef-solo を実行します。
実際の作業内容がずらずらと表示されます。

[root@localhost ~]# chef-solo -j node.json

ここまでで、先ほどの node.json に書いた、Apache2、PHP、MySQLサーバと言ったものが一通りインストールされ、 iptables のファイアウォールもSSHとHTTPを開けた状態で設定されます。

[root@localhost ~]# echo '<?php phpinfo();' > /var/www/info.php

などとして、ブラウザで http://(IPアドレス)/info.php を開くと、phpinfoの結果が表示されますので、 APCやmysql等のPHP拡張もちゃんと有効になっていることが確認できます。
(安全のため、info.php は確認後に削除するのをおすすめします)

試しに、PHPのmysql拡張を一旦アンインストールして、もう一度chef-soloを実行してみます。

[root@localhost ~]# rpm -e php-mysql

[root@localhost ~]# chef-solo -j node.json
(省略)
[Wed, 20 Apr 2011 20:17:20 +0900] INFO: Upgrading package[php-mysql] version from uninstalled to 5.1.6-27.el5_5.3
(省略)

先ほどアンインストールした php-mysql パッケージが再びインストールされました。
このように、chef-soloを実行する度に、サーバの「そうあるべき状態」を維持するために必要な設定やパッケージのインストール等が自動で行われます。

管理ツールによる文書化・標準化

開発中に必要になったライブラリや設定ファイルを、 全サーバに適用する手間を省くためにレシピやサーバの属性に反映させていくと、 「サーバのあるべき状態」が常にChefの設定として残ることになります。 いざ必要になってからサーバ設定を文書化するのは面倒ですが、 普段から、手抜きのためにしていることが、そのまま文書化につながるというメリットが出てきます。

また、サーバ毎のものでは無い部分はレシピとして使い回すことができるため、 どのようにサーバを設定するのか、今どうしてそういう設定になっているのか、 という属人性が強い部分を履歴を含めて標準化するもできます。 その結果、人が行っていればどうしても発生してしまう誤設定を、限りなく減らすことにもつながります。

このサーバなどのインフラストラクチャの構成をスクリプトや設定ファイル(コード)として実現する考え方は、 「Infrastructure as code」と呼ばれています。 ニフティクラウドのようにAPIを提供するクラウド環境が登場したため、 サーバの手配からアプリケーションの配布まで、 アプリを提供するために必要な全ての情報ををコードとして表現することができるようになりました。 最終的には、技術者が直接サーバに何か作業を行うことは無くなっていくと考えています。

関連情報

Chef公式サイト
Chef-Solo で PHP をインストールしてみた - miauの避難所
Mwrc2011 cookbook design patterns Chef開発者による紹介スライド
オープンソースなシステム自動管理ツール Puppet:第1回 システム自動管理ツールの必要性とPuppetの概要|gihyo.jp … 技術評論社
さようならPuppet、こんにちはChef - Masatomo Nakano Blog

次回予告

Chefの紹介が長くなってしまったため、 JMeterを用いた負荷試験については次回の記事に分割します。
第3話「もう負荷も恐くない」までもうちょっとだけお待ちください。