Nginx + Lua、セッション保存機能を備えた柔軟な負荷分散







負荷を分散する際の重要な問題は、クライアントセッションを維持することです。 特に、バランサーの背後に何らかのインタラクティブなバックエンドがある場合。 さらに、A / Bテストを行い、クライアントの部分をさまざまなコンテンツに柔軟に調整したい場合。 Nginx plusはそのような機会を提供しますが、安くて早くしたい場合はどうでしょうか?







Luaを使用してNginxの機能を拡張する機能が役立ちます。









アルゴリズムは簡単です。 クライアントの最初のリクエストでCookieを設定し、次に値に応じて特定のバックエンドに送信します。 私たちは、必要なパラメータの分析と適切なアルゴリズムでクッキーを自分で配布します。







OpenRestyアセンブリは強力なnginx-harvesterとして使用できますが、必要に応じてこれは冗長であるため、リポジトリからnginx 1.10.3



基づいて必要な機能のみを収集します。







私たちが持っている科目:







 Debian jessie 4.9.0-0.bpo.1-amd64 Nginx 1.10.3 (nginx.org) libluajit-5.1-2
      
      





必要なアセンブリコンポーネント:







 ngx_devel_kit-0.3.0 lua-nginx-module-0.10.8 lua-resty-core-0.1.11 lua-resty-lrucache-0.06
      
      





debパッケージをビルドするためのパッケージをインストールします。







 # cd /usr/src/ # aptitude install quilt debhelper libluajit-5.1-dev libluajit-5.1-2 # apt-get -t jessie source nginx
      
      





最後のコマンドは、構成済みのリポジトリからnginxソースコードをダウンロードします。 Linux用のnginx:パッケージを使用します







モジュールのソースコードの現在のバージョンをダウンロードして解凍します: ngx_devel_kitおよびlua-nginx-module







 # wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz # wget https://github.com/openresty/lua-nginx-module/archive/v0.10.8.tar.gz # tar -xf v0.3.0.tar.gz # tar -xf v0.10.8.tar.gz
      
      





最初のモジュールは、切望されている2番目のモジュールを構築するために必要です。







nginx-1.10.3/debian/rules



にあるdebパッケージアセンブリルールファイルを編集し、パラメーターリストにconfig.status.nginx: config.env.nginx



を追加します。







 --add-module=/usr/src/ngx_devel_kit-0.3.0 --add-module=/usr/src/lua-nginx-module-0.10.8
      
      





結果のパッケージを収集してインストールします。







 # cd nginx-1.10.3 && dpkg-buildpackage -us -uc -b && cd ../ # dpkg -i nginx_1.10.3-1~jessie_amd64.deb # aptitude hold nginx
      
      





最後のコマンドは、インストールされたパッケージを修正して、誤って更新しないようにします。







さらに、 Lua用Nginx APIを提供するOpenRestyプロジェクトのluaライブラリがさらに2つ必要になります。lua -resty-corelua-resty-lrucacheです。 これらは、パス/usr/local/lib/lua/



沿って(デフォルトで)インストールされた*.lua



ファイルのセットです。







 # wget https://github.com/openresty/lua-resty-core/archive/v0.1.11.tar.gz # wget https://github.com/openresty/lua-resty-lrucache/archive/v0.06.tar.gz # tar -xf v0.1.11.tar.gz # tar -xf v0.06.tar.gz # cd lua-resty-core-0.1.11 && make install && cd ../ # cd lua-resty-lrucache-0.06 && make install && cd ../
      
      





準備部分が完了したら、nginxの構成に進みます。 何が起こっているのかについてのコメント付きの単純化された構成を提供します。







この場合、バランサーとバックエンドの両方が同じサーバー上にあり、アップストリームが800xポートのローカルアドレスを指すため、コンテンツオプションを実装するだけで済みました。

ただし、実装の柔軟性により、必要な構成を構築できます。 順番に。







http {}



ブロックで、luaを初期化します。







コメント付きのコード:
 #     *.lua      lua_package_path "/usr/local/lib/lua/?.lua;;"; init_by_lua_block { --    --  ,     require "resty.core" collectgarbage("collect") -- just to collect any garbage }
      
      





*_lua_block



ブロックには、独自の構文と機能を持つlua-codeがすでに*_lua_block



てい*_lua_block









外部要求を受け入れるメインサーバー。







コメント付きのコード:
 server { listen 80; server_name test.domain.local; location / { #   cookie "upid"    —     if ($cookie_upid = "") { #    nginx-,     ID  set $upstream_id ''; rewrite_by_lua_block { --          nginx- math.randomseed(ngx.time()) --    ,     ( ) math.random(100) local num = math.random(100) --  ,       20% / 80% if num > 20 then ngx.var.upstream_id = 1 ngx.ctx.upid = ngx.var.upstream_id else ngx.var.upstream_id = 2 ngx.ctx.upid = ngx.var.upstream_id end -- ID    nginx- "upstream_id"   "upid"  ngx.ctx  lua,          } #    "upid"    ID #     ,         (  ),    add_header Set-Cookie "upid=$upstream_id; Domain=$host; Path=/"; } #       ,   ID  ngx.ctx.upid   if ($cookie_upid != "") { rewrite_by_lua_block { ngx.ctx.upid = ngx.var.cookie_upid } } #      upstream- proxy_pass http://ab_test; } }
      
      





luaを使用するアップストリームブロックは、nginxの組み込みロジックを置き換えます。







コメント付きのコード:
 upstream ab_test { # ,  nginx  .     server 127.0.0.1:8001; balancer_by_lua_block { local balancer = require "ngx.balancer" --    -- port  ,     ID  local host = "127.0.0.1" local port = 8000 + ngx.ctx.upid --   upstream     local ok, err = balancer.set_current_peer(host, port) if not ok then ngx.log(ngx.ERR, "failed to set the current peer: ", err) return ngx.exit(500) end --    ,  ,   ,      } }
      
      





まあ、シンプルなデモバックエンドは、最終的に顧客に提供されます。







コメントなしのコード:
 server { listen 127.0.0.1:8001; server_name test.domain.local; location / { root /var/www/html; index index.html; } } server { listen 127.0.0.1:8002; server_name test.domain.local; location / { root /var/www/html; index index2.html; } }
      
      





nginx-aがこの構成で開始すると、警告がログに分類されます。







 use of lua-resty-core with LuaJIT 2.0 is not recommended; use LuaJIT 2.1+ instead while connecting to upstream
      
      





これは、必要なバージョンを組み立ててインストールすることで削除できます。 しかし、2.0(libluajit-5.1-2)でも機能します。

これで、ブラウザと開発者ツールを使用して、サーバーとCookieの設定を確認できます。







したがって、テストと統計に必要な柔軟性が得られました。 バックエンドが正常に機能するために必要なクライアントセッションを保存します。 まあ、ちょうど面白い経験。







PS同様のタスクは、セッションを考慮してバランスを取ることができるhaproxyを使用するなど、他の方法で解決できます。 または、クライアントを分離するには、 ngx_http_split_clients_moduleを使用し、 mapを使用して他の値に応じていくつかの値マップします。

ただし、クライアントの配布とバックエンドの選択のオプションを使用すると、システムをより柔軟に構成できます。 また、必要に応じて、さまざまなロジックを作品に追加します。 ただし、現在のシステムを再構築することはありません。







ご清聴ありがとうございました。








All Articles