nginx/lua/OpenResty

运行曰志

函数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 语法和编程规范,并对可能的错误进行错误处理。

猜你喜欢

转载自blog.csdn.net/machh/article/details/130344265