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.say local _M = {} function _M.foo(a) say(a) end return _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_name ngx.var.some_nginx_variable_name = value

注意,只有已經定義的nginx變量可以寫入。 例如:

location /foo { set $my_var ''; # this line is required to create $my_var at config time content_by_lua_block { ngx.var.my_var = 123; ... } }

  也就是說,nginx變量不能在運行中創建。一些特殊的nginx變量,如$ args和$ limit_rate可以分配一個值,許多其他變量不是,如$ query_string,$ arg_PARAMETER和$ http_NAME。通過寫入ngx.var [1],ngx.var [2],ngx.var [3]等,也可以通過此接口讀取Nginx正則表達式組捕獲變量$ 1,$ 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_OKNGX_ERRORNGX_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_GET ngx.HTTP_HEAD ngx.HTTP_PUT ngx.HTTP_POST ngx.HTTP_DELETE ngx.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.capturengx.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.STDERR
   ngx.EMERG
   ngx.ALERT
   ngx.CRIT
   ngx.ERR
   ngx.WARN
   ngx.NOTICE
   ngx.INFO
   ngx.DEBUG

print

語法: 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 = 32 ngx.say("sub post: ", ngx.ctx.blah) } } location /main { content_by_lua_block { ngx.ctx.blah = 73 ngx.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: 73 sub pre: nil sub post: 32 main 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.lua
 local _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.ctx function _M.main() ctx.foo = "bar"
 end

 return _M

改用以下內容:

 -- mymodule.lua
 local _M = {} function _M.main(ctx) ctx.foo = "bar"
 end

 return _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.statusres.headerres.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=3 Set-Cookie: foo=bar Set-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_bodylua_need_request_body上會被直接轉發到子請求不創建子請求(無論請求體數據在內存中緩存或臨時文件緩存)時復制整個請求體數據。默認情況下,這個選項是false和時body沒有指定選項時,當前的(父)請求的請求體,當子請求取只轉發PUTPOST請求方法。

發出一個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的變量將影響到當前的請求。

應小心使用此選項,變量的作用域共享可以有意想不到的副作用。argsvarscopy_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_varscopy_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_headersoff的子請求的位置。

如果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):

 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.a local 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 then ngx.say("connect redis error : ",err) return err end

-- 權限驗證
local res,err = redis_instance:auth('tinywanredis') if not res then ngx.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 then ngx.say("get msg error : ", err) return err end

--得到的數據為空處理 
if resp == ngx.null then ngx.say("this is not redis_data")
    return nil
end ngx.var.stream_id = resp -- ngx.say("reds get result : ", resp)

 思路圖片:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM