今年もYAPC::AsiaというPerlカンファレンスのコアスタッフをしていて、システムの担当になりました。
2012年にお手伝いを始めてから、2013年のアプリケーションやシステムを引き継ぎ、2014年もYAPCサイトのシステムの管理保守をさせてもらっています。


そこで、2015年のYAPCでは他の誰かにお願いできるようにYAPCサイトのシステムの概要をざっくり書いておこうと思いました。
これを読んで、Webアプリは難しそうと考えていた人が「ああなんだか自分にもできそうだ」と感じでもらって、
あわよくば来年にはバトンタッチできたら最高です。


経験の浅い新卒2・3年目でもできるので、気合があれば何とかなるんじゃないかな!


Mojoliciousを使ったYAPC Webアプリ


YAPCのシステムは、もちろん Perl で作られています。使用しているWAF(Web Application Framework)は Mojolicious です。
ソースコードはgithubに上がっているので、だれでも閲覧できます。本番環境でのperlのバージョンは 5.16.3 です。


依存モジュールは carton で管理しています。
git clone してきたら、carton install すればOKです。
ディレクトリ構成で特別なのはこの辺です。


gettext/ ... 日英翻訳ファイル置き場 ( Data::Localizeで使用 )
devel/ ... ./devel/server は localサーバを立ち上げ用スクリプト
etc/ ... config.pl は設定ファイル
misc/ ... services/ は daemontools用、DBスキーマは YAPC2014.sql
-> /service/yapcasia2014-app -> misc/services/yapcasia2014-app

local環境でYAPCアプリを立ち上げるには、以下のスクリプトを叩くだけです。
(Mysql と Memcached で怒られたら立ち上げましょう。)


./devel/server

Mojolicious以外の実装箇所


DB, O/R Mapperは、牧さん燻製の WithDBI です。
といってもインタフェースはTengなどの他のO/R Mapperとさほど変わらないのですんなり使えると思います。
返ってくるデータがTeng::Rowのようなオブジェクトではなく、 arrayref や hashref であることが特徴です。


Container は YAPCApp::Container にあります。
Object::Container や、Pickles::Container っぽいですが、use Mooされているのでガラッと印象が変わっています。
Mojoliciousのhelperでも似たようなことができますが、YAPCApp.pmで、


has container => sub { YAPCApp::Container->new };

をして、setup_container メソッド内で


$self->helper(get => sub { $container->get($_[1]) });

とすることで、helperメソッドに登録した get で container にあるインスタンスへアクセスできるようにしています。
デザインパターンでいうとFlyweightパターンですね。


Rendererは Xslate を使っています。YAPCApp.pm の setup_xslate内で


$self->renderer->add_handler( tx => { YAPCApp::Renderer->build( ... ) } )

としているので、templateの拡張子が tx であれば xslate を使っている YAPCApp::Renderer でレンダリングされます。
テンプレートの syntax は TT です。


システム構成、運用、デプロイ


構成 / 運用


DBはMysql、キャッシュはMemcached、HttpdはNginxが使われています。


運用方法は、misc/service 以下のディレクトリを、/service 以下からシンボリックリンクを貼って、
daemontoolsでsupervisorの管理下に置いてデーモン化しています。更に、server_starterで再起動時も安心。


デプロイ


デプロイ方法はいたってシンプルで、 git pull & svc -h で済ませます。
たくさんサーバが有るわけではないですしね。


最近では Capistrano をデプロイツールとして使う話をよく聞きます。自動化することは素晴らしいことです。
なので、込み入ったことをしたり、まとめてたくさん処理する必要が出てきたら導入を検討すればいいかなと思っています。


devサーバが無いので、localで開発→本番デプロイという開発環境だということもシンプルに済ませてる一因かもしれません。


周辺サービスとの連携


Movable Type


YAPCサイトのトップページやNewsページは Movable Type で管理しています。
今年は、頂いたデザインを反映させるところからスタートだったので、 MTの独自タグを知っているとさくさく作業が進みます。


コンテンツは、再構築の際にHTMLを吐いてくれるので、静的ファイルをNginxでそのまま配信できるようにしてあげればOKです。


Facebook, Twitter, Github


ソーシャルアカウントでログインするために利用しています。


Peatix ( チケット販売 / 投票 )


課金は毎年おなじみのPeatixさんのシステムを使っています。
管理画面からチケット販売情報をcsvでダウンロードできるので、自動でfetchしてくるスクリプトを script/ 以下に入れています。


これを使って、各種類のチケットの枚数などを一箇所に集めて可視化したり、個人スポンサーのtwitterID入力の結果一覧を取得するのに役立てています。
有効なチケットの席IDなどもここから取れますね。


有効なチケットの席IDはランダムの英数字8桁で振られていて、これらをYAPCのDBにインポートしてユーザ投票のアクティベートに使っています。
席IDによってチケット種別もわかるので、1日券の場合は参加日のトークにしか投票できないなどの制限をつけています。


管理画面を作っていないので、投票結果は結果発表前に男らしくSQLでえいやと出します。
ステージに立って直接SQL叩くのすごく怖いので今年は管理画面作りたいですね…


HRForecast


HRForecast
チケット枚数や、トークの応募数、メールのお知らせ購読者など、変化量を継続的に記録するためにHRForecastにデータを保存、グラフ化して可視化しています。
これによって、何をしたらどんな効果があったかを、ざっくり仮設と検証を行える環境になりました。
簡単グロースハッキング!