2011年6 月18日  |  Written by matsumoto  |  under Perl Yahoo!ブックマークに登録    はてなブックマーク - [perl] perlbrewを使ったperl-5.14.1のインストール

perl-5.14.1がリリースされていまして、さっそくインストールしました。
perlbrewを使ってのperlのインストールのメモです。

  • perl-5.14.0 -> 2011/05 リリース
  • perl-5.14.1 -> 2011/06 リリース

予定どおりでしたら、サブバージョンのアップデート(perl-5.14.2)は 2011/10ごろでしょうか。

perlのインストール先

perlbrewのデフォルト通り、 $HOME/perl5 … 以下にインストールしています。

/home/app-account/perl5/perlbrew/perls/current/bin/perl

perlbrewが無い場合はインストール

cd
curl -LO http://xrl.us/perlbrew
perl perlbrew install
rm perlbrew

perlbrew経由で perl-5.14.1 をインストール

perlbrew経由で perl-5.14.1 をインストール

~/perl5/perlbrew/bin/perlbrew install perl-5.14.1

(何もしていないサーバーでも20分ぐらいかかります)

とりあえずデフォで入っているモジュールを全部アップデート

curl -L --insecure http://cpanmin.us | ./perl5/perlbrew/perls/perl-5.14.1/bin/perl - App::cpanminus
./perl5/perlbrew/perls/perl-5.14.1/bin/cpanm App::cpanoutdated
./perl5/perlbrew/perls/perl-5.14.1/bin/cpan-outdated | ./perl5/perlbrew/perls/perl-5.14.1/bin/cpanm

cpanm コマンドが使えるようになるので、必要なモジュールを適当にインストールしていきます。

./perl5/perlbrew/perls/perl-5.14.1/bin/cpanm Task::Plack

環境構築が完了したら、 switch コマンドで 常用するperlのバージョンを定義します。

~/perl5/perlbrew/bin/perlbrew switch perl-5.14.1

"current"のperlが 5-14.1になりました。 Shebangなどでは、 current経由で指定しています。

~/perl5/perlbrew/perls/current/bin/perl -v

This is perl 5, version 14, subversion 1 (v5.14.1) built for i686-linux

perl自体をアンインストール OR 再インストールしたい場合

rm -rf ~/perl5/perlbrew/perls/perl-5.14.1/

すっきりDELして、再度 perlbrew 経由でインストールします。

運用システムで利用しているperl

perlbrewを利用していない、昔からのOS付属のperlで運用システムもありつつなのですが、大体以下のような感じです。

  • 昔からのシステムで利用

    • perl-5.8.8
  • perlbrewを適用したシステムで利用
    • perl-5.12.3

5.14.xは検証しつつですが、今後メインで利用するバージョンになると思います。

perl-5.10.x は利用していません。

RHLE6ではデフォルトが5.10.1っぽいので、将来の CentOS 6 のデフォルトのperlのバージョンも5.10.1になると思うのですが
今後、は多分OS付属のperlは、メインで率先しての利用は行わないと思います。

perlbrewでバージョンを自由にコントロールできますし、マニュアル化も簡単です。
なによりyum/RPMの依存関係を壊さないので大変使い勝手が良いです。

関連リンク

2011年6 月15日  |  Written by matsumoto  |  under Apache, サーバー Yahoo!ブックマークに登録    はてなブックマーク - CentOS5 での yum / Apacheなどの環境構築

ご無沙汰しております、松本です。先月36歳になりました。
今度こそきっちりBlogを書き続けるように頑張ります。決して暑さのせいじゃないのですが、かまけていました。

四捨五入するとアラフォー、プログラマ定年説からは既にオーバーしている年代に突入致しました。
が、なるべくよろしい感じにアレしたいと思います。

CentOS5 + yum + Apacheなど

今回はCentOS5のyumのデフォをなるべく利用して、Apache周りのシステムを構築する周りです。
ググればほとんどの情報がでてくるCentOSですが、弊社で利用している一部の環境の構築手法含めのメモ記事であります。

yum環境について

昔は(特に"FreeBSD最高!"の時代)、ソースビルド→インストールにこだわっていたりなどあったのですが・・・

CentOS5+yumでは、ミドルウェアのアップデートや、環境構築の際のマニュアル化も簡単で
yumでどんどん入る最近では、yumでのインストール前提での構築に完全にスライドしてしまいました。

yumの利用は以下をポリシーとしています。

  • なるべく CentOS5公式のリポジトリのツール/ソフトウェアを利用する
  • なるべくデフォルトでセットアップされている構成で利用する。
    • 同名のツール/ソフトウェアは公式のレポジトリにあるものを優先する(バージョンが低い場合もあるけどそこはスルー)
    • 公式の中の base / updates / extras を利用。
    • 公式の中でも特にデフォルトで無効になっている、"centosplus / contrib"は利用しない。

プラス、epel(Extra Packages for Enterprise Linux) をインストールしています。
epelは、デフォルトのリポジトリには無いソフトウェアを提供するもので、libapreq2 や、nginx などはepel経由でインストールしています。

Fedoraプロジェクトで運営されていまして、CentOS5の公式の次に、一番公式に近いものと判断して選択しました。

RPMForge も使いやすいのですが、公式のツール/ソフトウェアの同名ファイルを上書きする可能性もあるため、特にインストールしません。
また、前述の "なるべく少ない数のリポジトリで済ませたい" という主旨から epel だけをインストールしています。

もしかしたら将来的に RPMForge経由でのインストールもあり得るかもしれませんが
現状では デフォルトの base / updates / extras + epel で事足りています。

yum環境の構築

上記ポリシーに従い、以下のコマンドでyum環境を構築しています。
fastmirrorを入れないと、都度もっさり検索するので必須です。

epelをレポジトリに追加

i386 (32bit) の場合

# rpm -ivh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm

x86_64 (64bit) の場合

# rpm -ivh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm

fastestmirror その他必須ツール系をまずインストール

# yum install -y yum-fastestmirror
# yum -y install ntp sudo zsh screen vim-enhanced subversion git

全てのツール/ソフトウェアを更新

# yum -y update

以上の作業が済んだらApache等のインストールです。

ツール/ソフトウェアのインストール

perlを利用したWAFでは、Plack/PSGI のアプリが隆盛を極めていますが、弊社では未だに mod_perl で運用している事もありまして
以下、Proxy + App の構成を Apache2 + mod_perl2での運用を想定した構築手順です。

Apacheのインストール、設定など

必要なツール/ソフトウェアをインストール

Apache2::Request を利用するために、 libapreq2 も併せてインストールしています。

CentOSのyumで扱うhttpdは CentOS5ですと、 apache 2.2.3 です。
このバージョンは mod_proxy_balancer も使えるので Proxyサーバがそのまま、ロードバランサ代わりにもなります。

# yum -y install \
httpd httpd-devel httpd-manual \
mod_perl mod_perl-devel \
libapreq2 libapreq2-devel perl-libapreq2

また、デフォルトでの boot時の自動起動を無効にしておきます。

# /sbin/service httpd off

以上で終了です。超あっさりです。

apacheのconfigなどの扱い

yumでインストールしたApacheのデフォルトのConfigファイルや実行ファイルなどは、おおよそ以下になっています。

  • 実行ファイル

    • /usr/sbin/apachectl
  • httpd.conf
    • /etc/httpd/conf/httpd.conf
  • httpd.conf内で利用する外部ファイル
    • /etc/mime.types
    • /etc/httpd/conf/magic (mod_mime_magicを使う場合)
  • その他モジュールで使う設定ファイル
    • /etc/httpd/conf.d/

などです・・・。

激しく面倒な構成です。yumで色々インストールしていくと、何を抱えているかわからなくなりがちでして
弊社では

  • Proxy 用のconfファイル=1枚
  • App用のConfファイル=1枚

を作り、それぞれに apachectl のスクリプトを用意して運用しています。
このそれぞれが yumでインストールした httpd を参照して、 2つのデーモンを起動するようにしています。

具体的なファイル構成は以下です。

/home/app-account/proj/etc/app.conf  <-- mod_perl用の httpd.conf (これ1枚で完結)
/home/app-account/proj/etc/proxy.conf <-- Proxy用の httpd.conf (これ1枚で完結)
/home/app-account/proj/bin/apachectl-app <-- mod_perl用の apachectl
/home/app-account/proj/bin/apachectl-proxy <-- mod_perl用の apachectl
/home/app-account/proj/etc/mime.types <-- /etc/mime.types をコピー

apachectl-app や apachectl-proxy では、httpd.confの参照先を変更しています。

HTTPD='/usr/sbin/httpd'

  • App

    HTTPD='/usr/sbin/httpd -f /home/app-account/proj/etc/app.conf'
  • Proxy

    HTTPD='/usr/sbin/httpd -f /home/app-account/proj/etc/proxy.conf'

と、書き換えています。

appとproxyのスクリプトの違いは、大きいところでは以下3つです。

  • httpd -f で参照する先のhttpd.confのパスの違い
  • pidファイルを proxy と app で違うパスに指定
  • ロードするモジュールのだし分け

この他、 mod_perl や mod_php 、その他 mod_xx をロードする場合は、それぞれ必要な側にのみ記述します。

また、 mime.types は proj に add されたファイルを使っています。全てのファイルの参照先は Proj 以下になるようにしています。

この手法&手順だと何がうれしいのか

上記の"proj"ディレクトリ以下をバージョン管理システムで管理していますので、conf/スクリプト共にファイルが書き換わったり無くしたりなどがありません。

また、設定変更も 例えば複数台のWebサーバで同じシステムを構築&LB配下に置く場合など、非常に運用がしやすくなります。

apache(httpd)のバージョンアップも容易で、
且つ モジュールのインストール時に自動でファイルが上書きや追加されても影響がありませんので、
意図した通りに運用することが用意になります。

特に、”直接サーバーに入ってそれぞれのConfigファイルを書き換え”がありませんので、ややすっきりします。

ということで yum でもりもりと更新しても あまりドキドキせずに運用できる辺りが一番の狙いです。

いかがでしょうか。超あっさり目ですが、 Apache2の yum での 簡単扱い手順でした。

関連リンク

2010年9 月1日  |  Written by matsumoto  |  under Perl Yahoo!ブックマークに登録    はてなブックマーク - [perl] SledgeでText::Xslateを使う

こんにちは、松本です。
3月の最終エントリ以後、暑すぎて ダラダラし過ぎました。Blogをちゃんと書くようにします。

今回はperlのフレームワーク "Sledge" でテンプレートエンジンの "Text::Xslate" を使います。

Template-Toolkitについて

Sledgeで利用するテンプレートエンジンは TT(Template-Toolkit) がデファクトスタンダードであります。
(HTML::Templateも使えますが・・・)

TTは、テンプレートエンジンとして非常に柔軟性が高く、大変に使いやすいのですが何せ、処理が重いです。

6A(シックス・アパート)のBlogサービスの、VoxもTemplate-Toolkitを利用しているらしいのですが

Template Toolkit: profile. Wow! Template Toolkit takes 60% of the request time.

との事で、リクエストの処理全体の6割をTTが占有してしまっているという驚愕の事実らしいです。

弊社でも ClearSilverText::MicroTemplateTenjiin などを Sledge に組み込めるか、試行錯誤してみたのですが
TTと全く違う文法で記述されたHTMLテンプレートが、プロジェクト毎に混在するとなると、運用面で人的負荷や稼動コストが増える可能性があったため、見送っていました。


Text::Xslate

Text::Xslate は、藤 吾郎さん が CPAN で公開されているモジュールで、精力的にUPDATEされているテンプレートエンジンです。

TTとほとんど同一の文法でHTMLテンプレートを記述することができ、更に高速動作するモジュールでして
先の 6割の処理の部分を抑える事ができるのでは?と期待大です。

TTの文法により近づけるために Text::Xslate::Bridge::TT2Like モジュールも併せて利用します。

インストール

cpanm で さっくりインストールです。

cpanm -S Text::Xslate Text::Xslate::Bridge::TT2Like

Sledgeのテンプレートクラス

ズバリ、以下のテンプレートクラスをPages.pmから呼び出しています。

Prog/Pages.pm (一部)

シンタックスハイライトを付けてある、全コードは こちら

sub create_template {
    my ($self, $file) = @_;
    my $tmpl = Proj::Template::Text::Xslate->new($file, $self);
    return $tmpl;
}

Proj/Template/Text/Xslate.pm

シンタックスハイライトを付けてある、全コードは こちら

package Proj::Template::Text::Xslate;

use utf8;
use strict;
use warnings;
#use base qw/Sledge::Template/;

use Text::Xslate;
use Scalar::Util;

use vars qw($Tx);
$Tx = '';

sub new {
    my($class, $file, $page) = @_;
    bless {
        _options => {
            filename => $file,
        },
        _params  => {
            config  => $page->create_config,
            r       => $page->r,
            session => $page->session,
        },
    }, $class;
}

sub add_associate       { Sledge::Exception::UnimplementedMethod->throw }
sub associate_namespace { Sledge::Exception::UnimplementedMethod->throw }

sub output {
    my $self = shift;
    #my %config = %{$self->{_options}};
    #my $input  = delete $config{filename};
    my $input  = delete $self->{'_options'}->{'filename'}
                           || Sledge::Exception::TemplateNotFound->throw(
                                   "No template file detected. Check your template path.",
                              );
    if(!$Tx) {
        my %config = %{$self->{_options}};

        $config{syntax}    = 'TTerse';
        $config{header}    = [ qw/commons.inc/ ];
        $config{module}    = [ qw/Text::Xslate::Bridge::TT2Like/ ],
        $config{path}      = [ $self->{'_params'}->{'config'}->tmpl_path, $self->{'_params'}->{'config'}->tmpl_path . '/includes' ];
        $config{cache}     = 1;
        $config{cache_dir} = $self->{'_params'}->{'config'}->cache_dir . '/text_xslate_cache';
        $config{type}      = 'text';
        $config{function}  = {
            nl2br      => \&Text::Xslate::Bridge::TT2Like::html_line_break,
            uri_escape => \&Text::Xslate::uri_escape,
        };
        $Tx = Text::Xslate->new(%config);
        #warn "[ CREATE TX ]";
    }
    unless (-e $input) {
        Sledge::Exception::TemplateNotFound->throw(
             "No template file detected. Check your template path.",
        );
    }
    $input =~ s@/path/to/proj/view/@@;
    my $output = $Tx->render($input, $self->{'_params'});
    $self->finalize;
    return $output;
}

sub param {
    my $self = shift;
    if (@_ == 0) {
        return keys %{$self->{'_params'}};
    }
    elsif (@_ == 1) {
        return $self->{'_params'}->{$_[0]};
    }
    else {
        while (my($key, $val) = splice @_, 0, 2) {
            $self->{'_params'}->{$key} = $val;
        }
    }
}

sub finalize {
    my $self = shift;
    for my $key ($self->param()) {
        if( ! ref( $self->{'_params'}->{$key} ) || $key eq 'session' || $key eq 'r' || $key eq 'config') { next; }
        if (!Scalar::Util::isweak($self->{'_params'}->{$key})) {
            #warn "[ WEAKEN ] ".$key;
            eval { Scalar::Util::weaken($self->{'_params'}->{$key}) };
        }
        delete $self->{'_params'}->{$key};
    }
}

1;

速度比較

Template-ToolkitからText::Xslateに変更することで、大よそ 150% ぐらい、リクエストの処理速度が向上しました。

今まで 100req/sec だったものが 150req/sec に高速化された形です。

気になった点、ハマッた点

  • mod_perlのプロセスサイズが 120%ぐらい増えました。 メモリが少ない環境では要注意かも。

ハマッた点

Docsにも書いてある点がほとんどなので、ちゃんと読め!という部分なのですが・・・

  • [% INCLUDE "header.inc" %] など、 "(ダブルクォーテーション)でファイル名を囲まないといけないです。
  • TTのオプションに存在する、"ABSOLUTE" が使えないので INCLUDE内のファイルに明示的に変数を渡さなければならないので

    [%- INCLUDE "header.inc" WITH
        FOO = 'ふー'
     -%]

    などとWITHで記述します。

  • TTでいう、PROCESS、INSERT は使えないです。
  • マクロを呼び出すときに、[% macro_func %] でなく、[% macro_func() %] と () を付ける必要があります。
  • render($file,$param) で指定する $fileは path で指定された以下のファイルパスを指定します。(絶対パスではないです)
  • TTの PRE_PROCESS は Text::Xslate の new時に渡す引数の header に相当します

まとめ

Template-Toolkitとほとんど同一の記法で、基本差し替えるだけで
Webアプリ全体の処理速度が向上しますので、是非ご利用されてみてはいかがでしょうか。

150%の処理速度向上が見込めましたので、次回プロジェクトでは試行してみたいと思います。

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