<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # Nginx Lua 模塊指令 Nginx共11個處理階段,而相應的處理階段是可以做插入式處理,即可插拔式架構;另外指令可以在http、server、server if、location、location if幾個范圍進行配置: |指令|所處處理階段|使用范圍|解釋| | --- | --- | --- | --- | |init_by_lua<br/>init_by_lua_file|loading-config|http|nginx Master進程加載配置時執行;<br/>通常用于初始化全局配置/預加載Lua模塊| |init_worker_by_lua<br/>init_worker_by_lua_file|starting-worker|http|每個Nginx Worker進程啟動時調用的計時器,如果Master進程不允許則只會在init_by_lua之后調用;<br/>通常用于定時拉取配置/數據,或者后端服務的健康檢查| |set_by_lua<br/>set_by_lua_file|rewrite|server,server<br/>if,location,location if|設置nginx變量,可以實現復雜的賦值邏輯;此處是阻塞的,Lua代碼要做到非常快;| |rewrite_by_lua<br/>rewrite_by_lua_file|rewrite<br/>tail|http,server,location,location<br/>if|rrewrite階段處理,可以實現復雜的轉發/重定向邏輯;| |access_by_lua<br/>access_by_lua_file|access tail|http,server,location,location<br/>if|請求訪問階段處理,用于訪問控制| |content_by_lua<br/>content_by_lua_file|content|location,location<br/>if|內容處理器,接收請求處理并輸出響應| |header_filter_by_lua<br/>header_filter_by_lua_file|output-header-filter|http,server,location,location<br/>if|設置header和cookie| |body_filter_by_lua<br/>body_filter_by_lua_file|output-body-filter|http,server,location,location<br/>if|對響應數據進行過濾,比如截斷、替換。| |log_by_lua<br/>log_by_lua_file|log|http,server,location,location<br/>if|log階段處理,比如記錄訪問量/統計平均響應時間| 更詳細的解釋請參考[http://wiki.nginx.org/HttpLuaModule#Directives](http://wiki.nginx.org/HttpLuaModule#Directives)。如上指令很多并不常用,因此我們只拿其中的一部分做演示。 ## init_by_lua 每次Nginx重新加載配置時執行,可以用它來完成一些耗時模塊的加載,或者初始化一些全局配置;在Master進程創建Worker進程時,此指令中加載的全局變量會進行Copy-OnWrite,即會復制到所有全局變量到Worker進程。 #### 1. nginx.conf配置文件中的http部分添加如下代碼 ``` #共享全局變量,在所有worker間共享 lua_shared_dict?shared_data?1m; init_by_lua_file?/usr/example/lua/init.lua; ``` #### 2. init.lua ``` -- 初始化耗時的模塊 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 ``` 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://127.0.0.1/lua 會發現全局變量一直不變,而共享內存一直遞增 global variable : 2 , shared memory : 8 hello world 很不幸,上面只是理論結果,實際本人測試為全局變量會隨著刷新而改動,永遠比共享內存大1,懷疑nginx新的版本更新了全局變量的定義 <br/> 另外注意一定在生產環境開啟lua\_code\_cache,否則每個請求都會創建Lua VM實例。 ## init_worker_by_lua 用于啟動一些定時任務,比如心跳檢查,定時拉取服務器配置等等;此處的任務是跟Worker進程數量有關系的,比如有2個Worker進程那么就會啟動兩個完全一樣的定時任務。 #### 1. nginx.conf配置文件中的http部分添加如下代碼 ``` init_worker_by_lua /usr/openResty/lua/init_worker.lua; ``` #### 2. init_worker.lua ``` 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 openResty.conf配置文件 ``` location /lua_set_1 { default_type "text/html"; set_by_lua_file $num /usr/openResty/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 ``` 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://127.0.0.1/lua_set_1?i=1&j=10進行測試。 如果我們用純set指令是無法實現的。 再舉個實際例子,我們實際工作時經常涉及到網站改版,有時候需要新老并存,或者切一部分流量到新版 2.1 在openResty.conf中使用map指令來映射host到指定nginx變量,方便我們測試 ``` ############ 測試時使用的動態請求 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時訪問新版,那么我們可以簡單的使用如 ``` if?($item_dynamic?=?"1")?{?? ???proxy_pass?http://new; }?? proxy_pass?http://old; ``` 但是我們想把商品編號為為8位(比如品類為圖書的)沒有改版完成,需要按照相應規則跳轉到老版,但是其他的到新版;雖然使用if指令能實現,但是比較麻煩,基本需要這樣 ``` 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了: ``` 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 openResty.conf配置文件 ``` location /lua_rewrite_1 { default_type "text/html"; rewrite_by_lua_file /usr/openResty/lua/test_rewrite_1.lua; echo "no rewrite"; } ``` #### 1.2 test_rewrite_1.lua ``` if ngx.req.get_uri_args()["jump"] == "1" then return ngx.redirect("http://www.baidu.com?jump=1", 302) end ``` 當我們請求http://127.0.0.1/lua_rewrite_1時發現沒有跳轉,而請求http://127.0.0.1/lua_rewrite_1?jump=1時發現跳轉到百度首頁了。 此處需要301/302跳轉根據自己需求定義。 #### 2.1 openResty.conf配置文件 ``` location /lua_rewrite_2 { default_type "text/html"; rewrite_by_lua_file /usr/openResty/lua/test_rewrite_2.lua; echo "no rewrite"; } ``` #### 2.2 test_rewrite_2.lua ``` 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; <br/> 訪問如http://127.0.0.1/lua_rewrite_2?jump=0時得到響應 rewrite2 uri : /lua_rewrite_2, a : <br/> 訪問如http://127.0.0.1/lua_rewrite_2?jump=1時得到響應 rewrite2 uri : /lua_rewrite_4, a : 1 #### 3.1 openResty.conf配置文件 ``` location /lua_rewrite_3 { default_type "text/html"; rewrite_by_lua_file /usr/openResty/lua/test_rewrite_3.lua; echo "no rewrite"; } ``` #### 3.3 test_rewrite_3.lua ``` 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://127.0.0.1/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訪問,可以使用如下形式 ``` 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. openResty.conf配置文件 ``` location /lua_access { default_type "text/html"; rewrite_by_lua_file /usr/openResty/lua/test_access.lua; echo "access"; } ``` #### 2. test_access.lua ``` if ngx.req.get_uri_args()["token"] ~= "123" then return ngx.exit(403) end ``` 即如果訪問如http://17.0.0.12/lua_access?token=234將得到403 Forbidden的響應。這樣我們可以根據如cookie/用戶token來決定是否有訪問權限。 <br/> 另外在使用PCRE進行正則匹配時需要注意正則的寫法,具體規則請參考[http://wiki.nginx.org/HttpLuaModule](http://wiki.nginx.org/HttpLuaModule)中的Special PCRE Sequences部分。還有其他的注意事項也請閱讀官方文檔。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看