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 ;
set $b ;
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,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 = ;
...
}
}
也就是说,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 ()
ngx.ERROR (-)
ngx.AGAIN (-)
ngx.DONE (-)
ngx.DECLINED (-)
请注意,只有三个这些常数是由所利用的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_GET
ngx.HTTP_HEAD
ngx.HTTP_PUT
ngx.HTTP_POST
ngx.HTTP_DELETE
ngx.HTTP_OPTIONS (added in the v0..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 () (first added in the v0.9.20 release)
value = ngx.HTTP_SWITCHING_PROTOCOLS () (first added in the v0.9.20 release)
value = ngx.HTTP_OK ()
value = ngx.HTTP_CREATED ()
value = ngx.HTTP_ACCEPTED () (first added in the v0.9.20 release)
value = ngx.HTTP_NO_CONTENT () (first added in the v0.9.20 release)
value = ngx.HTTP_PARTIAL_CONTENT () (first added in the v0.9.20 release)
value = ngx.HTTP_SPECIAL_RESPONSE ()
value = ngx.HTTP_MOVED_PERMANENTLY ()
value = ngx.HTTP_MOVED_TEMPORARILY ()
value = ngx.HTTP_SEE_OTHER ()
value = ngx.HTTP_NOT_MODIFIED ()
value = ngx.HTTP_TEMPORARY_REDIRECT () (first added in the v0.9.20 release)
value = ngx.HTTP_BAD_REQUEST ()
value = ngx.HTTP_UNAUTHORIZED ()
value = ngx.HTTP_PAYMENT_REQUIRED () (first added in the v0.9.20 release)
value = ngx.HTTP_FORBIDDEN ()
value = ngx.HTTP_NOT_FOUND ()
value = ngx.HTTP_NOT_ALLOWED ()
value = ngx.HTTP_NOT_ACCEPTABLE () (first added in the v0.9.20 release)
value = ngx.HTTP_REQUEST_TIMEOUT () (first added in the v0.9.20 release)
value = ngx.HTTP_CONFLICT () (first added in the v0.9.20 release)
value = ngx.HTTP_GONE ()
value = ngx.HTTP_UPGRADE_REQUIRED () (first added in the v0.9.20 release)
value = ngx.HTTP_TOO_MANY_REQUESTS () (first added in the v0.9.20 release)
value = ngx.HTTP_CLOSE () (first added in the v0.9.20 release)
value = ngx.HTTP_ILLEGAL () (first added in the v0.9.20 release)
value = ngx.HTTP_INTERNAL_SERVER_ERROR ()
value = ngx.HTTP_METHOD_NOT_IMPLEMENTED ()
value = ngx.HTTP_BAD_GATEWAY () (first added in the v0.9.20 release)
value = ngx.HTTP_SERVICE_UNAVAILABLE ()
value = ngx.HTTP_GATEWAY_TIMEOUT () (first added in the v0..1rc38 release)
value = ngx.HTTP_VERSION_NOT_SUPPORTED () (first added in the v0.9.20 release)
value = ngx.HTTP_INSUFFICIENT_STORAGE () (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(...)
上下文: 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 =
}
access_by_lua_block {
ngx.ctx.foo = ngx.ctx.foo +
}
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 =
ngx.say("sub post: ", ngx.ctx.blah)
}
} location /main {
content_by_lua_block {
ngx.ctx.blah =
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:
sub pre: nil
sub post:
main post:
在此,改性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 = , bar = }
当在上下文中使用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.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=
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_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 = , 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 = }}); ngx.print(res.body)
}
}
访问/lua
将产生的输出:
dog = hello
cat =
该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] #: * 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-]+)\/([a-zA-Z0-]+)(|-).*\.(m3u8|ts)) {
set $app_name $;
set $a $;
}
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 ;
proxy_send_timeout ;
proxy_read_timeout ;
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()
--建立连接
local ip = '127.0.0.1'
local port =
--尝试连接到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() --调用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)
思路图片:
Nginx模块Lua-Nginx-Module学习笔记(一)Nginx Lua API 接口详解的更多相关文章
- Linux防火墙iptables学习笔记(三)iptables命令详解和举例[转载]
Linux防火墙iptables学习笔记(三)iptables命令详解和举例 2008-10-16 23:45:46 转载 网上看到这个配置讲解得还比较易懂,就转过来了,大家一起看下,希望对您工作能 ...
- (转)live555学习笔记10-h264 RTP传输详解(2)
参考: 1,live555学习笔记10-h264 RTP传输详解(2) http://blog.csdn.net/niu_gao/article/details/6936108 2,H264 sps ...
- 【精选】Nginx模块Lua-Nginx-Module学习笔记(一)Nginx Lua API 接口详解
源码地址:https://github.com/Tinywan/Lua-Nginx-Redis 一.介绍 各种* _by_lua,* _by_lua_block和* _by_lua_file配置指令用 ...
- 【官方文档】Nginx模块Nginx-Rtmp-Module学习笔记(一) RTMP 命令详解
源码地址:https://github.com/Tinywan/PHP_Experience 说明: rtmp的延迟主要取决于播放器设置,但流式传输软件,流的比特率和网络速度(以及响应时间“ping” ...
- 《基于Nginx的中间件架构》学习笔记---4.nginx编译参数详细介绍
通过nginx -V查看编译时参数: 在nginx安装目录下,通过./configure --help,查看对应版本ngnix编译时支持的所有参数: Nginx编译参数详细介绍: --help 显示本 ...
- SNMP学习笔记之SNMP 原理与实战详解
原文地址:http://freeloda.blog.51cto.com/2033581/1306743 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法 ...
- 学习笔记--Grunt、安装、图文详解
学习笔记--Git安装.图文详解 安装Git成功后,现在安装Gruntjs,官网:http://gruntjs.com/ 一.安装node 参考node.js 安装.图文详解 (最新的node会自动安 ...
- Django学习笔记之Django Form表单详解
知识预览 构建一个表单 在Django 中构建一个表单 Django Form 类详解 使用表单模板 回到顶部 构建一个表单 假设你想在你的网站上创建一个简单的表单,以获得用户的名字.你需要类似这样的 ...
- 【官方文档】Nginx模块Nginx-Rtmp-Module学习笔记(二)HLS 指令详解
源码地址:https://github.com/Tinywan/PHP_Experience 一.在Nginx配置文件的RTMP模块中配置hls hls_key_path /tmp/hlskeys; ...
随机推荐
- 团队作业5-Alpha版本测试报告
1.在测试过程中总共发现了多少Bug?每个类别的Bug分别为多少个? 修复的Bug: a. 修复的bug: 页面打开后比例改变: 出现中文乱码: 点击按钮时不能响应: 导航栏加入显示错误: 上传图片后 ...
- 团队作业4——第一次项目冲刺(Alpha版本)2017.11.16
1.当天站立式会议照片 本次会议在5号公寓3楼召开,本次会议内容:①:熟悉每个人想做的模块.②:根据老师的要求将项目划分成一系列小任务.③:在上次会议内容完成的基础上增加新的任务. 2.每个人的工作 ...
- MySql点点滴滴(一)之可视化工具介绍
以下的文章主要介绍的是10个可以简化开发过程的MySQL工具,其中包括MySQL Workbench.phpMyAdmin.Aqua Data Studio,以及SQLyog与MYSQL Front等 ...
- Windows10(UWP)下的MEF
前言 最近在帮一家知名外企开发Universal Windows Platform的相关应用,开发过程中不由感慨:项目分为两种,一种叫做前人栽树后人乘凉,一种叫做前人挖坑后人遭殃.不多说了,多说又要变 ...
- 每日站立会议——敏捷流程scrum实践
每日站立会议是敏捷流程scrum中的很重要的一个制度之一. 功能: 1.快速同步进展,让项目组内部的员工互相了解彼此的进展,从而了解本项目的整体进展. 2.给每个人一种精神压力,信守 ...
- go 面试题总结
1.什么是goroutine,他与process, thread有什么区别? 2. 什么是channel,为什么它可以做到线程安全? 3. 了解读写锁吗,原理是什么样的,为什么可以做到? 4. 如何用 ...
- response和request的setCharacterEncoding区别
一.request.setCharacterEncoding():是设置从request中取得的值或从数据库中取出的值. 指定后可以通过getParameter()则直接获得正确的字符串,如果不指定, ...
- LaTex Font Size 字体大小
目录 命令 效果图 命令 LaTex中字体大小由以下命令控制: \tiny \scriptsize \footnotesize \small \normalsize \large \Large \LA ...
- MVC3控制器方法获取Form数据方法
http://www.cnblogs.com/bianlan/archive/2013/01/12/2857310.html 控制器方法获取View页面传送的数据有多种方法,以Edit方法为例: 1. ...
- 关于ASP.NET MVC的Html.BeginForm()方法
http://zhidao.baidu.com/link?url=9j53URZJv2B9W-TPtQAaKCRbqIcYy2r3WNO0NDzciTON0EYj5Hhd3rl3UlIllK1CqOC ...