运行曰志
函数ngx.log(log level, …)记录OpenResty的运行日志,用法很类似Lua的标准库
函数 print,可以接受任意多个参数,记录任意信息。
ngx.log 的第一个参数是日志级别,只有高于配置文件里“error log,设.定级别的消息才会被真正地写入日志(通常都是 error 级),取值从高到低是:
- ngx . STDERR 日志直接打印到标准输出,最高级别的 日志
- ngx. EMERG 发生了紧急情况( emergency),
- ngx . ALERT 发生严重错误 ,可 能需要报警给运维系统:
- ngx.CRIT . 发生严重错误( critical) ;
- ngx . ERR 普通的错误,业务中发生了意外;
- ngx . WARN 警告信息,业务正常,但可能要检查警告的来源:
- ngx.NOTICE 提醒信息 仅仅是告知,通常可 以忽略:
- ngx. INFO 一般的信息;
- ngx . DEBUG 调试用的信息,只有 debug 版本才会启用。
location 匹配
location 指令可以根据请求的 URI 进行配置。
匹配操作在规范化的 URI 上进行,包括解码以 “%XX” 形式编码的文本,解析相对路径组件中的 “.” 和 “…”,以及可能的将两个或更多相邻的斜杠压缩为一个斜杠。
location 可以通过前缀字符串或正则表达式进行定义。正则表达式可以使用前缀 “~*” 修饰符(用于不区分大小写的匹配)或 “~” 修饰符(用于区分大小写的匹配)。为了找到与给定请求匹配的 location,Nginx 首先检查使用前缀字符串定义的 location(前缀 location)。其中,选择具有最长匹配前缀的 location 并记住它。然后,按照在配置文件中出现的顺序检查正则表达式。正则表达式的搜索在找到第一个匹配后终止,并使用相应的配置。如果没有与正则表达式匹配的项,则使用之前记住的前缀 location 的配置。
location 块可以嵌套,但有一些例外情况。
对于不区分大小写的操作系统,如 macOS 和 Cygwin,使用前缀字符串进行匹配时会忽略大小写(0.7.7)。但是,比较限于单字节的本地化。
正则表达式可以包含捕获组(0.7.40),可以在其他指令中使用。
如果具有最长匹配前缀的 location 使用了 “^~” 修饰符,则不会检查正则表达式。
此外,使用 “=” 修饰符可以定义 URI 和 location 的完全匹配。如果找到完全匹配,则搜索终止。例如,如果频繁发生 "/ "请求,定义 “location = /” 将加速这些请求的处理,因为搜索会在第一次比较后终止。这样的 location 显然不能包含嵌套的 location。
示例:
location ~ " / (\w+) {
content_by_lua_file service/http/$1.lua;
}
这是一个 Nginx 的 location 配置指令,其中 ~ 符号表示使用正则表达式进行匹配。它会匹配以斜杠 “/” 开头,并且后面紧跟着一个或多个字母、数字、下划线的字符串。
解析该配置指令的含义如下:
- 当请求的 URL 路径满足正则表达式 “/ (\w+)” 时,即以斜杠 “/” 开头,后面跟着一个或多个字母、数字、下划线的字符串时,这个 location 配置将生效。
- 当匹配成功时,Nginx 将执行后面的指令:content_by_lua_file service/http/$1.lua;
- 这里使用了 Lua 脚本处理请求的内容,脚本文件的路径由请求中的匹配组 $1 的值来决定,即将匹配到的字符串作为文件名,并拼接到 “service/http/” 路径下,以 “.lua” 作为文件扩展名。
- 意味着该配置将请求路径中的匹配到的字符串作为 Lua 脚本文件名,并通过 content_by_lua_file 指令执行该脚本,处理请求的内容。
模块
在 Lua 中,模块是一种组织代码的方式,可以将相关的函数、变量和常量封装到一个独立的命名空间中,以便在其他地方引用和使用。local _M = {} 语句创建了一个名为 _M 的局部变量,并将一个空的表(table)赋值给它。这个表将用于存放模块中的函数、变量和常量。
模块的定义通常包含在一个 Lua 文件中,并以 return 语句结束,将定义好的表作为模块的返回值。例如,一个简单的 Lua 模块可以如下定义:
-- my_module.lua
local _M = {
}
function _M.foo()
print("This is foo() function")
end
function _M.bar()
print("This is bar() function")
end
return _M
在上面的例子中,模块 my_module 定义了两个函数 foo() 和 bar(),并将它们放在了 _M 表中。模块文件以 return _M 结束,将 _M 表作为模块的返回值,使得其他地方可以通过 require 函数引用这个模块,并访问其中的函数。
使用 local _M = {} 的方式可以有效地将模块中的函数、变量和常量封装到一个局部作用域中,避免了全局变量的污染和命名冲突,同时也符合了模块化编程的思想。在实际的 Lua 编程中,这种方式非常常见,用于定义各种类型的 Lua 模块,包括在 OpenResty 中使用的 ngx_http_lua_module 模块。
nginx 中的rewrite_by_lua_file用法
在 Nginx 中,rewrite_by_lua_file 指令用于在请求处理阶段使用 Lua 脚本进行 URI 重写。其用法如下:
rewrite_by_lua_file <lua_file_path>;
其中 <lua_file_path> 是指定的 Lua 脚本文件的路径,可以是绝对路径或相对路径。
当请求到达 Nginx,并匹配到 rewrite_by_lua_file 指令所在的 location 块时,Nginx 将会执行指定路径下的 Lua 脚本文件。在 Lua 脚本中,可以通过 ngx 模块来操作请求对象和响应对象,实现自定义的 URI 重写逻辑。
以下是一个简单的示例,演示如何使用 rewrite_by_lua_file 指令进行 URI 重写:
location /example {
rewrite_by_lua_file /path/to/lua_script.lua;
}
在上面的例子中,当请求 URI 匹配到 /example 时,Nginx 将会执行 /path/to/lua_script.lua 中的 Lua 脚本进行 URI 重写操作。
在 Lua 脚本中,可以通过 ngx.req 对象获取请求对象的信息,如请求 URI、请求方法、请求头等;
通过 ngx.req.set_uri 方法设置新的 URI,从而实现 URI 重写。
例如:
-- 获取请求 URI
local uri = ngx.req.uri
-- 对请求 URI 进行处理,例如添加前缀
uri = "/new_prefix" .. uri
-- 设置新的 URI
ngx.req.set_uri(uri)
需要注意的是,rewrite_by_lua_file 指令中指定的 Lua 脚本应该是可读取并执行的,并且应该具有足够的权限来访问所需的文件或资源。在编写 Lua 脚本时,应该遵循 Lua 语法和编程规范,并对可能的错误进行错误处理。