ようへいの日々精進XP

よかろうもん

(超メモ)HAProxy 1.6 で Lua がサポートされたので触ってみた(2)〜リクエストヘッダで Backend の振り分け〜

どこまでも自称な HAProxy 芸人のかっぱです。

tl;dr

引き続き、HAProxy の Lua サポートについて触ってみたい。あくまで試行錯誤なので誤りがあれば適宜修正する。


参考


リクエストヘッダで Backend を振り分ける例

リクエストヘッダを取得する

色々と試行錯誤した結果、Lua でリクエストヘッダの中身を取得したい場合には Fetches クラスを利用すると良いとのこと。

また、HAProxy の設定から呼び出す場合には core クラスの register_fetches メソッドを利用する。(※メソッドという呼び方が正しいか解らないけど)

Backend のアプリケーションを用意

$ mkdir foo bar
$ echo "foo.example.com" > foo/index.html
$ echo "bar.example.com" > bar/index.html
$ cd foo
$ python -m SimpleHTTPServer 5001 &
$ cd ../bar/
$ python -m SimpleHTTPServer 5002 &

Lua スクリプト

以下のような Lua スクリプトを書いて backend.lua というファイル名で保存する。

$ cat backend.lua
core.register_fetches("select_backend", function(txn)
  if txn.sf:req_fhdr("Host") == "foo.example.com" then
    return "backend1"
  elseif txn.sf:req_fhdr("Host") == "bar.example.com" then
    return "backend2"
  end
  return "backend1"
end)

txn.sf については以下のようにドキュメントに記載されている。

This attribute contains a Fetches class object. The functions of this object returns always a string.

また、req_fhdr については HAProxy の req.fhdr と同様にリクエストヘッダを返す。引数にリクエストヘッダ名(例:"Host")を指定することで任意のリクエストヘッダの値を返すことが出来る。例えば、User-Agent を取得したい場合には以下のように記述する。

core.register_fetches("fetch_useragent", function(txn)
  print(txn.sf:req_fhdr("User-Agent"))
end)

HAProxy の設定

HAProxy の設定は以下のように。

$ cat haproxy.cfg
global
   lua-load backend.lua

frontend http_frt
  bind 127.0.0.1:10002
  mode http
  use_backend %[lua.select_backend]

backend backend1
  server app1 127.0.0.1:5001

backend backend2
  server app2 127.0.0.1:5002

%[lua.select_backend] には Lua スクリプトから返される値が展開される。

ちなみに、Lua スクリプトを利用しない場合には以下のような書き方になる。

$ cat haproxy.cfg
global

frontend http_frt
  bind 127.0.0.1:10002
  acl foo hdr(Host) -i foo.example.com
  acl bar hdr(Host) -i bar.example.com
  use_backend backend1 if foo
  use_backend backend2 if bar
  default_backend backend1

backend backend1
  server app1 127.0.0.1:5001

backend backend2
  server app2 127.0.0.1:5002

HAProxy の起動

$ haproxy -f haproxy.cfg &

動作確認

#
# Host ヘッダに foo.example.com を指定
#
$ curl -H "Host: foo.example.com" 127.0.0.1:10002                                                                                                                          
127.0.0.1 - - [17/Oct/2015 07:22:16] "GET / HTTP/1.1" 200 -
foo.example.com

#
# Host ヘッダに bar.example.com を指定
#
$ curl -H "Host: bar.example.com" 127.0.0.1:10002
127.0.0.1 - - [17/Oct/2015 07:22:25] "GET / HTTP/1.1" 200 -
bar.example.com

雑な比較

ab で雑に処理能力を比較してみた。

$ ab -H "Host: foo.example.com" -n 100 -c 10 http://127.0.0.1:10002/

HAProxy 単体での振り分け

1. Requests per second:    99.61 [#/sec] (mean)
2. Requests per second:    100.17 [#/sec] (mean)
3. Requests per second:    99.79 [#/sec] (mean)

Lua スクリプトによる振り分け

1. Requests per second:    98.58 [#/sec] (mean)
2. Requests per second:    99.66 [#/sec] (mean)
3. Requests per second:    100.37 [#/sec] (mean)

ぱっと見 Lua スクリプトを利用することによるオーバーヘッドは小さい。


ということで...

Lua よく解ってないけど...

振り分けの定義をスクリプトとして定義出来るのは嬉しい。

引き続き...

  • Lua 使っている場合のオーバーヘッドとか見てみたい
  • Lua サポートを試す