WebSocket(node + socket.io)をstunnel + HAProxyでプロキシする - その1 - HAProxyのインストールまで

WebSocketのステータスは、昨年12月にRFC6455としてproposed standard(標準化への提唱)のステータスになりました。

node.js+socket.ioやjetty(Java)を始めサーバーサイドの実装は既に多くあり、クライアントはGoogle ChromeSafariが実装しています。
FireFoxなどはMozWebSocketとして実装されており、リリースは標準化を待っている状態です。
2月にリリースされたFireFox 11より、proposed standardへの移行を受けてWebSocketを正式にリリースしました。
https://dev.mozilla.jp/2012/02/firefox11/

例えば、サーバーにnode.jsを利用するアプリケーションを構築していく場合、実際にはnode.js自体をスケールしたり、WebSocket以外の機能はnode.js以外で実装したい場合もあります。
その場合は、リバースプロキシサーバーが必要となりますが、現在、もっとも有力なのはHAProxyです*1 *2

これから数回に分けで、以下の図のように、node.jsとnginx配下にあるWebアプリケーションをHAProxyでまとめるサーバー構成のシステムを構築する手順についてまとめて行きます。

なお、この内容は以下のブログを参考に実際に、co-meetingで実装した内容*3をまとめ直した物になります。

Proxy socket.io and nginx on the same port, over SSL
Nginx, Websockets, SSL and Socket.IO deployment

まずは、HAProxyのインストールから

HAProxyのインストール

HAProxyは、OSとバージョンの組み合わせによってWebSocketが通ったり通らなかったりします。

CentOS5.5は、yumでインストールされる1.3系でもWebSocketが動きます。
Ubuntu10.04は1.3.22が入りますが、こちらはWebSocketが動かないので1.4系をインストールする必要があります。

Ubuntu 10.04(ソースからインストール)
$ sudo apt-get update
$ sudo apt-get install gcc
$ wget http://haproxy.1wt.eu/download/1.4/src/haproxy-1.4.20.tar.gz
$ tar xvfz haproxy-1.4.20.tar.gz
$ cd haproxy-1.4.20
$ make TARGET=linux26
$ sudo make install
install -d /usr/local/sbin
install haproxy /usr/local/sbin
install -d /usr/local/share/man/man1
install -m 644 doc/haproxy.1 /usr/local/share/man/man1
install -d /usr/local/doc/haproxy
for x in configuration architecture haproxy-en haproxy-fr; do \
		install -m 644 doc/$x.txt /usr/local/doc/haproxy ; \

デーモンとして登録

$ sudo vi /etc/init.d/haproxy

以下の起動スクリプトをコピーして保存してください。
https://gist.github.com/2224288

$ sudo chmod +x /etc/init.d/haproxy 
$ sudo apt-get install sysv-rc-conf # sysv-rc-confが入ってない場合
$ sudo sysv-rc-conf

起動テスト用の設定ファイルを作成

$ sudo mkdir /etc/haproxy
$ sudo cp examples/haproxy.cfg /etc/haproxy/
$ sudo vi /etc/haproxy/haproxy.cfg

haproxy.cfgをいくつか修正

chroot /usr/share/haproxy

コメントアウト

#chroot /usr/share/haproxy
redispatch
option redispatch
$ sudo mkdir /etc/haproxy/errors
$ sudo cp examples/errorfiles/* /etc/haproxy/errors/
$ sudo service haproxy start
 * Starting haproxy haproxy                                              [ OK ] 
Ubuntu 10.04(手抜きバージョン)

apt-getで先に1.3.xをインストール後、1.4.20をインストール後、起動スクリプトを若干修正して1.4.20を利用します。

$ sudo apt-get install haproxy
$ sudo vi /etc/default/haproxy
#ENABLED=0
ENABLED=1

起動

$ sudo /etc/init.d/haproxy start

1.4.20(2012/03/28時点での最新)で上書き

$ sudo apt-get update
$ sudo apt-get install gcc
$ wget http://haproxy.1wt.eu/download/1.4/src/haproxy-1.4.20.tar.gz
$ tar xvfz haproxy-1.4.20.tar.gz
$ cd haproxy-1.4.20
$ make TARGET=linux26
$ sudo make install
$ haproxy -version
HA-Proxy version 1.4.20 2012/03/10
Copyright 2000-2012 Willy Tarreau 

apt-getでインストールした場合に作成される起動スクリプトは/usr/sbin/の下のhaproxyを指しています。
make installすると/usr/local/sbinの下にhaproxyコマンドがインストールされるので変更する必要があります。
(インストールオプションがありそうなものですが、すぐに見つからず)

$ vi /ect/init.d/haproxy
HAPROXY=/usr/sbin/haproxy

を以下に修正

HAPROXY=/usr/local/sbin/haproxy

再起動します。

$ sudo /etc/init.d/haproxy restart

*1:NginxはWebSocketに対応するプラグインがありますが、パスやヘッダによる振り分けなどができないため柔軟な構成は取れません

*2:WebSocketに対応したリバースプロキシサーバーは、他にPoundがあります。こちらの記事も大変参考になります:Railsの各種サーバーの速度ベンチマーク: Pound、Varnish、Nginx、Unicorn、Mongrel

*3:実際には、co-meetingはnode.jsの替わりにjettyを使っています