[perl] TwitPepper・Webアプリの中の人(その1)

2010年2 月21日  |  Written by matsumoto  |  under Apache, Perl Yahoo!ブックマークに登録    はてなブックマーク - [perl] TwitPepper・Webアプリの中の人(その1)

こんにちは、松本です。寒い中 いかがお過ごしでしょうか。

1月冒頭に 年始の抱負 を書いた後、忙しさにかまけ、jQueryPHP の新バージョンに心踊らせるのに精一杯で、Corei7の低TDP版 "Corei7-860S" の登場にも気付かず今日気づきました。
ついに Core2 Quad シリーズも世代交代か・・・と考え始めております今日この頃です。

今回弊社のサービス"TwitPepper(ツイットペッパー)"の技術面から見た中身についてご紹介したいと思います。


TwitPepper(ツイットペッパー)とは

TwitPepperとは、Twitterのデザインを外部から簡単に変更できるサービスを提供しているサイトです。

http://twitpepper.jp/ Blogサービスのスキン変更のように、自分もTwitterページをお手軽に色々なデザインに変更することができます。詳しくは TwitPepper内の解説ページ をご覧下さい。

遅ればせながらなのですが、昨年12.21にリリースしまして本年冒頭にプレスリリース、1月末に月間カレンダーシリーズをリリースしまして、好評頂いておりますサービスです。(3月分のカレンダーももうすぐアップされると思います。)

TwitPepperのWebアプリケーション概要

TwittPepperは、いわゆるLAMP構成で構成されています。LAMP構成の詳細は以下になっています。

  • L・・・Linux (CentOS 4 i386)
  • A・・・Apache 2.2 + Apache 1.3
  • M・・・MySQL 5.0
  • P・・・Perl(mod_perl)

それぞれの概要を記述していきます。

L・・・Linux (CentOS 4 i386)

TwittPepperのサーバは、さくらインターネットの専用サーバ を使っています。OSはCentOS4(i386/32bit)を利用しています。現在はまだそれほどのトラフィックが発生していないので、いわゆる10Mスタンダード がデフォルトで付いていますのでそちらを利用しています。
※サーバを借りた時期がやや以前なので、旧ネットワークプランにリンクしています。

さくらさんでは、OSは他にUbuntu、FreeBSDなども選択可能 ですが、弊社では新規のサーバは全てCentOSで統一しています。

また、バージョンは基本5、で i386(32bit)を選択しています。
(今回借りているサーバはやや以前に借りたサーバなので、バージョン4ですが、現在はデフォルトでバージョン5を選択しています。)

搭載するメモリ量について

x86_64(64bit)を選択しない理由は、64bit化するとWebアプリケーションのプロセスサイズが肥大化し、メモリ増強が必要になります。なのですが、さくらさんではメモリが月額料金にのっているため、月々のランニングコストに乗ってしまいます。

ランニングコストの内訳は以下になります。

合計搭載メモリ量 専用サーバのランニングコスト
2G 専用サーバ標準料金のまま
4G(2G+2G) +2,100円/月

弊社ではできるだけランニングコストを抑えたいので、メモリサイズを最小で運用できるi386(32bit)で運用し、まずはデフォルトのメモリ2Gで運用。その後メモリが必要であれば+2G(月額2,100円追加)で最大4G(2G+2G)に拡張し、32bitOSの上限値までメモリを利用できる形で1つのWebアプリケーションを完結させています。

ノウハウ集約のためにOSを統一

もちろん、案件によってはメモリ8Gを必要とするサーバの構築もありますので、そういった場合は x86_84(64bit)のOSを積み、そもそもメモリ4Gの壁が存在しない形にしています。

以前はFreeBSD、RedHatLinux、FedoraCoreが混在していたのですが、CentOS以降は書籍・ネット上の資料がCentOSが一番多いと判断しまして、ノウハウの集約をする為にも、OSは統一しています。

自分は以前からFreeBSDをずっと使ってきていて、慣れている部分も多かったのですが・・・ yumの利便性と、案件によってはJavaが動作する環境が必要だったため、Linuxに移行しました。

関連リンク

A・・・Apache 2.2 + Apache 1.3

WebサーバはApacheを利用しています。こちら、表記が2つあり Apache 2.2 と Apache 1.3 の2つが存在しています。
これは、"リバースプロキシ(Reverse Proxy)" という技術を使ってWebアプリケーションを運用しているため、1つのサーバに2つのWebサーバが混在しているという形になっています。

リバースプロキシ(Reverse Proxy)とは

"リバースプロキシ(Reverse Proxy)" という技術は色々な場面で使われています。
弊社では主に "Webサーバを多段構成にする事で、負荷軽減を狙うための技術" として用いています。
とても簡単な図解なのですが、以下の様に構成しています。

  • リバースプロキシ(Reverse Proxy)の構成例
    http://www.alink.co.jp/images/works/reverse_proxy_sample.gif

Proxy側(フロント)・・・Apache2.2

Proxy側(フロントエンド)は yum 経由でインストールできる、 Apache2.2 を利用しています。 yum が使えない場合はソースコードからApache2.2をインストールします。

  • yum から Apache2.2をインストール

    sudo yum install httpd
  • ソースコードから Apache2.2をインストール
    ./configure --enable-mods-shared=all
    --enable-so
    --enable-proxy
    --enable-proxy-connect
    --enable-proxy-http
    --enable-proxy-balancer
    --enable-ssl
    --enable-dav
    --enable-cache
    --enable-disk-cache
    --enable-mem-cache 
    
    sudo make install

Apache2.2 を利用している理由は、まず Apache2.x 以上のApacheは SSLの扱いが簡単という点と、Apache2.2 以上ではmod_mem_cache / mod_disk_cache と、 mod_proxy_balancer が使える点が大変に大きいです。

この2つが最初から使えることで、後々スケールアウトの必要が出てきた場合も柔軟に対応できます。

※<参考>Apache 2.0 のインストール
何らかの事情でApache 2.2 ではなく、Apache 2.0 をインストールしなければならない場合は以下のように configure のセッティングを行っています。
prefix の指定は、今後Apache2.2がインストールされたとしてもインストールディレクトリ先が重複しないための措置です。

  • Apache 2.0.x 本体のインストール

    ./configure --prefix=/usr/local/apache20
     --enable-mods-shared=all
     --enable-so
     --enable-proxy
     --enable-ssl
     --enable-dav

App(アプリケーション)側・・・Apache1.3

アプリケーション側は Apache1.3を利用しています。
TwitPepperでは mod_perl を利用しています。Apache1.3 のmod_perlを利用するために
必要なミドルウエア、モジュールをソースからインストールします。

  • Apache 1.3 本体のインストール

    ./configure
     --enable-shared=max
     --enable-module=all
     --disable-module=auth_dbm
    
    sudo make install

続いて mod_perl をインストールします。 mod_perl 自体のダウンロードは こちら から行うことができます。
今回はApache1.3用のmod_perlですので、 "For use with Apache 1.3.x " の "Download" のリンク先をダウンロードします。

  • Apache 1.3 に mod_perlをインストール

    wget http://perl.apache.org/dist/mod_perl-1.0-current.tar.gz
    tar xvzf mod_perl-1.0-current.tar.gz
    cd mod_perl-1.31
    
    perl Makefile.PL USE_APXS=1 WITH_APXS=/usr/local/apache/bin/apxs EVERYTHING=1
    
    make install clean

APXSの指定先はApache 1.3をインストールしたディレクトリを指定します。
今回はデフォルトのprefixですので "/usr/local/apche/" 以下の "bin/apxs" になります。

Proxy 側(フロント)側の設定

Proxy(フロント)から、バックエンドのアプリケーションサーバにリクエストを飛ばすために、Proxy(フロント)のhttpd.confに以下のように記述しています。

/usr/local/apache2/conf.httpd.conf に記述

ProxyRequests Off
ProxyPreserveHost On
RewriteRule ^/(.*)/([a-z_]+)-([0-9]+).html$ http://localhost:xxxx(ポート番号)/project_path/$1/$2?id=$3&%{QUERY_STRING} [P,L]
RewriteRule ^/(.*).html http://localhost:xxxx(ポート番号/project_path/$1?%{QUERY_STRING} [P,L]
RewriteRule ^/(.*) http://localhost:xxxx(ポート番号/project_path/$1 [P,L]
  • 1行目・・・フォワードプロキシサーバとしての動作を無効化しています ProxyRequestsについての詳細はこちら
  • 2行目・・・HTTPヘッダのHost:行をProxy側と同じものをApp側にも飛ばすための設定です。ProxyPreserveHostについての詳細はこちら
    これを行わないと、Host部での解釈ができないためApp側でのVirtualHostが有効に働きません。
  • 3行目~5行目・・・Proxy条件・設定です。この部分で記述した書式に従い、Proxy先にリクエストを飛ばします。
    各行の最後に "[P.L]" と終わっていますが、これはmod_rewriteの書式で"Proxyして(P)、条件定義はこの行で終了(L)" という意味になります。

App(アプリケーション)側の設定

App側は基本的には、リクエストがReverseProxyかどうかを判別する必要はありません。なのですが、REMOTE_ADDR(リモートアドレス・接続元)が全てProxy元(今回は同一サーバなので、127.0.0.1=ローカルホスト)になってしまい、アクセスログにも全てProxy元のIPアドレスが記述されます。

アプリ的、ログ解析的にも特に気にしない場合はいいのですが、やはり、アクセス状況を知りたいという場合が来るケースが多いと思いますので
Proxy元が受けたREMOTE_ADDRと同じ値(ユーザーのIPアドレス)をProxy先にもとどくよう、設定します。

設定には mod_extract_forarded モジュールを使います。
(配布されている方のURLをリンクしようと思ったのですが、現在サーバが存在していないようです。もう1.3用のモジュールの配布は終了されてしまったのでしょうか?)

mod_extract_forarded を Apache1.3に適用するには以下のようにしています。

  • mod_extract_forarded をインストール
    ※mod_extract_forwarded.c が存在するディレクトリに移動して、

    /usr/local/apache/bin/apxs -i -a -n 'extract_forwarded' mod_extract_forwarded.so
  • /usr/local/apche/conf/httpd.conf の設定
    以下を追加

    LoadModule extract_forwarded_module libexec/mod_extract_forwarded.so
    
    AddModule mod_extract_forwarded.c
    
    <IfModule mod_extract_forwarded.c>
        RemoveAcceptForwarder all
        AddAcceptForwarder all
    </IfModule>

※<参考> Apache2 の mod_extract_forwarded
Apache 2.x 用の mod_extract_forwarded については、以下からダウンロードできるようです。
(Apche2.0.x 用と書いてありますが、Apache 2.2 でも一応インストールできました。)

関連リンク

M・・・MySQL 5.0

MySQLは全て、yum経由の 5.0.x を利用しています。 現在主流のMySQL5.1 も利用したいのですが、 yum で簡単にインストールできるという部分が、マニュアル化・アプリ全体の品質の統一に大変有効だと思いまして、現在は yum でのインストールのみを利用しています。

yumでのインストールは簡単です。perl用のDBDドライバも同時にインストールします。

yum install mysql mysql-server perl-DBD-mysql

sudo service mysqld start

起動後、すぐにRootのパスワードを設定します。

mysqladmin -u root password 'xxxxxxxxxxx'

MySQLのUTF8対応

MySQLをUTF8対応するために /etc/my.conf で以下のように記述しています。

  • [client] に以下を追記

    default-character-set = utf8
  • [mysqld] に以下を追記
    default-character-set = utf8
    character-set-server=utf8

mysql に接続して、以下のように表示されれば、UTF8での扱いはほぼ問題ないのでは無いかと思います。

mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

mysql は chkconfig にも登録して置き、 boot時に起動するように設定しています。

sudo config add mysqld
sudo chkconfig mysqld on

P・・・Perl(mod_perl)

App側の動的処理は 全て mod_perl で書いています。弊社では案件によっては PHPを利用するケースもありますが、ほとんどの場合は mod_perl でソリューションしています。
特に自社内システムは100% perl/mod_perl で動いています。

mod_perl 自体のインストールは先ほど書いたとおりになります。

mod_perl の上に乗せて動かすアプリケーションですが、コーディングルールの統一化を図るため、MVC(フレームワーク)を利用しています。
弊社では mod_perl用のフレームワークは Sledge を利用しています。
通常のSledge は、基本 EUC-JP を前提としているのですが、弊社ではデフォルトがUTF8ですので、UTF8で動かすためにカスタムモジュールを追加しています。

このSledge を mod_perl 上で扱い、その上に DB との通信するためのORマッパー(今回は Class::DBI )、そしてテンプレートとして template-toolkit を利用しています。

参考リンク

次回に続きます。

少々記事が大きくなってしまいまして・・・ mod_perl + Sledge + Class::DBI + TT(template-toolkit) については
"TwitPepper・Webアプリの中の人(その2)" に続きます。

memcached などもカリカリ使っていますので、こちらに付いても書きたいと思っています。

現在コメントはありません | コメントの投稿はこちら

コメントを書き込む

コメント本文

※コメントのフォーム内で以下のタグがご利用いただけます
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

私はチーム・マイナス6%です