国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Lua在Nginx的應(yīng)用

Mike617 / 3016人閱讀

摘要:例如響應(yīng)部分通過的形式獲取或設(shè)置響應(yīng)頭信息。以某個(gè)狀態(tài)碼返回響應(yīng)內(nèi)容,狀態(tài)碼常量對(duì)應(yīng)關(guān)系見部分,也支持?jǐn)?shù)字形式的狀態(tài)碼。重定向當(dāng)前請(qǐng)求到新的,響應(yīng)狀態(tài)碼可選列表為默認(rèn)。具體內(nèi)容如下相關(guān)文章進(jìn)入的世界在的應(yīng)用

首發(fā)于 樊浩柏科學(xué)院

當(dāng) Nginx 標(biāo)準(zhǔn)模塊和配置不能靈活地適應(yīng)系統(tǒng)要求時(shí),就可以考慮使用 Lua 擴(kuò)展和定制 Nginx 服務(wù)。OpenResty 集成了大量精良的 Lua 庫、第三方模塊,可以方便地搭建能夠處理超高并發(fā)、擴(kuò)展性極高的 Web 服務(wù),所以這里選擇 OpenResty 提供的 lua-nginx-module 方案。

安裝Lua環(huán)境

lua-nginx-module 依賴于 LuaJIT 和 ngx_devel_kit。LuaJIT 需要安裝,ngx_devel_kit 只需下載源碼包,在 Nginx 編譯時(shí)指定 ngx_devel_kit 目錄。

系統(tǒng)依賴庫

首先確保系統(tǒng)已安裝如下依賴庫。

$ yum install readline-devel pcre-devel openssl-devel gcc
安裝LuaJIT

首先,安裝 LuaJIT 環(huán)境,如下所示:

$ wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz
$ tar zxvf LuaJIT-2.0.5.tar.gz
$ cd LuaJIT-2.0.5
$ make install
# 安裝成功
==== Successfully installed LuaJIT 2.0.5 to /usr/local ====

設(shè)置 LuaJIT 有關(guān)的環(huán)境變量。

$ export LUAJIT_LIB=/usr/local/lib
$ export LUAJIT_INC=/usr/local/include/luajit-2.0
$ echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
$ ldconfig
下載相關(guān)模塊

下載 ngx_devel_kit 源碼包,如下:

$ wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz
$ tar zxvf v0.3.0.tar.gz
# 解壓縮后目錄名
ngx_devel_kit-0.3.0

接下來,下載 Lua 模塊 lua-nginx-module 源碼包,為 Nginx 編譯作準(zhǔn)備。

$ wget https://github.com/openresty/lua-nginx-module/archive/v0.10.10.tar.gz
$ tar zxvf v0.10.10.tar.gz
# 解壓縮后目錄名
lua-nginx-module-0.10.10
加載Lua模塊

Nginx 1.9 版本后可以動(dòng)態(tài)加載模塊,但這里由于版本太低只能重新編譯安裝 Nginx。下載 Nginx 源碼包并解壓:

$ wget http://nginx.org/download/nginx-1.13.5.tar.gz
$ tar zxvf nginx-1.13.5.tar.gz

編譯并重新安裝 Nginx:

$ cd nginx-1.13.5
# 增加--add-module=/usr/src/lua-nginx-module-0.10.10 --add-module=/usr/src/ngx_devel_kit-0.3.0
$ ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-http_stub_status_module --with-pcre --add-module=/usr/src/lua-nginx-module-0.10.10 --add-module=/usr/src/ngx_devel_kit-0.3.0
$ make
$ make install
# 查看是否安裝成功
$ nginx -v
配置Nginx環(huán)境

現(xiàn)在只需配置 Nginx,即可嵌入 Lua 腳本。首先,在 http 部分配置 Lua 模塊和第三方庫路徑:

# 第三方庫(cjson)地址luajit-2.0/lib
lua_package_path "/home/www/lua/?.lua;;";
lua_package_cpath "/usr/local/include/luajit-2.0/lib/?.so;;";

接著,配置一個(gè) Lua 腳本服務(wù):

# hello world測(cè)試
server {
    location /lua_content {
        # 定義MIME類型
        default_type "text/plain";
        content_by_lua_block {
            ngx.say("Hello,world!")
        }
    }
}

測(cè)試安裝和配置是否正常:

$ service nginx test
$ service nginx reload
# 訪問地址/lua_content輸出
Hello,world!
Lua調(diào)用Nginx

lua-nginx-module 模塊中已經(jīng)為 Lua 提供了豐富的 Nginx 調(diào)用 API,每個(gè) API 都有各自的作用環(huán)境,詳細(xì)描述見 Nginx API for Lua。這里只列舉基本 API 的使用 。

先配一個(gè) Lua 腳本服務(wù),配置文件如下:

location?~?/lua_api?{??
????# 示例用的Nginx變量??
????set?$name?$host;
????default_type?"text/html";??
????# 通過Lua文件進(jìn)行內(nèi)容處理
????content_by_lua_file?/home/www/nginx-api.lua;??
}
請(qǐng)求部分

ngx.var

可以通過ngx.var.var_name形式獲取或設(shè)置 Nginx 變量值,例如 request_uri、host、request 等。

-- ngx.say打印內(nèi)容
ngx.say(ngx.var.request_uri)
ngx.var.name = "www.fanhaobai.com"

ngx.req.get_headers()

該方法會(huì)以表的形式返回當(dāng)前請(qǐng)求的頭信息。查看請(qǐng)求的頭信息:

ngx.say("Host : ", ngx.req.get_headers().host, "
") for k,v in pairs(ngx.req.get_headers()) do if type(v) == "table" then ngx.say(k, "?:?", table.concat(v, ","), "
") else ngx.say(k,"?:?", v, "
") end end

當(dāng)然,通過 ngx.req.set_header() 也可以設(shè)置頭信息。

ngx.req.set_header("Content-Type", "text/html")

ngx.req.get_uri_args()

該方法以表形式返回當(dāng)前請(qǐng)求的所有 GET 參數(shù)。查看請(qǐng)求 query 為?name=fhb的 GET 參數(shù):

ngx.say("name : ", ngx.req.get_uri_args().name, "
") for k,v in pairs(ngx.req.get_uri_args()) do if type(v) == "table" then ngx.say(k, "?:?", table.concat(v, ","), "
") else ngx.say(k,"?:?", v, "
") end end

同樣,可以通過 ngx.req.set_uri_args() 設(shè)置請(qǐng)求的所有 GET 參數(shù)。

ngx.req.set_uri_args({name="fhb"}) --{name="fhb"}可以為query形式name=fhb

get_post_args()

該方法以表形式返回當(dāng)前請(qǐng)求的所有 POST 參數(shù),POST 數(shù)據(jù)必須是 application/x-www-form-urlencoded 類型。查看請(qǐng)求curl --data "name=fhb" localhost/lua_api的 POST 參數(shù):

--必須先讀取body體
ngx.req.read_body()
ngx.say("name : ", ngx.req.get_post_args().name, "
") for k,v in pairs(ngx.req.get_post_args()) do if type(v) == "table" then ngx.say(k, "?:?", table.concat(v, ","), "
") else ngx.say(k,"?:?", v, "
") end end

通過 ngx.req.get_body_data() 方法可以獲取未解析的請(qǐng)求 body 體內(nèi)容字符串。

ngx.req.get_method()

獲取請(qǐng)求的大寫字母形式的請(qǐng)求方式,通過 ngx.req.set_method() 可以設(shè)置請(qǐng)求方式。例如:

ngx.say(ngx.req.get_method())
響應(yīng)部分

ngx.header

通過ngx.header.header_name的形式獲取或設(shè)置響應(yīng)頭信息。如下:

ngx.say(ngx.header.content_type)
ngx.header.content_type = "text/plain"

ngx.print()

ngx.print() 方法會(huì)填充指定內(nèi)容到響應(yīng) body 中。如下所示:

ngx.print(ngx.header.content_type)

ngx.say()

如上述使用,ngx.say() 方法同 ngx.print() 方法,只是會(huì)在后追加一個(gè)換行符。

ngx.exit()

以某個(gè)狀態(tài)碼返回響應(yīng)內(nèi)容,狀態(tài)碼常量對(duì)應(yīng)關(guān)系見 HTTP status constants 部分,也支持?jǐn)?shù)字形式的狀態(tài)碼。

ngx.exit(403)

ngx.redirect()

重定向當(dāng)前請(qǐng)求到新的 url,響應(yīng)狀態(tài)碼可選列表為 301、302(默認(rèn))、303、307。

ngx.redirect("http://www.fanhaobai.com")
其他

ngx.re.match

該方法提供了正則表達(dá)式匹配方法。請(qǐng)求?name=fhb&age=24匹配 GET 參數(shù)中的數(shù)字:

local m, err = ngx.re.match(ngx.req.set_uri_args, "[0-9]+")
if m then
    ngx.say(m[0])
else
    ngx.say("match not found")
end

ngx.log()

通過該方法可以將內(nèi)容寫入 Nginx 日志文件,日志文件級(jí)別需同 log 級(jí)別一致。

ngx.md5() | ngx.encode_base64() | ngx.decode_base64()

它們都是字符串編碼方式。ngx.md5() 可以對(duì)字符串進(jìn)行 md5 加密處理,而 ngx.encode_base64() 是對(duì)字符串 base64 編碼, ngx.decode_base64() 為 base64 解碼。

Nginx中嵌入Lua

上面講述了怎么在 Lua 中調(diào)用 Nginx 的 API 來擴(kuò)展或定制 Nginx 的功能,那么編寫好的 Lua 腳本怎么在 Nginx 中得到執(zhí)行呢?其實(shí),Nginx 是通過模塊指令形式在其 11 個(gè)處理階段做插入式處理,指令覆蓋 http、server、server if、location、location if 這幾個(gè)范圍。

模塊指令列表

這里只列舉基本的 Lua 模塊指令,更多信息參考 Directives 部分。

指令 所在階段 使用范圍 說明
init_by_lua
init_by_lua_file
加載配置文件 http 可以用于初始化全局配置
set_by_lua
set_by_lua_file
rewrite server
location
location if
復(fù)雜邏輯的變量賦值,注意是阻塞的
rewrite_by_lua
rewrite_by_lua_file
rewrite http
server
location
location if
實(shí)現(xiàn)復(fù)雜邏輯的轉(zhuǎn)發(fā)或重定向
content_by_lua
content_by_lua_file
content location
location if
處理請(qǐng)求并輸出響應(yīng)
header_filter_by_lua
header_filter_by_lua_file
響應(yīng)頭信息過濾 http
server
location
location if
設(shè)置響應(yīng)頭信息
body_filter_by_lua
body_filter_by_lua_file
輸出過濾 http
server
location
location if
對(duì)輸出進(jìn)行過濾或修改
使用指令

注意到,每個(gè)指令都會(huì)有*_lua*_lua_file兩個(gè)指令,*_lua指令后為 Lua 代碼塊,而*_lua_file指令后為 Lua 腳本文件路徑。下面將只對(duì)*_lua指令進(jìn)行說明。

init_by_lua

該指令會(huì)在 Nginx 的 Master 進(jìn)程加載配置時(shí)執(zhí)行,所以可以完成 Lua 模塊初始化工作,Worker 進(jìn)程同樣會(huì)繼承這些。

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

-- 所有worker共享的全局變量
lua_shared_dict?shared_data?1m;??
init_by_lua_file?/usr/example/lua/init.lua;

init.lua初始化腳本為:

local?cjson?=?require?"cjson"
local?redis?=?require?"resty.redis"
local?shared_data?=?ngx.shared.shared_data

set_by_lua

我們直接使用 set 指令很難實(shí)現(xiàn)很復(fù)雜的變量賦值邏輯,而 set_by_lua 模塊指令就可以解決這個(gè)問題。

nginx.conf配置文件 location 部分內(nèi)容為:

location /lua {
    set_by_lua_file $num /home/www/set.lua;
    default_type "text/html";
    echo $num;
}

set.lua腳本內(nèi)容為:

local?uri_args?=?ngx.req.get_uri_args()
local?i?=?uri_args.a?or?0
local?j?=?uri_args.b?or?0
return?i?+?j

上述賦值邏輯,請(qǐng)求 query 為?a=10&b=2時(shí)響應(yīng)內(nèi)容為 12。

rewrite_by_lua

可以實(shí)現(xiàn)內(nèi)部 URL 重寫或者外部重定向。nginx.conf配置如下:

location /lua {
    default_type?"text/html";
    rewrite_by_lua_file?/home/www/rewrite.lua;
}

rewrite.lua腳本內(nèi)容:

if?ngx.req.get_uri_args()["type"]?==?"app"?then
    ngx.req.set_uri("/m_h5",?false);
end

access_by_lua

用于訪問權(quán)限控制。例如,只允許帶有身份標(biāo)識(shí)用戶訪問,nginx.conf配置為:

location?/lua?{??
    default_type?"text/html";
    access_by_lua_file?/home/www/access.lua;
}??

access.lua腳本內(nèi)容為:

if?ngx.req.get_uri_args()["token"]?==?"fanhb"?then
    return?ngx.exit(403)
end

content_by_lua

該指令在 Lua 調(diào)用 Nginx 部分已經(jīng)使用過了,用于輸出響應(yīng)內(nèi)容。

案例 訪問權(quán)限控制

使用 Lua 模塊對(duì)本站的 ES 服務(wù)做受信操作控制,即非受信 IP 只能查詢操作。nginx.conf配置如下:

location / {
    set $allowed "115.171.226.212";
    access_by_lua_block {
        if ngx.re.match(ngx.req.get_method(), "PUT|POST|DELETE") and not ngx.re.match(ngx.var.request_uri, "_search") then
        start, _ = string.find(ngx.var.allowed, ngx.var.remote_addr)
        if not start then
        ngx.exit(403)
        end
    end
    }
    
    proxy_pass http://127.0.0.1:9200$request_uri;
}
訪問頻率控制

在 Nginx 配置文件的 location 部分配置 Lua 腳本基本參數(shù),并配置 Lua 模塊指令:

default_type?"text/html";
set rate_per 300
access_by_lua_file?/home/www/access.lua;

Lua 腳本實(shí)現(xiàn)頻率控制邏輯,使用 Redis 對(duì)單位時(shí)間內(nèi)的訪問次數(shù)做緩存,key 為訪問 uri 拼接 token 后的 md5 值。具體內(nèi)容如下:

local redis = require "resty.redis"
local red = redis:new()

local limit = tonumber(ngx.var.rate_per) or 200
local expire_time = tonumber(ngx.var.rate_expire) or 1000
local key = "rate.limit:string:"

red:set_timeout(500)
local ok, err = red:connect("www.fanhaobai.com", 6379)
if not ok then
    ngx.log(ngx.ERR, "failed to connect redis: " .. err)
    return
end

key = key .. ngx.md5(ngx.var.request_uri .. (ngx.req.get_uri_args()["token"] or ngx.req.get_post_args()["token"]))
local times, err = red:incr(key)
if not times then
    ngx.log(ngx.ERR, "failed to exec incr: " .. err)
    return
elseif times == 1 then
    ok, err = red:expire(key, expire_time)
    if not ok then
        ngx.log(ngx.ERR, "failed to exec expire: " .. err)
        return
    end
end

if times > limit then
    return ngx.exit(403)
end

return

相關(guān)文章 ?

進(jìn)入Lua的世界(2017-09-03)

Lua在Redis的應(yīng)用(2017-09-04)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/40404.html

相關(guān)文章

  • lapis入門

    摘要:入門是為和編寫的框架。使用來安裝創(chuàng)建一個(gè)應(yīng)用命令行工具附帶了一個(gè)命令行工具,可幫助您創(chuàng)建新項(xiàng)目和啟動(dòng)服務(wù)器。在生產(chǎn)環(huán)境中,應(yīng)當(dāng)啟用緩存以獲得最佳性能。指令指定一個(gè)代碼塊,它將處理與其他不匹配的任何請(qǐng)求。將忽略常規(guī)的二進(jìn)制文件。 lapis入門 Lapis 是為 Lua 和 MoonScript 編寫的 Web 框架。 Lapis 很有趣,因?yàn)樗⒃贜ginx 發(fā)行的 OpenRest...

    endless_road 評(píng)論0 收藏0
  • 基于 Nginx 動(dòng)態(tài)代理

    摘要:目前最常用的軟件反向代理服務(wù)器有和。基于實(shí)現(xiàn)動(dòng)態(tài)代理為了實(shí)現(xiàn)動(dòng)態(tài)代理方案,需要在反向代理服務(wù)器中增加定制的功能。同時(shí),由于反向代理服務(wù)器需要處理大量的代理請(qǐng)求,因此會(huì)頻繁的讀取反向代理配置數(shù)據(jù)。 基于 Nginx 的動(dòng)態(tài)代理 作者:趙波日期:2016 年 8 月 4 日 在實(shí)際應(yīng)用中,遇到了這樣一個(gè)場(chǎng)景: 已有一個(gè)手機(jī) APP 客戶端,需要在該 APP 客戶端中實(shí)現(xiàn)通過 Web 的形式...

    wean 評(píng)論0 收藏0
  • OpenResty安裝、配置與使用

    摘要:用于方便地搭建能夠處理超高并發(fā)擴(kuò)展性極高的動(dòng)態(tài)應(yīng)用服務(wù)和動(dòng)態(tài)網(wǎng)關(guān)。安裝安裝依賴庫下載及安裝激活組件被用于構(gòu)建。大部組件默認(rèn)是激活的,也有部件不是。您需要通過以下選項(xiàng)在編譯的時(shí)候?qū)⑺鼈兏髯约せ睿汀? OpenResty簡(jiǎn)介 OpenResty 是一個(gè)基于 Nginx 與 Lua 的高性能 Web 平臺(tái),其內(nèi)部集成了大量精良的 Lua 庫、第三方模塊以及大多數(shù)的依賴項(xiàng)。用于方便地搭建能夠處...

    stackfing 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<