WebSocket(node + socket.io)をstunnel + HAProxyでプロキシする - その2 - HAProxyの設定
Nginxとnode.jsをHAProxy+stunnelでまとめる方法についてまとめています。
サーバーの構成は以下のようになります。
前回の記事はHAProxyのインストールまで紹介しました。
http://d.hatena.ne.jp/hrendoh/20120328/1332917793
今回は、HAProxyでNginxとnode.jsのサーバーに振り分ける設定方法と、各種パラメータについて実際の設定例を基にまとめてみます。
設定のリファレンスは、公式サイトのDocumentページにリンクがあるテキストのものと、Google codeにも同じ内容のものがまとまっています。
Google codeのドキュメントの方が見やすいのでお薦めです。
haproxy.cfgの設定
HAProxyの設定は /etc/haproxy/haproxy.cfg に記述します。
今回の例は、以下のようになります。
global
maxconn 4096
daemon
nproc 1
log 127.0.0.1 local1 debug
defaults
mode http
option httplog
log global
frontend all 0.0.0.0:80
timeout client 86400000
default_backend www_backend
acl is_websocket hdr(Upgrade) -i WebSocket
acl is_websocket path_beg /socket.io/
use_backend socket_backend if is_websocket
backend www_backend
balance roundrobin
option forwardfor # This sets X-Forwarded-For
option httpclose
timeout server 30000
timeout connect 4000
server server1 localhost:81 weight 1 maxconn 1024 check
backend socket_backend
balance roundrobin
option forwardfor # This sets X-Forwarded-For
option httpclose
timeout queue 5000
timeout server 86400000
timeout connect 86400000
server server1 localhost:3000 weight 1 maxconn 1024 check
以下、これを踏まえてhaproxy.confの設定について説明していきます。
設定ファイルの構成
まず、"global"セクションに、HAProxyプロセス全体で共通の設定を記述し、続けて、以下の4つのプロキシ設定セクションに、リッスンする各ポートの設定やバックエンドサーバーへの振り分け設定などを記述していきます。
- defaults: 後述するfrontend、backend、listenのデフォルトパラメータを指定します。
- frontend: クライアントからの接続を受け入れるソケットのパラメータを指定します。
- backend: プロキシするサーバーに関わるパラメータを指定します。
- listen: frontendとbackendを完全にプロキシする設定を記述します。
プロセス設定
設定例の"global"セクションに記述されている各パラメータは以下の通りです。
プロキシ設定
プロキシセクションに設定するパラメータは、"defaults"、"frontend"、"backend"、"listen"のいづれのセクションでも使用可能なものと、専用のものがあります。
各パラメータと利用可能なセクションの一覧がドキュメントの「Proxy keywords matrix」にあります。
以下、大まかに分けてよく使うパラメータについて説明しています。
Keep-Aliveの設定(すべてのセクション)
接続モード(すべてのセクション)
backendの選択(defaults, frontend, listen)
- default_backup: マッチするuse_backendが無かった場合に使用されるbackendを指定します。
- use_backend:
ロードバランス(backend)
- balance: ロードバランスに使用するアルゴリズムを指定します。HAProxyは非常に強力なロードバランス機能を提供しています。指定しなかった場合のデフォルトはroundrobinです。
- roundrobin: ラウンドロビン、重み付けの機能あり、動的調整あり(サーバーダウンから回復直後に大量リクエストを割が割り当てられないように調整します)、各backendについて最大4128のアクティブサーバーを指定可能。
- static-rr: ラウンドロビン、重み付けの機能あり、動的調整なし、backendサーバーの制限無し。
- leastconn: もっとも接続数が少ないサーバーが割り当てられます。
- source: IP Addressのハッシュ値を元に振り分け。
- uri: URIの'?'の前をハッシュし、その値を元に振り分け。つまり、サーバーが停止/起動されない限りは、URIの値が同じなら同じサーバーに振り分けられる。ハッシュするURIの深さや長さなど詳細な設定も可能。 balance uri [len
] [depth ] - url_param: URIのパラメータにより振り分け、POSTの場合もcheck_postを指定するとPOSTのボディを使用する。 balance url_param [check_post [
]] - hdr(name): HTTPヘッダーにより振り分け
- rdp-cookie, rdp-cookie(name): RDPクッキーをハッシュした値により振り分け、nameを指定しない場合は"mstshash"が使用される。
- option forwardfor: backendサーバーへ送られるリクエストに"X-Forwarded-For"ヘッダーを追加します。HAPorxyはリバースプロキシとして動作するため、各backendサーバーはHAProxyサーバーのIPアドレスをクライアントアドレスとして認識してしまいます。これを解決するために本オプションを利用します。
ACL
Access Control Lists (ACL)は、HAProxyの肝となる重要な機能で、これによって柔軟なサーバー構成が可能になります。
ACLの指定フォーマットは以下のようになります:
acl[flags] [operator] ...
今回の例では、"Upgrade"ヘッダーに"WebSocket"という値が含まれている場合にis_websocketをtrueにします。
acl is_websocket hdr(Upgrade) -i WebSocket
以下のブログも参考になります:
HAProxyのACLとCriteria
ログ出力
設定例から、ログ出力に関する箇所だけ抜き出しました。
global
...
log 127.0.0.1 local1 debug
defaults
...
log global
...
logパラメータの設定は以下のフォーマットで記述します。
log <address> <facility> <level>
- address: ログを送信するIPアドレスを指定します。設定例ではローカルのrsyslogデーモンにログを送信します。IPv4アドレスを指定した場合は、UDPソケットでログが送信されるのでrsyslog側で受けられるように設定する必要があります。また、Unixソケットを使用することもできます。
- facility: syslogのファシリティを指定します。
- level: rsyslogdに送信するログレベル "emerg", "alert", "crit", "err", "warning", "notice", "info", "debug" を指定します。省略した場合は、すべてのログが送信されます。
プロキシセクションで"log global"と記述した場合は"global"セクションの設定が引き継がれます。
Ubuntu 10.04でのログ設定を以下のブログを参考にまとめて見ます。
HAProxy Logging in Ubuntu Lucid
$ sudo vi /etc/rsyslog.d/haproxy.conf
# .. otherwise consider putting these two in /etc/rsyslog.conf instead: $ModLoad imudp $UDPServerRun 514 $UDPServerAddress 127.0.0.1 # ..and in any case, put these two in /etc/rsyslog.d/haproxy.conf: local1.* -/var/log/haproxy_1.log & ~ # & ~ means not to put what matched in the above line anywhere else for the rest of the rules # http://serverfault.com/questions/214312/how-to-keep-haproxy-log-messages-out-of-var-log-syslog
$ sudo service rsyslog restart
ポートを空ける必要があるので、reloadじゃなくてrestart
ログ出力の確認
$ tail -f /var/log/haproxy_1.log Apr 20 15:15:54 localhost.localdomain haproxy[11220]: Connect from 127.0.0.1:57720 to 127.0.0.1:80 (all/HTTP) Apr 20 15:15:54 localhost.localdomain haproxy[11220]: Connect from 127.0.0.1:57721 to 127.0.0.1:80 (all/HTTP) Apr 20 15:15:54 localhost.localdomain haproxy[11220]: Connect from 127.0.0.1:57722 to 127.0.0.1:80 (all/HTTP) ...
ローテーションも設定しておきます
$ sudo vi /etc/logrotate.d/haproxy
/var/log/haproxy*.log {
weekly
missingok
rotate 52
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
reload rsyslog >/dev/null 2>&1 || true
endscript
}
以上、大まかにHAProxyの設定について説明しました。
次回はstunnelのセットアップについて説明します。
