【精选】Nginx模块Lua-Nginx-Module学习笔记(一)Nginx Lua API 接口详解
源碼地址:https://github.com/Tinywan/Lua-Nginx-Redis
一、介紹
各種* _by_lua,* _by_lua_block和* _by_lua_file配置指令用作nginx.conf文件中Lua API的網關。 下面描述的Nginx Lua API只能在這些配置指令的上下文中運行的用戶Lua代碼中調用。API以兩個標準軟件包ngx和ndk的形式暴露給Lua。 這些軟件包位于ngx_lua中的默認全局范圍內,并且始終可在ngx_lua指令中使用。
這些包可以像這樣引入外部Lua模塊:
local say = ngx.saylocal _M = {}function _M.foo(a)say(a)endreturn _M強烈建議使用package.seeall標志,因為其各種不良的副作用。也可以直接要求外部Lua模塊中的包:
local ngx = require“ngx”local ndk = require“ndk”v0.2.1rc19版本中引入了需要這些軟件包的能力。
用戶代碼中的網絡I / O操作應該只通過Nginx Lua API調用來完成,因為Nginx事件循環可能被阻塞,否則性能會明顯下降。 磁盤操作與相對少量的數據可以使用標準的Lua io庫,但巨大的文件讀寫應盡可能避免,因為他們可能會顯著阻止Nginx進程。 強烈建議將所有網絡和磁盤I / O操作委派給Nginx的子請求(通過ngx.location.capture方法等),以獲得最佳性能。
二、命令介紹
ngx.arg
語法:val = ngx.arg [index]
上下文:set_by_lua *,body_filter_by_lua *
描述:當在set_by_lua *指令的上下文中使用時,此表是只讀的,并保存config指令的輸入參數:
value = ngx.arg[n]這里是一個例子
location /foo_sum {set $a 32;set $b 56;set_by_lua $sum'return tonumber(ngx.arg[1]) + tonumber(ngx.arg[2])'$a $b;echo "sum = ${sum}";}CURL 運行輸出
root@iZ236j3sofdZ:/usr/local/nginx/conf/lua# curl "http://localhost/foo_sum" sum = 88寫出88,32和56的和。
當在body_filter_by_lua *的上下文中使用此表時,第一個元素將輸入數據塊保存到輸出過濾器代碼,第二個元素保存指示整個輸出數據流結束的“eof”標志的布爾標志。
傳遞給下游Nginx輸出過濾器的數據塊和“eof”標志也可以通過將值直接分配給相應的表元素來覆蓋。 當將nil或空Lua字符串值設置為ngx.arg [1]時,根本不會將數據塊傳遞到下游Nginx輸出過濾器。
ngx.null
ngx.null常量是一個NULL light用戶數據,通常用于在Lua表等中表示nil值,類似于lua-cjson庫的cjson.null常量。 這個常數首先在v0.5.0rc5版本中引入。
ngx.var.VARIABLE?
語法:ngx.var.VAR_NAME
上下文:set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*
讀取和寫入Nginx變量值
value = ngx.var.some_nginx_variable_namengx.var.some_nginx_variable_name = value注意,只有已經定義的nginx變量可以寫入。 例如:
location /foo {set $my_var ''; # this line is required to create $my_var at config timecontent_by_lua_block {ngx.var.my_var = 123;...}}也就是說,nginx變量不能在運行中創建。一些特殊的nginx變量,如args和args和?limit_rate可以分配一個值,許多其他變量不是,如querystring,querystring,arg_PARAMETER和httpNAME。通過寫入ngx.var[1],ngx.var[2],ngx.var[3]等,也可以通過此接口讀取Nginx正則表達式組捕獲變量httpNAME。通過寫入ngx.var[1],ngx.var[2],ngx.var[3]等,也可以通過此接口讀取Nginx正則表達式組捕獲變量?1,2,2,?3等。將ngx.var.Foo設置為nil值將取消設置$ Foo Nginx變量。
ngx.var.args = nil小心當從Nginx變量讀取時,Nginx將在每個請求的內存池中分配內存,只有在請求終止時才釋放內存。 因此,當您需要在Lua代碼中重復讀取Nginx變量時,將Nginx變量值緩存到您自己的Lua變量中,例如:
local val = ngx.var.some_var--- use the val repeatedly later以防止(臨時)內存在當前請求的生存期內泄漏。 緩存結果的另一種方法是使用ngx.ctx表。未定義的NGINX變量評估為nil,而未初始化(但已定義)的NGINX變量將被評估為空的Lua字符串。此API需要相對昂貴的元方法調用,建議避免在熱代碼路徑上使用它。
Core constants
上下文:?init_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, *log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*
ngx.OK (0)ngx.ERROR (-1)ngx.AGAIN (-2)ngx.DONE (-4)ngx.DECLINED (-5)請注意,只有三個這些常數是由所利用的Nginx API為lua(即ngx.exit接受NGX_OK,NGX_ERROR和NGX_DECLINED作為輸入)。
ngx.null該ngx.null常數是一個NULL通常用來表示在Lua表等零值光用戶數據和類似于LUA-cjson庫的cjson.null常數。此常數最早在引入的v0.5.0rc5釋放。
待續.........
HTTP方法常量
上下文:?init_by_lua *,* set_by_lua,rewrite_by_lua *,* access_by_lua,content_by_lua *,* header_filter_by_lua,body_filter_by_lua *,* log_by_lua,ngx.timer *,* balancer_by_lua,ssl_certificate_by_lua *,* ssl_session_fetch_by_lua,ssl_session_store_by_lua *。
ngx.HTTP_GETngx.HTTP_HEADngx.HTTP_PUTngx.HTTP_POSTngx.HTTP_DELETEngx.HTTP_OPTIONS (added in the v0.5.0rc24 release)ngx.HTTP_MKCOL (added in the v0.8.2 release)ngx.HTTP_COPY (added in the v0.8.2 release)ngx.HTTP_MOVE (added in the v0.8.2 release)ngx.HTTP_PROPFIND (added in the v0.8.2 release)ngx.HTTP_PROPPATCH (added in the v0.8.2 release)ngx.HTTP_LOCK (added in the v0.8.2 release)ngx.HTTP_UNLOCK (added in the v0.8.2 release)ngx.HTTP_PATCH (added in the v0.8.2 release)ngx.HTTP_TRACE (added in the v0.8.2 release)這些常數通常在使用ngx.location.capture和ngx.location.capture_multi方法調用。
?
HTTP狀態常數
上下文:?init_by_lua *,* set_by_lua,rewrite_by_lua *,* access_by_lua,content_by_lua *,* header_filter_by_lua,body_filter_by_lua *,* log_by_lua,ngx.timer *,* balancer_by_lua,ssl_certificate_by_lua *,* ssl_session_fetch_by_lua,ssl_session_store_by_lua *。
value = ngx.HTTP_CONTINUE (100) (first added in the v0.9.20 release)value = ngx.HTTP_SWITCHING_PROTOCOLS (101) (first added in the v0.9.20 release)value = ngx.HTTP_OK (200)value = ngx.HTTP_CREATED (201)value = ngx.HTTP_ACCEPTED (202) (first added in the v0.9.20 release)value = ngx.HTTP_NO_CONTENT (204) (first added in the v0.9.20 release)value = ngx.HTTP_PARTIAL_CONTENT (206) (first added in the v0.9.20 release)value = ngx.HTTP_SPECIAL_RESPONSE (300)value = ngx.HTTP_MOVED_PERMANENTLY (301)value = ngx.HTTP_MOVED_TEMPORARILY (302)value = ngx.HTTP_SEE_OTHER (303)value = ngx.HTTP_NOT_MODIFIED (304)value = ngx.HTTP_TEMPORARY_REDIRECT (307) (first added in the v0.9.20 release)value = ngx.HTTP_BAD_REQUEST (400)value = ngx.HTTP_UNAUTHORIZED (401)value = ngx.HTTP_PAYMENT_REQUIRED (402) (first added in the v0.9.20 release)value = ngx.HTTP_FORBIDDEN (403)value = ngx.HTTP_NOT_FOUND (404)value = ngx.HTTP_NOT_ALLOWED (405)value = ngx.HTTP_NOT_ACCEPTABLE (406) (first added in the v0.9.20 release)value = ngx.HTTP_REQUEST_TIMEOUT (408) (first added in the v0.9.20 release)value = ngx.HTTP_CONFLICT (409) (first added in the v0.9.20 release)value = ngx.HTTP_GONE (410)value = ngx.HTTP_UPGRADE_REQUIRED (426) (first added in the v0.9.20 release)value = ngx.HTTP_TOO_MANY_REQUESTS (429) (first added in the v0.9.20 release)value = ngx.HTTP_CLOSE (444) (first added in the v0.9.20 release)value = ngx.HTTP_ILLEGAL (451) (first added in the v0.9.20 release)value = ngx.HTTP_INTERNAL_SERVER_ERROR (500)value = ngx.HTTP_METHOD_NOT_IMPLEMENTED (501)value = ngx.HTTP_BAD_GATEWAY (502) (first added in the v0.9.20 release)value = ngx.HTTP_SERVICE_UNAVAILABLE (503)value = ngx.HTTP_GATEWAY_TIMEOUT (504) (first added in the v0.3.1rc38 release)value = ngx.HTTP_VERSION_NOT_SUPPORTED (505) (first added in the v0.9.20 release)value = ngx.HTTP_INSUFFICIENT_STORAGE (507) (first added in the v0.9.20 release)Nginx的日志級別常數
上下文:?init_by_lua *,* init_worker_by_lua,set_by_lua *,* rewrite_by_lua,access_by_lua *,* content_by_lua,header_filter_by_lua *,* body_filter_by_lua,log_by_lua *,* ngx.timer,balancer_by_lua *,* ssl_certificate_by_lua,ssl_session_fetch_by_lua *,* ssl_session_store_by_lua。
ngx.STDERRngx.EMERGngx.ALERTngx.CRITngx.ERRngx.WARNngx.NOTICEngx.INFOngx.DEBUG語法:?print(...)
上下文:?init_by_lua*, init_worker_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*
寫參數值到nginx的error.log與文件ngx.NOTICE日志級別。它相當于
ngx.log(ngx.NOTICE, ...)Lua的nil參數被接受,并導致文字"nil"字符串,而Lua的布爾導致文字"true"或"false"字符串。和ngx.null常數將產生"null"串輸出。
有一個硬編碼2048在Nginx的核心錯誤信息的長度字節的限制。此限制包括尾隨換行符和領先的時間戳。如果郵件的大小超出此限制,Nginx的將相應截斷消息文本。這個限制可以通過編輯手動修改NGX_MAX_ERROR_STR的宏定義src/core/ngx_log.h在Nginx的源代碼樹文件。
ngx.ctx
上下文:?init_worker_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*
這個表可以被用來存儲每個請求的Lua上下文數據,并具有使用壽命相同當前請求(與Nginx的變量)。考慮下面的例子,
location /test {rewrite_by_lua_block {ngx.ctx.foo = 76}access_by_lua_block {ngx.ctx.foo = ngx.ctx.foo + 3}content_by_lua_block {ngx.say(ngx.ctx.foo)}}然后GET /test將產生的輸出:79
即,ngx.ctx.foo條目橫跨重寫,訪問和請求的內容相存在。每一項要求,其中包括子請求,有它自己的表的副本。例如:
location /sub {content_by_lua_block {ngx.say("sub pre: ", ngx.ctx.blah)ngx.ctx.blah = 32ngx.say("sub post: ", ngx.ctx.blah)}}location /main {content_by_lua_block {ngx.ctx.blah = 73ngx.say("main pre: ", ngx.ctx.blah)local res = ngx.location.capture("/sub")ngx.print(res.body)ngx.say("main post: ", ngx.ctx.blah)}}然后GET /main會給輸出:
main pre: 73sub pre: nilsub post: 32main post: 73在此,改性ngx.ctx.blah的子請求條目不會影響所述一個在父請求。這是因為他們有兩個獨立的版本ngx.ctx.blah。內部重定向會破壞原來的請求ngx.ctx數據(如果有的話)和新要求將有一個空ngx.ctx表。例如:
location /new {content_by_lua_block {ngx.say(ngx.ctx.foo)}}location /orig {content_by_lua_block {ngx.ctx.foo = "hello"ngx.exec("/new")}}然后GET /orig會給:nil
而不是原來的"hello"值。任意的數據值,包括Lua的關閉和嵌套表,可以插入到這個“神奇”的表。它還允許自定義元方法的注冊。覆蓋ngx.ctx用一個新的Lua表也支持,例如:
ngx.ctx = { foo = 32, bar = 54 }當在上下文中使用init_worker_by_lua *,此表只是有當前的Lua處理程序的壽命相同。
在ngx.ctx查找需要相對昂貴元方法的調用,這是不是明確傳遞每個請求的數據沿著自己的函數參數慢得多。所以,不要濫用這個API保存你自己的函數的參數,因為它通常具有頗有些性能的影響。因為魔元方法的,從來沒有“本地”的ngx.ctx上由于Lua的模塊級的Lua的功能范圍之外的表工作者級的數據共享。例如,以下是壞:
-- mymodule.lualocal _M = {}-- the following line is bad since ngx.ctx is a per-request-- data while this <code>ctx</code> variable is on the Lua module level-- and thus is per-nginx-worker.local ctx = ngx.ctxfunction _M.main()ctx.foo = "bar"endreturn _M改用以下內容:
-- mymodule.lualocal _M = {}function _M.main(ctx)ctx.foo = "bar"endreturn _M也就是說,讓調用者通過ctx表明確地通過一個函數的參數。
?
ngx.location.capture
語法:?res = ngx.location.capture(uri, options?)
上下文:?rewrite_by_lua *,* access_by_lua,content_by_lua *
是一個同步非阻塞的NGINX子請求uri
NGINX的子請求提供了一個非常強大的方式去實現非阻塞的內部請求,或者其他的C模塊,比如?ngx_proxy, ngx_fastcgi, ngx_memc, ngx_postgres, ngx_drizzle, 甚至ngx_lua自己等等。
當然,這些子請求僅僅是模擬HTTP請求,但是并沒有額外的?HTTP/TCP,所有的進程都是C級別的
子請求完全不同與HTTP 301/302。
這里有個基本的例子:
res = ngx.location.capture(uri)返回與4插槽,一個Lua表:res.status,res.header,res.body,和res.truncated。
res.status?用于保存子請求響應的響應狀態代碼。
res.header持有子請求的響應頭,這是一個正常的Lua表。對于多值響應頭,該值是保存所有的順序它們出現的值的Lua(陣列)表。例如,如果子請求響應報頭包含以下幾行:
返回一個LUA的TABLE,三個值(res.status, res.header, and res.body)。
res.header包含了所有的子請求的頭的信息,它是一個普通的LUA TABLE。比如多個值的相應頭,他們以數組的形式按照順序返回出現。例如:子請求包含了如下信息:
Set-Cookie: a=3Set-Cookie: foo=barSet-Cookie: baz=blah然后res.header["Set-Cookie"]將被評估,以表中的值?{"a=3", "foo=bar", "baz=blah"}。
res.body持有子請求的響應體數據,這些數據可能會被截斷。你總是需要檢查res.truncated布爾標志,看是否res.body包含截斷數據。這里的數據截斷只能由那些不可恢復的錯誤在你的子請求一樣,遠端中止在響應體數據流的中間,或當你的子請求接收從響應體數據的讀取超時發生過早的連接的情況下造成的遙控器。URI查詢串可以串聯到的URI本身,例如:
res = ngx.location.capture('/foo/bar?a=3&b=4')像名為位置@foo不允許由于nginx的核心的限制。使用與組合正常位置internal指令準備僅供內部使用的位置。
可選選項表可以喂的第二個參數,它支持的選項:
- method?指定子請求的請求方法,只接受常量一樣ngx.HTTP_POST。
- body?指定子請求的請求體(僅字符串值)。
- args?指定子請求的URI查詢參數(這兩個字符串值和Lua表被接受)
- ctx?指定一個Lua表是ngx.ctx為子請求表。它可以是當前請求的ngx.ctx表,這有效地使母體和其子請求共享完全相同的上下文表。此選項最初是在引進v0.3.1rc25發行。
- vars?采取持有的值設置指定的Nginx變量在子請求作為此選項的值一個Lua表。此選項最初是在引進v0.3.1rc31發行。
- copy_all_vars?指定是否在當前請求所討論的子請求的所有的Nginx變量值復制。在子請求nginx的變量的修改將不會影響當前(父)的請求。此選項最初是在引進v0.3.1rc31發行。
- share_all_vars?指定是否共享的子請求與當前(父)要求所有的Nginx變量。在子請求Nginx的變量的修改將影響當前(父)的請求。啟用此選項可能會導致因不良副作用難以調試問題,被認為是不好的,有害的。只有啟用該選項,當你完全知道自己在做什么。
- always_forward_body?當設置為true,當前(父)的請求的請求體總是會被轉發到,如果創建的子請求body未指定選項。無論是通過讀取請求體()ngx.req.read_body或lua_need_request_body上會被直接轉發到子請求不創建子請求(無論請求體數據在內存中緩存或臨時文件緩存)時復制整個請求體數據。默認情況下,這個選項是false和時body沒有指定選項時,當前的(父)請求的請求體,當子請求取只轉發PUT或POST請求方法。
發出一個POST子請求,例如,可以做如下:
res = ngx.location.capture('/foo/bar',{ method = ngx.HTTP_POST, body = 'hello, world' })看到比其他POST HTTP方法的常量方法。該method選項是ngx.HTTP_GET默認。
該args選項可以指定額外的URI參數,例如:
ngx.location.capture('/foo?a=1',{ args = { b = 3, c = ':' } })相當于
ngx.location.capture('/foo?a=1&b=3&c=%3a')也就是說,該方法將根據規則URI參數逃脫鍵和值一起將它們連接起來成為一個完整的查詢字符串。對于作為通過的Lua表的格式args參數是相同于使用的格式ngx.encode_args方法。該args選項也可以采取簡單的查詢字符串:
ngx.location.capture('/foo?a=1',{ args = 'b=3&c=%3a' } })這在功能上等同于前面的例子。
該share_all_vars選項控制是否將當前請求和子請求之間共享nginx的變量。如果此選項設置為true,那么當前請求和相關的子請求將共享相同的Nginx變量的作用域。因此,通過一個子請求更改了Nginx的變量將影響到當前的請求。
應小心使用此選項,變量的作用域共享可以有意想不到的副作用。的args,vars或copy_all_vars選項通常優于代替。這個選項被設置為false默認
location /other {set $dog "$dog world";echo "$uri dog: $dog";}location /lua {set $dog 'hello';content_by_lua_block {res = ngx.location.capture("/other",{ share_all_vars = true });ngx.print(res.body)ngx.say(ngx.var.uri, ": ", ngx.var.dog)}}訪問位置/lua給:
/other dog: hello world /lua: hello world該copy_all_vars選項提供父請求的Nginx的變量的副本子請求時這樣子請求發出。由這樣子請求對這些變量所做的更改不會影響父請求或任何其他子請求共享父請求的變量。
location /other {set $dog "$dog world";echo "$uri dog: $dog";}location /lua {set $dog 'hello';content_by_lua_block {res = ngx.location.capture("/other",{ copy_all_vars = true });ngx.print(res.body)ngx.say(ngx.var.uri, ": ", ngx.var.dog)}}請求GET /lua將給輸出
/other dog: hello world /lua: hello請注意,如果兩者share_all_vars并copy_all_vars都設置為true,則share_all_vars優先。
除了上述兩個設置,有可能使用在子請求變量的值vars選項。這些變量的變量共享或復制已評估后設置,并且提供了對編碼它們以URL參數,并在Nginx的配置文件反向轉義它們傳遞特定值應用于一個子請求的更有效的方法:
location /other {content_by_lua_block {ngx.say("dog = ", ngx.var.dog)ngx.say("cat = ", ngx.var.cat)}}location /lua {set $dog '';set $cat '';content_by_lua_block {res = ngx.location.capture("/other",{ vars = { dog = "hello", cat = 32 }});ngx.print(res.body)}}訪問/lua將產生的輸出:
dog = hello cat = 32該ctx選項可用于指定自定義的Lua表作為ngx.ctx為子請求表。
location /sub {content_by_lua_block {ngx.ctx.foo = "bar";}}location /lua {content_by_lua_block {local ctx = {}res = ngx.location.capture("/sub", { ctx = ctx })ngx.say(ctx.foo);ngx.say(ngx.ctx.foo);}}然后請求GET /lua 輸出:
bar nil另外,也可以使用這個ctx選項共享同一ngx.ctx電流(父)請求和子請求之間的表:
location /sub {content_by_lua_block {ngx.ctx.foo = "bar";}}location /lua {content_by_lua_block {res = ngx.location.capture("/sub", { ctx = ngx.ctx })ngx.say(ngx.ctx.foo);}}請求GET /lua產生的輸出:bar
注意,通過發出子請求ngx.location.capture默認繼承當前請求的所有請求頭,而這可能對子請求響應意想不到的副作用。例如,使用標準時,ngx_proxy模塊服務子請求,“接受編碼:gzip”中的主要請求頭,可能會導致不能在Lua代碼正確處理gzip壓縮的響應。原始請求頭,應通過設置被忽略?proxy_pass_request_headers到off的子請求的位置。
如果body沒有指定選項,且always_forward_body選項為false(默認值),POST以及PUT子請求將繼承父請求(如果有的話)的請求主體。
上有可能為每一個主要請求并發子請求的數目的硬編碼上限。在舊版本Nginx的,下限為50并行子請求,并在最近的版本中,Nginx的1.1.x開始,這是提高到200并發子請求。當超過此限制時,以下錯誤消息被添加到error.log文件中:
[error] 13983#0: *1 subrequests cycle while processing "/uri"極限可以根據需要通過編輯的定義手動修改NGX_HTTP_MAX_SUBREQUESTS宏中nginx/src/http/ngx_http_request.h在Nginx的源樹文件。請同時參閱限制捕獲由配置位置的其他模塊的子請求指示。
?
ngx.location.capture_multi
ngx.status
ngx.header.HEADER
ngx.resp.get_headers
?
ngx.req.is_internal
?
ngx.req.start_time
語法:?secs = ngx.req.start_time()
上下文:?set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*
返回表示時間戳(包括毫秒作為小數部分)已創建當前請求時一個浮點數。下面的例子模擬了$request_time變量值(由提供ngx_http_log_module純LUA):
| 1 | local request_time = ngx.now() - ngx.req.start_time() |
ngx.req.http_version
語法:??num = ngx.req.http_version()
背景:?set_by_lua *,* rewrite_by_lua,access_by_lua *,* content_by_lua,header_filter_by_lua *
返回當前請求作為Lua的數字的HTTP版本號。
當前可能的值是2.0,1.0,1.1和0.9。返回nil了無法識別的值。
ngx.req.raw_header
語法:??str = ngx.req.raw_header(no_request_line?)
背景:?set_by_lua *,* rewrite_by_lua,access_by_lua *,* content_by_lua,header_filter_by_lua *
返回由Nginx的服務器接收到的原始原始的HTTP協議頭。
默認情況下,請求行和尾隨CR LF終止也將包括在內。例如,
ngx.print(ngx.req.raw_header())給出這樣的事情:
GET /t HTTP/1.1 Host: localhost Connection: close Foo: bar你可以指定可選的?no_request_line參數作為true排除從結果的請求行的值。例如
ngx.print(ngx.req.raw_header(true))輸出是這樣的:
Host: localhost Connection: close Foo: bar此方法不會在HTTP / 2請求工作尚未
?
CDN 反向代理LiveNode節點,通過Lua腳本操作Redis數據庫實現轉發
URL訪問地址:http://127.0.0.1/hls/4953.m3u8
nginx.conf 配置
location ~ \/.+\/.+\.(m3u8|ts) {#設置nginx變量if ($uri ~ \/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)(|-).*\.(m3u8|ts)) {set $app_name $1;set $a $2;}set $stream_id "";default_type 'text/html';lua_code_cache on;rewrite_by_lua_file /home/www/lua-tinywan/set_by_file.lua;#echo "stream_id :" $stream_id;proxy_buffering off;proxy_redirect off;proxy_connect_timeout 10;proxy_send_timeout 30;proxy_read_timeout 30;proxy_pass $stream_id;}set_by_file.lua 添加一下內容:-- 接受Nginx傳遞進來的參數$1 也就是SteamName local stream_a = ngx.var.alocal redis = require("resty.redis"); -- 創建一個redis對象實例。在失敗,返回nil和描述錯誤的字符串的情況下 local redis_instance = redis:new(); --設置后續操作的超時(以毫秒為單位)保護,包括connect方法 redis_instance:set_timeout(1000) --建立連接 local ip = '127.0.0.1' local port = 6379 --嘗試連接到redis服務器正在偵聽的遠程主機和端口 local ok,err = redis_instance:connect(ip,port) if not ok thenngx.say("connect redis error : ",err)return err end-- 權限驗證 local res,err = redis_instance:auth('tinywanredis') if not res thenngx.say("failed to authenticate: ", err)return end--數據庫選擇 redis_instance:select(2)--調用API獲取數據 local resp, err = redis_instance:hget("StreamLiveNodeInnerIp:"..stream_a,'livenode') if not resp thenngx.say("get msg error : ", err)return err end--得到的數據為空處理 if resp == ngx.null thenngx.say("this is not redis_data")return nil end ngx.var.stream_id = resp -- ngx.say("reds get result : ", resp)
?思路圖片:
?
?
貴在堅持,相信自己.總結
以上是生活随笔為你收集整理的【精选】Nginx模块Lua-Nginx-Module学习笔记(一)Nginx Lua API 接口详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云全球首次互联网8K直播背后的技术解
- 下一篇: Nginx:作为缓存,支持Range回源