日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Nginx >内容正文

Nginx

第二章 OpenResty(Nginx+Lua)开发入门

發布時間:2024/9/20 Nginx 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第二章 OpenResty(Nginx+Lua)开发入门 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Nginx入門

本文目的是學習Nginx+Lua開發,對于Nginx基本知識可以參考如下文章:

nginx啟動、關閉、重啟

http://www.cnblogs.com/derekchen/archive/2011/02/17/1957209.html

agentzh 的 Nginx 教程

http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html

Nginx+Lua入門

http://17173ops.com/2013/11/01/17173-ngx-lua-manual.shtml

nginx 配置指令的執行順序

http://zhongfox.github.io/blog/server/2013/05/15/nginx-exec-order/

nginx與lua的執行順序和步驟說明

http://www.mrhaoting.com/?p=157

Nginx配置文件nginx.conf中文詳解

http://www.ha97.com/5194.html

Tengine的Nginx開發從入門到精通

http://tengine.taobao.org/book/

官方文檔

http://wiki.nginx.org/Configuration

?

Lua入門

本文目的是學習Nginx+Lua開發,對于Lua基本知識可以參考如下文章:

Lua簡明教程

http://coolshell.cn/articles/10739.html

lua在線lua學習教程

http://book.luaer.cn/

Lua 5.1 參考手冊

http://www.codingnow.com/2000/download/lua_manual.html

Lua5.3 參考手冊

http://cloudwu.github.io/lua53doc/

Nginx Lua API

和一般的Web Server類似,我們需要接收請求、處理并輸出響應。而對于請求我們需要獲取如請求參數、請求頭、Body體等信息;而對于處理就是調用相應的Lua代碼即可;輸出響應需要進行響應狀態碼、響應頭和響應內容體的輸出。因此我們從如上幾個點出發即可。

?

接收請求

1、example.conf配置文件?

Java代碼??
  • location?~?/lua_request/(\d+)/(\d+)?{??
  • ????#設置nginx變量??
  • ????set?$a?$1;???
  • ????set?$b?$host;??
  • ????default_type?"text/html";??
  • ????#nginx內容處理??
  • ????content_by_lua_file?/usr/example/lua/test_request.lua;??
  • ????#內容體處理完成后調用??
  • ????echo_after_body?"ngx.var.b?$b";??
  • }??
  • 2、test_request.lua?

    Java代碼??
  • --nginx變量??
  • local?var?=?ngx.var??
  • ngx.say("ngx.var.a?:?",?var.a,?"<br/>")??
  • ngx.say("ngx.var.b?:?",?var.b,?"<br/>")??
  • ngx.say("ngx.var[2]?:?",?var[2],?"<br/>")??
  • ngx.var.b?=?2;??
  • ??
  • ngx.say("<br/>")??
  • ??
  • --請求頭??
  • local?headers?=?ngx.req.get_headers()??
  • ngx.say("headers?begin",?"<br/>")??
  • ngx.say("Host?:?",?headers["Host"],?"<br/>")??
  • ngx.say("user-agent?:?",?headers["user-agent"],?"<br/>")??
  • ngx.say("user-agent?:?",?headers.user_agent,?"<br/>")??
  • for?k,v?in?pairs(headers)?do??
  • ????if?type(v)?==?"table"?then??
  • ????????ngx.say(k,?"?:?",?table.concat(v,?","),?"<br/>")??
  • ????else??
  • ????????ngx.say(k,?"?:?",?v,?"<br/>")??
  • ????end??
  • end??
  • ngx.say("headers?end",?"<br/>")??
  • ngx.say("<br/>")??
  • ??
  • --get請求uri參數??
  • ngx.say("uri?args?begin",?"<br/>")??
  • local?uri_args?=?ngx.req.get_uri_args()??
  • for?k,?v?in?pairs(uri_args)?do??
  • ????if?type(v)?==?"table"?then??
  • ????????ngx.say(k,?"?:?",?table.concat(v,?",?"),?"<br/>")??
  • ????else??
  • ????????ngx.say(k,?":?",?v,?"<br/>")??
  • ????end??
  • end??
  • ngx.say("uri?args?end",?"<br/>")??
  • ngx.say("<br/>")??
  • ??
  • --post請求參數??
  • ngx.req.read_body()??
  • ngx.say("post?args?begin",?"<br/>")??
  • local?post_args?=?ngx.req.get_post_args()??
  • for?k,?v?in?pairs(post_args)?do??
  • ????if?type(v)?==?"table"?then??
  • ????????ngx.say(k,?"?:?",?table.concat(v,?",?"),?"<br/>")??
  • ????else??
  • ????????ngx.say(k,?":?",?v,?"<br/>")??
  • ????end??
  • end??
  • ngx.say("post?args?end",?"<br/>")??
  • ngx.say("<br/>")??
  • ??
  • --請求的http協議版本??
  • ngx.say("ngx.req.http_version?:?",?ngx.req.http_version(),?"<br/>")??
  • --請求方法??
  • ngx.say("ngx.req.get_method?:?",?ngx.req.get_method(),?"<br/>")??
  • --原始的請求頭內容??
  • ngx.say("ngx.req.raw_header?:?",??ngx.req.raw_header(),?"<br/>")??
  • --請求的body內容體??
  • ngx.say("ngx.req.get_body_data()?:?",?ngx.req.get_body_data(),?"<br/>")??
  • ngx.say("<br/>")??
  • ngx.var?: nginx變量,如果要賦值如ngx.var.b = 2,此變量必須提前聲明;另外對于nginx location中使用正則捕獲的捕獲組可以使用ngx.var[捕獲組數字]獲取;

    ngx.req.get_headers:獲取請求頭,默認只獲取前100,如果想要獲取所以可以調用ngx.req.get_headers(0);獲取帶中劃線的請求頭時請使用如headers.user_agent這種方式;如果一個請求頭有多個值,則返回的是table;

    ngx.req.get_uri_args:獲取url請求參數,其用法和get_headers類似;

    ngx.req.get_post_args:獲取post請求內容體,其用法和get_headers類似,但是必須提前調用ngx.req.read_body()來讀取body體(也可以選擇在nginx配置文件使用lua_need_request_body on;開啟讀取body體,但是官方不推薦);

    ngx.req.raw_header:未解析的請求頭字符串;

    ngx.req.get_body_data:為解析的請求body體內容字符串。

    ?

    如上方法處理一般的請求基本夠用了。另外在讀取post內容體時根據實際情況設置client_body_buffer_size和client_max_body_size來保證內容在內存而不是在文件中。

    ?

    使用如下腳本測試

    Java代碼??
  • wget?--post-data?'a=1&b=2'?'http://127.0.0.1/lua_request/1/2?a=3&b=4'?-O?-???
  • ?

    輸出響應?

    1.1、example.conf配置文件

    Java代碼??
  • location?/lua_response_1?{??
  • ????default_type?"text/html";??
  • ????content_by_lua_file?/usr/example/lua/test_response_1.lua;??
  • }??
  • 1.2、test_response_1.lua?

    Java代碼??
  • --寫響應頭??
  • ngx.header.a?=?"1"??
  • --多個響應頭可以使用table??
  • ngx.header.b?=?{"2",?"3"}??
  • --輸出響應??
  • ngx.say("a",?"b",?"<br/>")??
  • ngx.print("c",?"d",?"<br/>")??
  • --200狀態碼退出??
  • return?ngx.exit(200)??
  • ngx.header:輸出響應頭;

    ngx.print:輸出響應內容體;

    ngx.say:通ngx.print,但是會最后輸出一個換行符;

    ngx.exit:指定狀態碼退出。

    ?

    2.1、example.conf配置文件

    Java代碼??
  • location?/lua_response_2?{??
  • ????default_type?"text/html";??
  • ????content_by_lua_file?/usr/example/lua/test_response_2.lua;??
  • }??
  • ?

    2.2、test_response_2.lua

    Java代碼??
  • ngx.redirect("http://jd.com",?302)??
  • ngx.redirect:重定向;?

    ?

    ngx.status=狀態碼,設置響應的狀態碼;ngx.resp.get_headers()獲取設置的響應狀態碼;ngx.send_headers()發送響應狀態碼,當調用ngx.say/ngx.print時自動發送響應狀態碼;可以通過ngx.headers_sent=true判斷是否發送了響應狀態碼。

    ?

    其他API

    1、example.conf配置文件

    Java代碼??
  • location?/lua_other?{??
  • ????default_type?"text/html";??
  • ????content_by_lua_file?/usr/example/lua/test_other.lua;??
  • }??
  • ?

    2、test_other.lua

    Java代碼??
  • --未經解碼的請求uri??
  • local?request_uri?=?ngx.var.request_uri;??
  • ngx.say("request_uri?:?",?request_uri,?"<br/>");??
  • --解碼??
  • ngx.say("decode?request_uri?:?",?ngx.unescape_uri(request_uri),?"<br/>");??
  • --MD5??
  • ngx.say("ngx.md5?:?",?ngx.md5("123"),?"<br/>")??
  • --http?time??
  • ngx.say("ngx.http_time?:?",?ngx.http_time(ngx.time()),?"<br/>")??
  • ?

    ngx.escape_uri/ngx.unescape_uri?: uri編碼解碼;

    ngx.encode_args/ngx.decode_args:參數編碼解碼;

    ngx.encode_base64/ngx.decode_base64:BASE64編碼解碼;

    ngx.re.match:nginx正則表達式匹配;

    ?

    更多Nginx Lua API請參考?http://wiki.nginx.org/HttpLuaModule#Nginx_API_for_Lua。

    ?

    Nginx全局內存

    使用過如Java的朋友可能知道如Ehcache等這種進程內本地緩存,Nginx是一個Master進程多個Worker進程的工作方式,因此我們可能需要在多個Worker進程中共享數據,那么此時就可以使用ngx.shared.DICT來實現全局內存共享。

    ?

    1、首先在nginx.conf的http部分分配內存大小

    Java代碼??
  • #共享全局變量,在所有worker間共享??
  • lua_shared_dict?shared_data?1m;??
  • ?

    2、example.conf配置文件

    Java代碼??
  • location?/lua_shared_dict?{??
  • ????default_type?"text/html";??
  • ????content_by_lua_file?/usr/example/lua/test_lua_shared_dict.lua;??
  • }??
  • 3、?test_lua_shared_dict.lua

    Java代碼??
  • --1、獲取全局共享內存變量??
  • local?shared_data?=?ngx.shared.shared_data??
  • ??
  • --2、獲取字典值??
  • local?i?=?shared_data:get("i")??
  • if?not?i?then??
  • ????i?=?1??
  • ????--3、惰性賦值??
  • ????shared_data:set("i",?i)??
  • ????ngx.say("lazy?set?i?",?i,?"<br/>")??
  • end??
  • --遞增??
  • i?=?shared_data:incr("i",?1)??
  • ngx.say("i=",?i,?"<br/>")??
  • 更多API請參考http://wiki.nginx.org/HttpLuaModule#ngx.shared.DICT。?

    ?

    ?

    到此基本的Nginx Lua API就學完了,對于請求處理和輸出響應如上介紹的API完全夠用了,更多API請參考官方文檔。

    ?

    Nginx Lua模塊指令

    Nginx共11個處理階段,而相應的處理階段是可以做插入式處理,即可插拔式架構;另外指令可以在http、server、server if、location、location if幾個范圍進行配置:

    指令

    所處處理階段

    使用范圍

    解釋

    init_by_lua

    init_by_lua_file

    loading-config

    http

    nginx Master進程加載配置時執行;

    通常用于初始化全局配置/預加載Lua模塊

    init_worker_by_lua

    init_worker_by_lua_file

    starting-worker

    http

    每個Nginx Worker進程啟動時調用的計時器,如果Master進程不允許則只會在init_by_lua之后調用;

    通常用于定時拉取配置/數據,或者后端服務的健康檢查

    set_by_lua

    set_by_lua_file

    rewrite

    server,server if,location,location if

    設置nginx變量,可以實現復雜的賦值邏輯;此處是阻塞的,Lua代碼要做到非常快;

    rewrite_by_lua

    rewrite_by_lua_file

    rewrite tail

    http,server,location,location if

    rrewrite階段處理,可以實現復雜的轉發/重定向邏輯;

    access_by_lua

    access_by_lua_file

    access tail

    http,server,location,location if

    請求訪問階段處理,用于訪問控制

    content_by_lua

    content_by_lua_file

    content

    location,location if

    內容處理器,接收請求處理并輸出響應

    header_filter_by_lua

    header_filter_by_lua_file

    output-header-filter

    http,server,location,location if

    設置header和cookie

    body_filter_by_lua

    body_filter_by_lua_file

    output-body-filter

    http,server,location,location if

    對響應數據進行過濾,比如截斷、替換。

    log_by_lua

    log_by_lua_file

    log

    http,server,location,location if

    log階段處理,比如記錄訪問量/統計平均響應時間

    ?

    更詳細的解釋請參考http://wiki.nginx.org/HttpLuaModule#Directives。如上指令很多并不常用,因此我們只拿其中的一部分做演示。

    ?

    init_by_lua

    每次Nginx重新加載配置時執行,可以用它來完成一些耗時模塊的加載,或者初始化一些全局配置;在Master進程創建Worker進程時,此指令中加載的全局變量會進行Copy-OnWrite,即會復制到所有全局變量到Worker進程。

    ?

    1、nginx.conf配置文件中的http部分添加如下代碼

    Java代碼??
  • #共享全局變量,在所有worker間共享??
  • lua_shared_dict?shared_data?1m;??
  • ??
  • init_by_lua_file?/usr/example/lua/init.lua;??
  • ??

    2、init.lua

    Java代碼??
  • --初始化耗時的模塊??
  • local?redis?=?require?'resty.redis'??
  • local?cjson?=?require?'cjson'??
  • ??
  • --全局變量,不推薦??
  • count?=?1??
  • ??
  • --共享全局內存??
  • local?shared_data?=?ngx.shared.shared_data??
  • shared_data:set("count",?1)??
  • ?

    3、test.lua

    Java代碼??
  • count?=?count?+?1??
  • ngx.say("global?variable?:?",?count)??
  • local?shared_data?=?ngx.shared.shared_data??
  • ngx.say(",?shared?memory?:?",?shared_data:get("count"))??
  • shared_data:incr("count",?1)??
  • ngx.say("hello?world")??
  • ???

    4、訪問如http://192.168.1.2/lua 會發現全局變量一直不變,而共享內存一直遞增

    global variable : 2 , shared memory : 8 hello world?

    ?

    另外注意一定在生產環境開啟lua_code_cache,否則每個請求都會創建Lua VM實例。

    ?

    init_worker_by_lua

    用于啟動一些定時任務,比如心跳檢查,定時拉取服務器配置等等;此處的任務是跟Worker進程數量有關系的,比如有2個Worker進程那么就會啟動兩個完全一樣的定時任務。

    ?

    1、nginx.conf配置文件中的http部分添加如下代碼

    Java代碼??
  • init_worker_by_lua_file?/usr/example/lua/init_worker.lua;??
  • ??

    2、init_worker.lua

    Java代碼??
  • local?count?=?0??
  • local?delayInSeconds?=?3??
  • local?heartbeatCheck?=?nil??
  • ??
  • heartbeatCheck?=?function(args)??
  • ???count?=?count?+?1??
  • ???ngx.log(ngx.ERR,?"do?check?",?count)??
  • ??
  • ???local?ok,?err?=?ngx.timer.at(delayInSeconds,?heartbeatCheck)??
  • ??
  • ???if?not?ok?then??
  • ??????ngx.log(ngx.ERR,?"failed?to?startup?heartbeart?worker...",?err)??
  • ???end??
  • end??
  • ??
  • heartbeatCheck()??
  • ngx.timer.at:延時調用相應的回調方法;ngx.timer.at(秒單位延時,回調函數,回調函數的參數列表);可以將延時設置為0即得到一個立即執行的任務,任務不會在當前請求中執行不會阻塞當前請求,而是在一個輕量級線程中執行。

    ?

    另外根據實際情況設置如下指令

    lua_max_pending_timers 1024; ?#最大等待任務數

    lua_max_running_timers 256; ? ?#最大同時運行任務數

    ?

    ?

    set_by_lua?

    設置nginx變量,我們用的set指令即使配合if指令也很難實現負責的賦值邏輯;

    ?

    1.1、example.conf配置文件

    Java代碼??
  • location?/lua_set_1?{??
  • ????default_type?"text/html";??
  • ????set_by_lua_file?$num?/usr/example/lua/test_set_1.lua;??
  • ????echo?$num;??
  • }??
  • set_by_lua_file:語法set_by_lua_file $var lua_file arg1 arg2...; 在lua代碼中可以實現所有復雜的邏輯,但是要執行速度很快,不要阻塞;

    ?

    1.2、test_set_1.lua

    Java代碼??
  • local?uri_args?=?ngx.req.get_uri_args()??
  • local?i?=?uri_args["i"]?or?0??
  • local?j?=?uri_args["j"]?or?0??
  • ??
  • return?i?+?j??
  • 得到請求參數進行相加然后返回。

    ?

    訪問如http://192.168.1.2/lua_set_1?i=1&j=10進行測試。 如果我們用純set指令是無法實現的。

    ?

    再舉個實際例子,我們實際工作時經常涉及到網站改版,有時候需要新老并存,或者切一部分流量到新版

    ?

    2.1、首先在example.conf中使用map指令來映射host到指定nginx變量,方便我們測試

    Java代碼??
  • ############?測試時使用的動態請求??
  • map?$host?$item_dynamic?{??
  • ????default?????????????????????"0";??
  • ????item2014.jd.com????????????"1";??
  • }??
  • 如綁定hosts

    192.168.1.2 item.jd.com;

    192.168.1.2 item2014.jd.com;

    ?

    此時我們想訪問item2014.jd.com時訪問新版,那么我們可以簡單的使用如

    Java代碼??
  • if?($item_dynamic?=?"1")?{??
  • ???proxy_pass?http://new;??
  • }??
  • proxy_pass?http://old;??
  • ?

    但是我們想把商品編號為為8位(比如品類為圖書的)沒有改版完成,需要按照相應規則跳轉到老版,但是其他的到新版;雖然使用if指令能實現,但是比較麻煩,基本需要這樣

    Java代碼??
  • set?jump?"0";??
  • if($item_dynamic?=?"1")?{??
  • ????set?$jump?"1";??
  • }??
  • if(uri?~?"^/6[0-9]{7}.html")?{??
  • ???set?$jump?"${jump}2";??
  • }??
  • #非強制訪問新版,且訪問指定范圍的商品??
  • if?(jump?==?"02")?{??
  • ???proxy_pass?http://old;??
  • }??
  • proxy_pass?http://new;??
  • 以上規則還是比較簡單的,如果涉及到更復雜的多重if/else或嵌套if/else實現起來就更痛苦了,可能需要到后端去做了;此時我們就可以借助lua了:

    Java代碼??
  • set_by_lua?$to_book?'??
  • ?????local?ngx_match?=?ngx.re.match??
  • ?????local?var?=?ngx.var??
  • ?????local?skuId?=?var.skuId??
  • ?????local?r?=?var.item_dynamic?~=?"1"?and?ngx.re.match(skuId,?"^[0-9]{8}$")??
  • ?????if?r?then?return?"1"?else?return?"0"?end;??
  • ';??
  • set_by_lua?$to_mvd?'??
  • ?????local?ngx_match?=?ngx.re.match??
  • ?????local?var?=?ngx.var??
  • ?????local?skuId?=?var.skuId??
  • ?????local?r?=?var.item_dynamic?~=?"1"?and?ngx.re.match(skuId,?"^[0-9]{9}$")??
  • ?????if?r?then?return?"1"?else?return?"0"?end;??
  • ';??
  • #自營圖書??
  • if?($to_book)?{??
  • ????proxy_pass?http://127.0.0.1/old_book/$skuId.html;??
  • }??
  • #自營音像??
  • if?($to_mvd)?{??
  • ????proxy_pass?http://127.0.0.1/old_mvd/$skuId.html;??
  • }??
  • #默認??
  • proxy_pass?http://127.0.0.1/proxy/$skuId.html;??
  • ??

    ?rewrite_by_lua?

    執行內部URL重寫或者外部重定向,典型的如偽靜態化的URL重寫。其默認執行在rewrite處理階段的最后。

    ?

    1.1、example.conf配置文件

    Java代碼??
  • location?/lua_rewrite_1?{??
  • ????default_type?"text/html";??
  • ????rewrite_by_lua_file?/usr/example/lua/test_rewrite_1.lua;??
  • ????echo?"no?rewrite";??
  • }??
  • ?

    1.2、test_rewrite_1.lua

    Java代碼??
  • if?ngx.req.get_uri_args()["jump"]?==?"1"?then??
  • ???return?ngx.redirect("http://www.jd.com?jump=1",?302)??
  • end??
  • 當我們請求http://192.168.1.2/lua_rewrite_1時發現沒有跳轉,而請求http://192.168.1.2/lua_rewrite_1?jump=1時發現跳轉到京東首頁了。 此處需要301/302跳轉根據自己需求定義。

    ?

    2.1、example.conf配置文件

    Java代碼??
  • location?/lua_rewrite_2?{??
  • ????default_type?"text/html";??
  • ????rewrite_by_lua_file?/usr/example/lua/test_rewrite_2.lua;??
  • ????echo?"rewrite2?uri?:?$uri,?a?:?$arg_a";??
  • }??
  • ?

    2.2、test_rewrite_2.lua

    Java代碼??
  • if?ngx.req.get_uri_args()["jump"]?==?"1"?then??
  • ???ngx.req.set_uri("/lua_rewrite_3",?false);??
  • ???ngx.req.set_uri("/lua_rewrite_4",?false);??
  • ???ngx.req.set_uri_args({a?=?1,?b?=?2});??
  • end???
  • ngx.req.set_uri(uri, false):可以內部重寫uri(可以帶參數),等價于 rewrite ^ /lua_rewrite_3;通過配合if/else可以實現?rewrite ^ /lua_rewrite_3 break;這種功能;此處兩者都是location內部url重寫,不會重新發起新的location匹配;

    ngx.req.set_uri_args:重寫請求參數,可以是字符串(a=1&b=2)也可以是table;

    ?

    訪問如http://192.168.1.2/lua_rewrite_2?jump=0時得到響應

    rewrite2 uri : /lua_rewrite_2, a :

    ?

    訪問如http://192.168.1.2/lua_rewrite_2?jump=1時得到響應

    rewrite2 uri : /lua_rewrite_4, a : 1

    ?

    3.1、example.conf配置文件

    Java代碼??
  • location?/lua_rewrite_3?{??
  • ????default_type?"text/html";??
  • ????rewrite_by_lua_file?/usr/example/lua/test_rewrite_3.lua;??
  • ????echo?"rewrite3?uri?:?$uri";??
  • }??
  • ?

    3.2、test_rewrite_3.lua

    Java代碼??
  • if?ngx.req.get_uri_args()["jump"]?==?"1"?then??
  • ???ngx.req.set_uri("/lua_rewrite_4",?true);??
  • ???ngx.log(ngx.ERR,?"=========")??
  • ???ngx.req.set_uri_args({a?=?1,?b?=?2});??
  • end??
  • ngx.req.set_uri(uri, true):可以內部重寫uri,即會發起新的匹配location請求,等價于 rewrite ^ /lua_rewrite_4 last;此處看error log是看不到我們記錄的log。

    ?

    所以請求如http://192.168.1.2/lua_rewrite_3?jump=1會到新的location中得到響應,此處沒有/lua_rewrite_4,所以匹配到/lua請求,得到類似如下的響應

    global variable : 2 , shared memory : 1 hello world

    ?

    rewrite ^ /lua_rewrite_3; ? ? ? ? ? ? ? ? 等價于 ?ngx.req.set_uri("/lua_rewrite_3", false);

    rewrite ^ /lua_rewrite_3 break; ? ? ? 等價于 ?ngx.req.set_uri("/lua_rewrite_3", false); 加 if/else判斷/break/return

    rewrite ^ /lua_rewrite_4 last; ? ? ? ? ? 等價于 ?ngx.req.set_uri("/lua_rewrite_4", true);

    ?

    注意,在使用rewrite_by_lua時,開啟rewrite_log on;后也看不到相應的rewrite log。

    ?

    access_by_lua?

    用于訪問控制,比如我們只允許內網ip訪問,可以使用如下形式

    Java代碼??
  • allow?????127.0.0.1;??
  • allow?????10.0.0.0/8;??
  • allow?????192.168.0.0/16;??
  • allow?????172.16.0.0/12;??
  • deny??????all;??
  • ?

    1.1、example.conf配置文件

    Java代碼??
  • location?/lua_access?{??
  • ????default_type?"text/html";??
  • ????access_by_lua_file?/usr/example/lua/test_access.lua;??
  • ????echo?"access";??
  • }??
  • ?

    ?1.2、test_access.lua

    Java代碼??
  • if?ngx.req.get_uri_args()["token"]?~=?"123"?then??
  • ???return?ngx.exit(403)??
  • end??
  • 即如果訪問如http://192.168.1.2/lua_access?token=234將得到403 Forbidden的響應。這樣我們可以根據如cookie/用戶token來決定是否有訪問權限。

    ?

    ?

    content_by_lua???

    此指令之前已經用過了,此處就不講解了。

    ?

    另外在使用PCRE進行正則匹配時需要注意正則的寫法,具體規則請參考http://wiki.nginx.org/HttpLuaModule中的Special PCRE Sequences部分。還有其他的注意事項也請閱讀官方文檔。


    來源:http://jinnianshilongnian.iteye.com/blog/2186448

    總結

    以上是生活随笔為你收集整理的第二章 OpenResty(Nginx+Lua)开发入门的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 999在线观看视频 | 国产女18毛片多18精品 | 国产精品久久久午夜夜伦鲁鲁 | 国产一区二区三区四区五区美女 | 69视频网站 | 青青青在线免费观看 | 黄色福利视频网站 | 麻豆国产一区二区 | 久久久嫩草 | 中文字幕在线第一页 | 亚洲影院在线 | 嫩草视频一区二区三区 | 欧美性受xxxx白人性爽 | 国产精品一区免费 | av导航大全 | 一本色道久久加勒比精品 | 美女黄色一级视频 | 黄色不雅视频 | 亚洲一区免费看 | 久久久久久久久影院 | 麻豆三级 | 男人操女人下面视频 | 黄色永久网站 | 91精品国产一区二区无码 | 国产看真人毛片爱做a片 | 特黄视频在线观看 | 少妇野外性xx老女人野外性xx | 婷婷精品 | 精品一区二区久久久久久按摩 | 少妇2做爰hd韩国电影 | 免费色网址 | 欧洲精品码一区二区三区免费看 | 中文字字幕在线中文乱码 | 欧美在线免费观看 | 精品三级电影 | 嫩草影院永久入口 | 免费成人电影在线观看 | 狼人综合视频 | 91激情| av中文字幕一区二区三区 | 玩偶游戏在线观看免费 | 加勒比波多野结衣 | 色香蕉网站 | 免费看国产黄色 | 色妞网站 | 韩国中文字幕 | 亚洲国产清纯 | 伊人院| 美女无遮挡网站 | 成人午夜sm精品久久久久久久 | 亚洲精品成人无码毛片 | 韩国无码一区二区三区精品 | 性av网| 黄页在线播放 | 哪个网站可以看毛片 | 黄色动漫在线免费观看 | 欧美又粗又长 | 国产精品正在播放 | 久久人妻精品白浆国产 | 国产精品免费无遮挡无码永久视频 | 中文字幕123 | 国产麻豆久久 | 免费视频91 | 日韩av一区二区三区四区 | 国产亚洲成av人在线观看导航 | 黄色xxxxxx | 亚洲综合伊人 | 国产精品九色 | 少妇厨房愉情理伦bd在线观看 | 亚洲精品少妇久久久久久 | 一区二区视频免费看 | 特黄老太婆aa毛毛片 | 国产sm调教一区二区 | 欧美极品jizzhd欧美仙踪林 | 欧美色图另类 | 白浆av | 久久精品6 | 欧美黄色片网站 | 男女无套免费视频网站动漫 | 草色噜噜噜av在线观看香蕉 | 深夜视频在线观看免费 | 欧美日韩黄色片 | 国产一区欧美一区 | 日韩福利视频一区 | 亚洲网址在线 | 日韩一级理论片 | 亚洲av无码一区二区二三区软件 | 欧美日韩性生活 | 伊人久久爱 | 青青草手机在线观看 | 午夜福利电影一区二区 | 亚洲天堂福利视频 | 亚洲狠狠丁香婷婷综合久久久 | 精品久久久无码中文字幕 | 一区二区日本 | 丰满人妻一区二区三区四区 | 香蕉视频黄在线观看 | 蜜桃av影院 | 午夜精产品一区二区在线观看的 |