Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Nginx lua

8,571 views

Published on

Published in: Technology

Nginx lua

  1. 1. nginxとLuaの話 moriyoshi
  2. 2. Introduction
  3. 3. nginxとは カザフスタン出身のИгорь Сысоевさん (43) によっ て開発されたHTTPサーバ 2002年より開発がスタート、2004年に公開
  4. 4. Luaとは ブラジルの Pontifical Catholic University of Rio で開発されているプログラミング言語 埋め込み型のプログラミング言語として開発され、 ゲーム業界を中心に浸透、現在は汎用的なプログラ ミング言語として一定の地位を得ている ガーベジコレクション、コルーチン
  5. 5. nginx-lua nginxでLuaを使うためのモジュール nginxのモジュールで行えるような各種カスタマイズ をLuaで記述可能 https://github.com/chaoslawful/lua-nginxmodule/
  6. 6. OpenResty nginx-lua の現在のメンテナの agentzh (章亦春さ ん) が提供しているバンドル つぎのモジュールが全部入り array-var / auth-request / coolkit / echo / encrypted-session / forminput / headers-more / iconv-nginx / lua / memc / postgres / redis / redis2 / set-misc / srcache / xss あとこれらのビルドに必要なライブラリ一通り ものすごく楽できるので使おう
  7. 7. nginxのリクエスト処理フローと カスタマイズポイント
  8. 8. nginxのライフサイクル 初期化 イベントループ 後始末
  9. 9. nginxのリクエスト処理フロー リクエスト post read server rewrite rewrite等 location location rewrite if / set / rewrite等 preaccess / access content handler limit_req / allow / deny / auth_basic 等 autoindex / proxy_pass 等 output filter log レスポンス access_log 等
  10. 10. nginxのカスタマイズポイント 初期化フェーズ nginxの起動直後、サーバとして動作し始める前に 呼ばれる init_by_lua / init_by_lua_file
  11. 11. nginxのカスタマイズポイント rewriteフェーズ (1) rewriteが行われる前に呼ばれる set_by_lua / set_by_lua_file rewriteフェーズ (2) accessフェーズの直前に呼ばれる rewrite_by_lua / rewrite_by_lua_file accessフェーズ content handlerをディスパッチする前に呼ばれる access_by_lua / access_by_lua_file
  12. 12. nginxのカスタマイズポイント content handler リクエストに基づいてレスポンスを生成する content_by_lua / content_by_lua_file logフェーズ アクセスログを記録する log_by_lua / log_by_lua_file
  13. 13. nginxのカスタマイズポイント output filter nginxがレスポンスを返す直前に呼ばれる body_filter_by_lua / body_filter_by_lua_file header_filter_by_lua / header_filter_by_lua_file
  14. 14. nginx_luaを使うにあたり 覚えておくとよいこと (チートシート)
  15. 15. リクエスト関連 ngx.var.XXX - nginx変数$XXXの取得 ngx.var.uri - リクエストURI ngx.var[1] ... ngx.var[n] - locationのマッ チ ($1...n) ngx.req.get_uri_args() - リクエストURIのパ ラメータ部分をテーブルで ngx.req.get_headers() - リクエストヘッダを取 得 ngx.req.get_post_args() - POSTパラメータを パース (ngx.req.read_post() を事前に呼んでお く / application/x-www-form-urlencodedのみ)
  16. 16. レスポンス関連 ngx.say - レスポンスボディを返す ngx.header[”XXX”] - レスポンスヘッダを設定す る ngx.exit() - リクエストの処理を終了して、レスポ ンスコードをクライアントに返す
  17. 17. 組み込み関数 ngx.time() / ngx.now() - 現在時刻を取得 ngx.timer.at() - JSのsetTimeout()みたいなもの ngx.exec() - 内部リダイレクトを行う ngx.location.capture() - サブリクエストを生 成し、その結果をLuaスクリプト内部で利用できる 外部のWebサーバのレスポンスを簡易的に取得す るのに... 内部的なHTTPレスポンスをフィルタするのに...
  18. 18. ngx.location.capture /internalのレスポンスに文字列 OOPS が 含まれていたら、/oops.html にリダイレクト location = /internal { internal; resolver 8.8.8.8; proxy_pass http://determiner.example.com; } location /foo { rewrite_by_lua " res = ngx.location.capture("/internal") local m, err = ngx.re.match("OOPS", res.body) if m then return ngx.redirect("/oops.html") end "; }
  19. 19. 共有メモリ (ngx.shared) ngx.shared[”XXX”] - リクエスト間で共有される key-value dictionaryを取得する Redisなど使うまでもない場合に有用
  20. 20. ngx.shared 簡易的なカウンタ: /inc へのアクセスでインク リメント http { lua_shared_dict counter 12k; server { listen 8080; location /reset { content_by_lua ' ngx.shared.counter:set("value", 0) ngx.say("counter reset") '; } location /inc { content_by_lua ' local value = ngx.shared.counter:get("value") ngx.shared.counter:set("value", value + 1) ngx.say("count = " .. tostring(value)) '; } } }
  21. 21. サンプル
  22. 22. rewrite_by_lua アップストリームにリクエストを投げるときに、 xkeyというパラメータを付加する location /foo { rewrite_by_lua " ngx.req.set_uri_args({ xkey = "xxx" }); "; proxy_pass http://some_upstream; }
  23. 23. rewrite_by_lua 認証のかかったS3をアップストリームとして使う location /foo { set $bucket "hoge"; set $access_key "XXXXXX"; set $secret_key "YYYYYY"; rewrite_by_lua ' local date = ngx.http_time(ngx.time()) local string_to_sign = ngx.req.get_method() .. "n nn" .. date .. "n/" .. ngx.var.bucket .. "/" .. ngx.var[1] ngx.req.set_header("Date", date) ngx.req.set_header("Authorization", "AWS " .. ngx.var.access_key .. ":" .. ngx.encode_base64(ngx.hmac_sha1(ngx.var.secret_key, string_to_sign))) '; proxy_pass http://$bucket.s3.amazonaws.com/$1; }
  24. 24. acess_by_lua 日本時間の9∼21時以外のアクセスを禁止する location /foo { access_by_lua " local t = ngx.time() % 86400 if t >= 3600 * 12 then ngx.exit(ngx.HTTP_FORBIDDEN) end "; }
  25. 25. header_filter_by_lua レスポンスヘッダにX-Powered-Byを強制付加 location /foo { header_filter_by_lua " ngx.header["X-Powered-By"] = "PHP 7.0.0" "; }
  26. 26. ありがとうございました
  27. 27. Appendix: Lua基礎文法
  28. 28. Hello World function hello() local table = {"h", "e", "l", "l", "o"} local hello = "" for _, c in ipairs(table) do hello = hello .. c end return hello end print(hello(), "world")
  29. 29. 数値型・文字列・ブール型 a = 1 b = (a + 1) * 2 c = b / 3 -- c = 1.33333333... d = "string" e = f .. "string" -- e = "stringstring" f = e + 3 -- ERROR g = "1" + "2" -- g == 3, type(j) == "number" h = true or false -- true i = true and false -- false
  30. 30. テーブル a = { 1, 2, 3, 4, 5 } print(a[1], a[2], a[3]) -- 1 b = { a=1, b=2, c=3, d=4, e=5 print(b["a"], b["b"], b["c"]) print(b.a, b.b, b.c) -- 1 2 2 3 } -- 1 3 2 3
  31. 31. 関数 function fibo(n) if n == 0 then return 0 elseif n == 1 then return 1 else return fibo(n - 2) + fibo(n - 1) end end print(fibo(10)) -- 55
  32. 32. 繰り返し処理 for i = 0, 9, 1 do print(i) end -- 0 / 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 for i, v in ipairs({ 0, 1, 2, 3 }) do print(i, v) end -- 1, 0 / 2, 1 / 3, 2 / 4, 3 for k, v in pairs({ a=0, b=1, c=2, d=3 }) do print(k, v) end -- ”a”, 0 / ”b”, 1 / ”c”, 2 / ”d”, 3
  33. 33. イテレータ関数 i = 0 function iterate() i = i + 1 if i < 10 then return i end end for k in iterate do print(k) end -- 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9
  34. 34. 正規表現 a = "abcdef" beg, end_, capture = string.find(a, "([abc]+)") print(beg, end_, capture) -- 1, 3, "abc" b = string.gsub(a, "[de]", "*") print(b) -- "abc**f" c = "abc def ghi jkl" for m in string.gmatch(c, "([a-z]+)") do print(m) end -- ”abc” / ”def” / ”ghi” / ”jkl”

×