@blog.justoneplanet.info

日々勉強

Amazon EC2を使ってWebSocketサーバを10分でたてる

前回に引き続きWebSocketサーバをたてる。今回はAmazon EC2を使用する。

sudo passwd root

■インストール

rootのパスワードを設定したら以下のコマンドを実行する。

su
yum install openssl-devel gcc-c++ make
wget http://nodejs.org/dist/node-v0.4.3.tar.gz
tar xvzf node-v0.4.3.tar.gz
cd node-v0.4.3
./configure
make
make install
curl http://npmjs.org/install.sh | sh
npm install websocket-server
npm install base64

使用しているインスタンスによって、makeは時間がかかるので10分では無理。(๑°⌓°๑)

別解1

以下のようにnaveを使ってインストールする手法もある。

su
yum install openssl-devel gcc-c++ git make
git clone https://github.com/isaacs/nave.git ~/.nave
~/.nave/nave.sh install latest
~/.nave/nave.sh use latest
echo "~/.nave/nave.sh use latest" >> ~/.bash_profile
curl http://npmjs.org/install.sh | sh
npm install websocket-server
npm install base64

残念ながらmicroインスタンスでコンパイルすると負荷が高すぎて途中終了してしまった。Largeでコンパイルすればサクっと終わる。

追記

会社で同僚に教えてもらった。

別解2

nvmを使えばnpmも同時にインストールできる。

su
yum install openssl-devel gcc-c++ git make
git clone git://github.com/creationix/nvm.git ~/.nvm
source ~/.nvm/nvm.sh
echo "~/.nvm/nvm.sh" >> ~/.bash_profile
echo "nvm use v0.4.8" >> ~/.bash_profile
nvm sync
nvm install v0.4.8
npm install websocket-server
npm install base64

smallインスタンスたどコンパイルに時間がかかる。

■アカウントの作成

話が前後するがアカウントの作成からだと流石に10分は無理。作成方法については以下を参照すると良い。

■EC2まとめ

コマンドラインツールを使用するにはX.509 証明書が必要。基本的にはコントロールパネルから操作が可能。インスタンスを起動させるフローで証明書(鍵)がダウンロードできる。SSHはその鍵で接続する。そんな感じ。(。・ω・)ノ゙

■開発環境構築

以下のコマンドを実行しツールをインストールする。

npm install node-dev #ファイルを変更すると再実行
npm install node-inspector #Developer Tool
npm install cloud9 #IDE

さくらのVPSを10分でWebSocketサーバにする

たぶん10分くらいで可能。

yum install openssl-devel
wget http://nodejs.org/dist/node-v0.4.3.tar.gz
tar xvzf node-v0.4.3.tar.gz
cd node-v0.4.3
./configure
make
make install
curl http://npmjs.org/install.sh | sh
npm install websocket-server
npm install base64

make中は一休みできる(●´ω`●)

最新版

websocket-serverは新しいWebSocketの仕様に対応してないのでwebsocketを使用する。

yum install openssl-devel gcc-c++ make
wget http://nodejs.org/dist/v0.6.8/node-v0.6.8.tar.gz
tar xvzf node-v0.6.8.tar.gz
cd node-v0.6.8
./configure
make
make install
curl http://npmjs.org/install.sh | sh
npm install websocket

アーカイブをのぞいてみる

以下のようなファイルが存在するとする。

lib.a

以下のコマンドを実行し元のファイル名に分解できる。

ar -t lib.a

但しファイルによっては以下のように表示される。

ar: lib.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it)

アーカイブには複数のアーキテクチャ用のコードが含まれているためであり、以下のコマンドを実行して単一のアーキテクチャのファイルを抽出した後、arコマンドを実行する。

lipo lib.a -thin armv6 -output libarm6.a
ar -t libarm6.a

GNU helloをビルドする

wget http://mirrors.kernel.org/gnu/hello/hello-2.7.tar.gz
tar xvzf hello-2.7.tar.gz
cd hello-2.7
./configure --help=short

以下のように表示される。

Configuration of GNU Hello 2.7:

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --disable-dependency-tracking  speeds up one-time build
  --enable-dependency-tracking   do not reject slow dependency extractors
  --disable-nls           do not use Native Language Support
  --disable-rpath         do not hardcode runtime library paths

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-gnu-ld           assume the C compiler uses GNU ld default=no
  --with-libiconv-prefix[=DIR]  search for libiconv in DIR/include and DIR/lib
  --without-libiconv-prefix     don't search for libiconv in includedir and libdir
  --with-libintl-prefix[=DIR]  search for libintl in DIR/include and DIR/lib
  --without-libintl-prefix     don't search for libintl in includedir and libdir

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  LIBS        libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CPP         C preprocessor

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to <bug-hello@gnu.org>.
GNU Hello home page: <http://www.gnu.org/software/hello/>.
General help using GNU software: <http://www.gnu.org/gethelp/>.

ふむふむ。

./configure --prefix=/opt/hello-2.7
make
sudo make install

■実行

以下のコマンドを実行する。

hello

以下のように表示される。

Hello, world!

以下のコマンドを実行する。

env LANG=ja_JP.UTF-8 hello

以下のように表示される。

世界よ、こんにちは!

WebminにSSLで接続する

■モジュールのインストール

以下のコマンドを実行し必要なモジュールをインストールする。

wget http://download.webmin.com/download/Net_SSLeay.pm-1.23.tar.gz
tar xzvf Net_SSLeay.pm-1.23.tar.gz
cd Net_SSLeay.pm-1.23
/usr/bin/perl Makefile.PL && make
make test
make install

■設定

まず、前回の記事を参考にして証明書を生成し、「Webmin > Webmin設定 > SSL暗号化」にアクセスし、以下のように設定する。(証明書ファイルのパスは環境に合わせた値を入力)

可能であればSSLを使用可能にしますか?
はい
プライベート鍵ファイル
/root/ssl/server.key
証明書ファイル
/root/ssl/server.crt

こういうのは早めにやったほうが良いね。c(`・ω´・ c)っ≡つ ババババ

ApacheでSSLを利用する

前回の記事を参考に秘密鍵と証明書を生成する。

■コマンド

以下のファイルを編集する。

vi /etc/httpd/conf/httpd.conf

以下の記述を追記する。

SSLCertificateFile /root/ssl/server.crt
SSLCertificateKeyFile /root/ssl/server.key

バーチャルホストで運用し、特定のサイトのみSSLでも通信を行う場合は以下のようにする。

<VirtualHost *:80>
    SSLEngine On
    SSLCertificateFile /root/ssl/server.crt
    SSLCertificateKeyFile /root/ssl/server.key
    DocumentRoot /var/www/vhosts/domain/httpdocs
    ServerName localhost.localdomain
    ServerAlias www.localhost.localdomain
</VirtualHost>

CentOSにmembaseをインストールする

CentOS 5.3の32bit版にインストールしてみることにした。

■インストール

以下のコマンドでrpmからインストールできる。

wget http://c2978342.ltd.cloudfiles.rackspacecloud.com/membase-server-community_x86_1.6.4.rpm --referer="http://www.membase.org/downloads"
rpm -ivh membase-server-community_x86_1.6.4.rpm

ダウンロードサイトの仕様上、wgetにリファラーをつけた。インストールが完了すると以下のメッセージが表示される。

Starting Membase server[  OK  ]

You have successfully installed Membase Server.
Please browse to http://localhost.localdomain:8091/ to configure your server.
Please refer to http://membase.com and http://membase.org for
additional resources.

Please note that you have to update your firewall configuration to
allow connections to the following ports: 11211, 11210, 4369, 8091
and from 21100 to 21199.

By using this software you agree to the End User License Agreement.
See /opt/membase/LICENSE.txt.

■設定

ブラウザから設定ができるらしいので、以下のコマンドでポート8091番を開ける。ついでに上述のメッセージに従って、11211番、11210番、4369番も同様に対処しておく。

system-config-securitylevel-tui

http://localhost:8091/にアクセスすると悪そうな顔したキャラが表示されるはずだ。後は画面の指示に従えば良い。

■ベンチマーク

上手く書き込みできるかを検証するついでにベンチマークしてみる。

$memcache = new Memcache();
$memcache->connect('localhost', 11211);
$start = microtime(true);
for($i = 0; $i < 1000; $i++){
    $memcache->set("k{$i}", "abcdefghijklmnopqrstuvwxyz");
}
$end = microtime(true);
print($end - $start);// 0.19418982505798

以前にmemcachedのベンチマークで使用したコードをそのまま使うことができるのが素晴らしい。

勝手評価

速度はmemcachedの2~3倍程度かかるようだが、他のKVSよりも数倍高速である。複雑な構造を必要とせずハッシュテーブルとして使用するだけならば、オススメできる気がする。

不具合:保存ができない

管理画面にアクセスし(http://localhost:8091/index.html#sec=monitor_buckets&zoom=zoom_minute)Data Bucket>Item Countを見ると0のままで保存がされていない。

原因

memcachedが既にポートを使っていた。

対策1

以下のコマンドでmemcachedをstopする。普通の人はこれで良いと思う。

/etc/init.d/memcached stop
対策2

以下のコマンドでmemcachedをアンインストールする。membaseがあればmemcachedは要らないってこともあり得る。

yum remove memcached
確認

以下のコマンドで確認すると良いかもしれない。

lsof -i:11211
悪い例

memcachedがポートを使っている。

COMMAND    PID      USER   FD   TYPE DEVICE SIZE NODE NAME
memcached 2500 memcached   26u  IPv6   8072       TCP *:11211 (LISTEN)
memcached 2500 memcached   27u  IPv4   8073       TCP *:11211 (LISTEN)
memcached 2500 memcached   28u  IPv6   8077       UDP *:11211
memcached 2500 memcached   29u  IPv4   8078       UDP *:11211
良い例

membaseがポートを使っている。

COMMAND  PID    USER   FD   TYPE DEVICE SIZE NODE NAME
moxi    6481 membase   40u  IPv6  38065       TCP *:11211 (LISTEN)
moxi    6481 membase   41u  IPv4  38066       TCP *:11211 (LISTEN)

■特性

memcached互換のNoSQLデータベース「Membase」がオープンソースで登場」を参考のこと。デフォルトでGUI管理ってのはなかなか頑張ってるよね。

CentOSにMongoDBをインストールする

■インストール

yumリポジトリの追加

以下のコマンドでリポジトリを追加する。

vi /etc/yum.repos.d/mongo.repo

以下のようにファイルの中身を記述する。

[10gen]
name=10gen Repository
baseurl=http://downloads.mongodb.org/distros/centos/5.4/os/i386/
gpgcheck=0

保存したら以下のコマンドを実行する。

yum install mongo-stable*

起動

以下のコマンドで起動してみる。

/etc/init.d/mongod start

以下のコマンドで起動したか確認する。

lsof -i:27017

以下のコマンドで自動起動を設定する。

chkconfig mongod on
chkconfig mongod --list

参考

CentOS and Fedora Packages

amazon linuxにインストールする

wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.0.2.tgz
tar xvzf mongodb-linux-x86_64-2.0.2.tgz
mv mongodb-linux-x86_64-2.0.2 /var/lib/mongodb
mkdir /mnt/db
/var/lib/mongodb/bin/mongod --fork --logpath ~/mongod.log --dbpath /mnt/db/

■PHPから扱う準備

以下のコマンドでpecl_mongoをインストールする。

pecl clear-cache
pecl install mongo

以下のコマンドで設定ファイルを生成する。

cp /etc/php.d/curl.ini /etc/php.d/mongo.ini
vi /etc/php.d/mongo.ini

設定ファイルは以下のような記述だ。

; Enable mongo extension module
extension=mongo.so

設定が終わったらhttpdをreloadする。

/etc/init.d/httpd reload

参考

PHP & MongoDB Sitting in a Tree: Part 1

英語だが非常に参考になるドキュメントだ。

■ベンチマーク

以下のコードを使用してベンチマークしてみた。

$dbh = new Mongo();
$dbh = $dbh->testdb;
$col = $dbh->bench;
$start = microtime(true);
for($i = 0; $i < 1000; $i++){
    $col->insert(
        array(
            'key'   => "key{$i}",
            'value' => "abcdefghijklmnopqrstuvwxyz"
        ),
        true
    );
}
$end = microtime(true);
print($end - $start);0.66766786575317
$dbh->close();

但し、2回目以降は0.2秒以下になる。

データを取り出す

本当にデータが挿入されているのか不安になったので、以下のコードを使用してデータを覗いてみた。

$res = $col->find();
$s = 0;
foreach($res as $doc){
    print("<pre>{$s}");
    var_dump($doc);
    print('</pre>');
    $s++;
}
$dbh->close();

ベンチマークをしておいて言うのもオカシイが、データストアにおいて全く同じ条件というものは再現できないので単純に比較してはならない。用途に応じた選択が必要である。

amazon Linuxにインストールする

amazon Linuxにインストールする場合は以下のようにする。

curl -O  http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.0.2.tgz
tar xzf mongodb-linux-x86_64-2.0.2.tgz
mv mongodb-linux-x86_64-2.0.2 /var/lib/mongodb
cd /var/lib/mongodb/bin
mkdir /mnt/db
./mongod --fork --logpath /var/log/mongod.log --dbpath /mnt/db/