Nginx lua
Upcoming SlideShare
Loading in...5
×
 

Nginx lua

on

  • 2,854 views

 

Statistics

Views

Total Views
2,854
Views on SlideShare
2,808
Embed Views
46

Actions

Likes
10
Downloads
15
Comments
0

3 Embeds 46

http://tech.akat.info 36
https://twitter.com 8
https://translate.googleusercontent.com 2

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Nginx lua Nginx lua Presentation Transcript

    • nginxとLuaの話 moriyoshi
    • Introduction
    • nginxとは カザフスタン出身のИгорь Сысоевさん (43) によっ て開発されたHTTPサーバ 2002年より開発がスタート、2004年に公開
    • Luaとは ブラジルの Pontifical Catholic University of Rio で開発されているプログラミング言語 埋め込み型のプログラミング言語として開発され、 ゲーム業界を中心に浸透、現在は汎用的なプログラ ミング言語として一定の地位を得ている ガーベジコレクション、コルーチン
    • nginx-lua nginxでLuaを使うためのモジュール nginxのモジュールで行えるような各種カスタマイズ をLuaで記述可能 https://github.com/chaoslawful/lua-nginxmodule/
    • 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 あとこれらのビルドに必要なライブラリ一通り ものすごく楽できるので使おう
    • nginxのリクエスト処理フローと カスタマイズポイント
    • nginxのライフサイクル 初期化 イベントループ 後始末
    • 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 等
    • nginxのカスタマイズポイント 初期化フェーズ nginxの起動直後、サーバとして動作し始める前に 呼ばれる init_by_lua / init_by_lua_file
    • 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
    • nginxのカスタマイズポイント content handler リクエストに基づいてレスポンスを生成する content_by_lua / content_by_lua_file logフェーズ アクセスログを記録する log_by_lua / log_by_lua_file
    • nginxのカスタマイズポイント output filter nginxがレスポンスを返す直前に呼ばれる body_filter_by_lua / body_filter_by_lua_file header_filter_by_lua / header_filter_by_lua_file
    • nginx_luaを使うにあたり 覚えておくとよいこと (チートシート)
    • リクエスト関連 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のみ)
    • レスポンス関連 ngx.say - レスポンスボディを返す ngx.header[”XXX”] - レスポンスヘッダを設定す る ngx.exit() - リクエストの処理を終了して、レスポ ンスコードをクライアントに返す
    • 組み込み関数 ngx.time() / ngx.now() - 現在時刻を取得 ngx.timer.at() - JSのsetTimeout()みたいなもの ngx.exec() - 内部リダイレクトを行う ngx.location.capture() - サブリクエストを生 成し、その結果をLuaスクリプト内部で利用できる 外部のWebサーバのレスポンスを簡易的に取得す るのに... 内部的なHTTPレスポンスをフィルタするのに...
    • 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 "; }
    • 共有メモリ (ngx.shared) ngx.shared[”XXX”] - リクエスト間で共有される key-value dictionaryを取得する Redisなど使うまでもない場合に有用
    • 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)) '; } } }
    • サンプル
    • rewrite_by_lua アップストリームにリクエストを投げるときに、 xkeyというパラメータを付加する location /foo { rewrite_by_lua " ngx.req.set_uri_args({ xkey = "xxx" }); "; proxy_pass http://some_upstream; }
    • 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; }
    • 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 "; }
    • header_filter_by_lua レスポンスヘッダにX-Powered-Byを強制付加 location /foo { header_filter_by_lua " ngx.header["X-Powered-By"] = "PHP 7.0.0" "; }
    • ありがとうございました
    • Appendix: Lua基礎文法
    • 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")
    • 数値型・文字列・ブール型 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
    • テーブル 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
    • 関数 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
    • 繰り返し処理 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
    • イテレータ関数 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
    • 正規表現 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”