NGINXのTarantool用Luaコネクタの比較ストレステスト

最近、HaranにはTarantoolについての非常に多くの記事が掲載されています。データベースとアプリケーションサーバーは、さまざまな興味深いプロジェクトでMail.Ru Group、Avito、Yotaによって使用されています。 だから、私は思った-なぜ私たちは悪化していますか? それも試してみましょう。

私の専門的な変形により、次のケースを検討します。


このタスクにアプローチする方法は?

ユーザーの権利を確認するリソースの前にゲートウェイを配置してみましょう。チェックの結果に応じて、ユーザーにリソースへのアクセスを許可するかどうかを設定します。 ユーザー権限はTarantoolに保存されます。 マスターとマスターのレプリケーションがあり、ゲートウェイのクラスターを構築する必要がある場合に便利です。 NGINXをゲートウェイの基礎として使用します(Webサーバーを自分で記述しないでください...)。

NGINXは、「インテリジェンス」を追加して、ユーザーがどこに行くことができ、どこに行かないかを理解する必要があります。 これにはngx_http_auth_request_moduleを使用できますが、これをTarantoolと組み合わせる方法は明確ではありません。 OpenRestyの例を見てみましょう。Lua、つまりlua-nginx-moduleを使用して、ゲートウェイを知的化します。

NGINX内からTarantoolにアクセスするには、選択した言語の適切なドライバー、または「コネクター」が必要です。 Tarantoolの著者自身が、LuaからTarantoolへのコネクタが必要な場合は、アーキテクチャに何か問題があると書いています。 しかし、NGINX + Luaバンドルの場合、これは正当化される可能性があります。

グーグルは、最大3つの候補者の存在を示しています。


何を選ぶ? テストする必要があります。 それはします。

テストスタンド:




負荷ジェネレーターから、要求は安全なTLS形式でゲートウェイに送信されます(専門的な変形を忘れないでください)。 次に、NGINXはTLSを削除し、プレーンHTTPの形式で保護されたリソースに渡します。

試験機の機能


マシンと保護されたリソースの読み込み


(2台の同一の車)
CPU2xIntel Xeon E5 2680 @ 2.70GHz Sandy Bridge-EP / EX 32nm Technology 8コア/ 16スレッド
RAM32.0GB DDR3 @ 799MHz(11-11-11-28)
MBSupermicro X9DR3-F
ディスク223GB OCZ-VERTEX3(SSD)
OSDebian 8.9 x64(カーネル3.16.39-1)
Nginx1.12.1
仕事4.0.2-dirty [epoll] + GOST TLSパッチ

ゲートウェイ

CPU1 vCPU
RAM8 GB
プラットフォームVMWare Workstation 12.5
ホストCPUIntel Core i5 7600K 3.8 GHz
ホストRAM16 GB
ホストOSWindows 10 x64
Nginx1.12.1
lua-nginx-module最新のマスターブランチ

NGINX保護されたリソースの構成


珍しいことはありません-空のGIFだけです。

user nginx; worker_processes 32; error_log /var/log/ngate/nginx/error.log warn; pid /var/run/nginx.pid; worker_rlimit_nofile 65535; events { worker_connections 8192; } http { access_log /var/log/ngate/nginx/access.log main; keepalive_timeout 65; server { listen 80; server_name fast-ipsec2-db8; location / { root /var/www; index index.html index.htm; } location = /ff/empty_gif.gif { empty_gif; } } # end server } 

ゲートウェイNGINX構成:


 worker_processes 1; error_log /var/log/nginx/error.log warn; worker_rlimit_nofile 65535; events { worker_connections 8192; } http { include /etc/opt/nginx/mime.types; default_type text/html; sendfile on; keepalive_timeout 65; autoindex off; server_tokens off; lua_package_path '?.lua;/opt/lua/?.lua;'; # HTTPS server server { listen 443 ssl; server_name perf-test-1; ssl_certificate www.example.com.crt; ssl_certificate_key www.example.com.key; ssl_protocols TLSv1; ssl_ciphers HIGH:!aNULL:!MD5; if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; } # Local Tarantool Node set $ng_local_tnt_addr '127.0.0.1'; set $ng_local_tnt_port 3320; # ff location /ff/ { proxy_pass http://fast-ipsec2-db8/ff/; access_by_lua_file /opt/lua/res_access.lua; } } # end server perf-test-1 } # end http 

次の行に注意してください。

 access_by_lua_file /opt/lua/res_access.lua; 

ここでユーザーの権利を確認します。

コード/opt/lua/res_access.lua


簡単です:

1.認証Cookieを抽出します。
2.ユーザーがアクセスしているリソースを理解するためのParsim要求。
3.受け取ったTarantoolの値を渡して、判断を下します-ユーザーに任せるかどうかを決めます。
4.タランツールの回答を処理します
5.応答に応じて、ユーザーを開始するか、「アクセス拒否」と発声します。
簡単にするために、記事の範囲外のアクセス権を仕事に任せ、常にユーザーにリソースを許可します。

 local auth_cookie_value = ngx.var.cookie_nginxauth if auth_cookie_value == nil then ngx.log(ngx.WARN, "Authentication cookie not provided.") ngx.exit(ngx.HTTP_NOT_FOUND) end local uri_root_regex = "(\\/[a-zA-Z0-9\\-\\._]+\\/)" local m, err = ngx.re.match(ngx.var.uri, uri_root_regex, "ai") if err then ngx.log(ngx.ERR, "Error in regexp: ", err) ngx.exit(ngx.HTTP_NOT_FOUND) end if m == nil then ngx.log(ngx.ERR, "Regexp returned nil value.") ngx.exit(ngx.HTTP_NOT_FOUND) end local uri_root = m[0] if uri_root == nil then ngx.log(ngx.ERR, "error in regexp") ngx.exit(ngx.HTTP_NOT_FOUND) end local tnt = require 'resty.tarantool' #local tnt = require 'tarantool-lua.tarantool' local tar, err = tnt:new({ host = ngx.var.ng_local_tnt_addr, port = ngx.var.ng_local_tnt_port, --Default value 2000 socket_timeout = 500, # connect_now = false, }) if not tar:connect() then ngx.log(ngx.ERR, "TNT connection failed.") ngx.exit(ngx.HTTP_NOT_FOUND) end local res, err = tar:call('check_access', {auth_cookie_value, uri_root}) if not tar:set_keepalive() then ngx.log(ngx.WARN, "TNT connection not set as keep-alive.") end if not res then ngx.log(ngx.ERR, "TNT call failed: " .. err) ngx.exit(ngx.HTTP_NOT_FOUND) end if res[1] ~= nil and res[1][1] == true then -- Access granted ngx.log(ngx.INFO, "Resource access granted: " .. uri_root) return else ngx.log(ngx.ERR, "Resource access denied: " .. uri_root) ngx.exit(ngx.HTTP_FORBIDDEN) end 

Tarantoolストアドプロシージャコード


許可Cookieは引き続き無視されるため、簡単にするために取得および形成のプロセスは考慮しません。

 local strict = require('strict') strict.on() function check_access(session_id, resource_name) if session_id == nil or resource_name == nil then return false end log.info('Access to resource ' .. resource_name .. ' granted.') return true end 

テスト方法


テストには、wrkユーティリティを使用します。 負荷テストで実証されており、TLSに加えて、Luaでスクリプトをサポートしています(ただし、現在は使用しません)。 機能のうち、wrkには切断不可能なTLSセッション再開機能があるため、ゲートウェイCPUは永続的なTLSハンドシェイクに浪費されません。 スループットではなく、1秒あたりのアクセス制御チェックのパフォーマンスをテストするために、保護されたリソースから最小サイズのファイル(43バイトを使用する空のGIF)を要求します。

テストを始めましょう。

候補1(lua-nginx-tarantool):


まったく機能しません。 ドキュメントに従って使用する場合は、

 local tnt = require 'lua-nginx-tarantool.tarantool' local tar, err = tnt:new({...}) 

エラーが表示されます:

 runtime error: /opt/lua/res_access.lua:33: attempt to index local 'tnt' (a boolean value) 

わかりません。

候補2(tarantool-lua):


 ./wrk -t32 -c32 -d30s --latency --timeout 10s -H "Host: perf-test-1" -H "Cookie: nginxauth=XXX " https://192.168.85.159/ff/empty_gif.gif Thread Stats Avg Stdev Max +/- Stdev Latency 252.12ms 248.32ms 514.22ms 31.13% Req/Sec 4.55 5.54 60.00 95.77% Latency Distribution 50% 21.75ms 75% 502.22ms 90% 503.61ms 99% 507.63ms 3767 requests in 30.04s, 1.33MB read Non-2xx or 3xx responses: 1868 Requests/sec: 125.40 Transfer/sec: 45.49KB 

まず、それだけでは不十分です。 1秒あたり125クエリのみ。

第二に-回答の半分以上-予想される200ではなく、何か他のもの。 これは何? 答えはerror_log NGIXNにあります。

 [error] 11856#0: *23410 [lua] res_access.lua:42: TNT connection failed. 

何かがおかしい-Tarantoolが接続を拒否するか、NGINXがそれらを消化できません。
しかし、もう一度試してください。

候補3(lua-resty-tarantool):


 ./wrk -t32 -c32 -d30s --latency --timeout 10s -H "Host: perf-test-1" -H "Cookie: nginxauth=XXX " https://192.168.85.159/ff/empty_gif.gif Thread Stats Avg Stdev Max +/- Stdev Latency 9.03ms 1.13ms 28.79ms 79.90% Req/Sec 110.13 10.43 131.00 75.49% Latency Distribution 50% 8.63ms 75% 9.46ms 90% 10.64ms 99% 11.81ms 105344 requests in 30.03s, 43.40MB read Requests/sec: 3508.50 Transfer/sec: 1.45MB 

わあ! 1秒あたり3500リクエストであり、単一のエラーではありません!
また、error_logでは、NGINXは無音です。

結論


彼の由緒ある年齢といくつかの欠点にもかかわらず、Candidate 3(lua-resty-tarantool)は明らかにリーダーであるだけでなく、生産における唯一のユースケースです。 また、実際のプロジェクトで特定のテクノロジーを使用するかどうかを決定する前に、さまざまなユースケースをテストする必要があると確信しました。

Source: https://habr.com/ru/post/J336252/


All Articles