进阶Openresty高级功能之常用指令

2024-05-13 16:10:52 浏览数 (2)

Lua中有比较多常用且实用的指令,接下来将介绍常用的access_by_lua_xxxcontent_by_lua_xxxlog_by_lua_xxxlua_shared_dictlua_package_pathlua_code_cacheinit_worker_by_lua_file指令。

access_by_lua_xxx

access_by_lua支持将要执行的lua代码封装到文件或代码块中,分别对应着access_by_lua_fileaccess_by_lua_block。这类指令用于在请求的访问阶段执行Lua代码。它允许你在Nginx配置文件中嵌入Lua代码块,并在请求的访问阶段执行该代码块。它的作用是在请求进入Nginx后,但在请求被传递给后端服务器之前,对请求进行访问控制、重定向或其他自定义操作。

代码语言:lua复制
location / {
  access_by_lua_file service/access_check.lua;
  ...
}

-- 或者
location / {
  access_by_lua_block {
    -- Lua code here
  }
}

content_by_lua_xxx

content_by_lua支持将要执行的lua代码封装到文件或代码块中,分别对应着content_by_lua_filecontent_by_lua_block。这类指令用于在请求的内容处理阶段执行Lua代码。它允许你在Nginx配置文件中嵌入Lua代码块,并在请求的内容处理阶段执行该代码块。它的作用是在请求被后端服务器处理之前,对请求的内容进行修改、过滤或其他自定义操作。

代码语言:lua复制
location / {
  ...
  content_by_lua_file service/access_check.lua;
  ...
}

--或者

location / {
  ...
  content_by_lua_block {
    -- Lua code here
  }
}

log_by_lua_xxx

log_by_lua支持将要执行的lua代码封装到文件或代码块中,分别对应着log_by_lua_filelog_by_lua_block。这类指令用于在请求的日志记录阶段执行Lua代码。它允许你在Nginx配置文件中嵌入Lua代码块,并在请求的日志记录阶段执行该代码块。它的作用是在请求完成后,对请求的日志进行自定义处理、记录额外的信息或执行其他自定义操作。

代码语言:lua复制
location / {
  ...
  log_by_lua_file service/access_check.lua;
}

--或者
location / {
  ...
  log_by_lua_block {
    -- Lua code here
    ngx.log(ngx.INFO," request end")
  }
}

lua_shared_dict

代码语言:lua复制
http {
    lua_shared_dict uri_white_list_cache 10m;   # 创建一个10MB的共享字典

    server {
        ...
    }
}

lua_shared_dict 用于创建和配置Lua共享字典(shared dictionary)。

Lua共享字典是一种在Nginx中用于存储和共享数据的机制。它允许不同的Nginx worker进程之间共享数据,以及在同一请求的不同阶段之间传递数据。

通过 lua_shared_dict 指令,你可以定义一个共享字典,并为其指定名称、大小和其他属性。这样,你就可以在Lua代码中使用这个共享字典来存储和访问数据。

共享字典的作用包括但不限于:

  1. 在不同的Nginx worker进程之间共享数据。这对于需要在多个worker进程之间共享状态或缓存数据的应用程序非常有用。
  2. 在同一请求的不同阶段之间传递数据。例如,你可以在 access_by_lua 阶段将一些数据存储在共享字典中,然后在 content_by_lua 阶段或其他后续阶段中访问这些数据。
  3. 作为一个高效的缓存机制。共享字典可以用于缓存计算结果、数据库查询结果或其他需要频繁访问的数据,以提高性能和响应速度。

需要注意的是,共享字典是在Nginx的内存中分配的,因此你需要根据实际需求合理配置共享字典的大小,以避免内存溢出或浪费。

使用示例:在另外的lua脚本中可以获取cache变量,并进行赋值。

代码语言:lua复制
-- 获取全局的缓存变量
local white_list_cache = ngx.shared.uri_white_list_cache
local function load_white_list()
    local prefix = ngx.config.prefix()
    local uri_file_path = prefix .. "/conf/uri_white_list.txt"
    local uri_file = io.open(uri_file_path, "r")
    if uri_file then
        for line in uri_file:lines() do
            line = line:gsub("^%s*(.-)%s*$", "%1")
            -- 更新全局的缓存变量
            table.insert(white_list_cache, line)
        end
        ngx.log(ngx.INFO, "Load URI white list (" .. (#white_list_cache-1) .. " uris) file success")
    else
        ngx.log(ngx.ERR, "Failed to open URI white list file")
    end
    uri_file:close()
end

load_white_list()

lua_package_path

代码语言:lua复制
http {
    lua_package_path '$prefix/service/?.lua;/blah/?.lua;;';

    server {
        ...
    }
}

lua_package_path 用于设置Lua模块的搜索路径。

在指令 lua_package_path 中,$prefix 是一个变量,表示Nginx安装目录的路径。$prefix/service/?.lua/blah/?.lua 是具体的路径模式。

这个指令的作用是告诉Nginx在加载Lua模块时应该搜索的路径。路径模式中的 ?.lua 是一个通配符,表示匹配任意的Lua文件名。

具体来说,lua_package_path 的设置会影响到 require 函数在Nginx中加载Lua模块时的搜索路径。当你在Lua代码中使用 require 加载模块时,Nginx会按照 lua_package_path 指定的路径顺序进行搜索,直到找到匹配的模块文件。

在上述示例中,lua_package_path 设置为 $prefix/service/?.lua;/blah/?.lua;;,表示Nginx会按照以下顺序搜索Lua模块:

  1. $prefix/service/?.lua:在Nginx安装目录下的 service 目录中搜索Lua模块文件。
  2. /blah/?.lua:在 /blah 目录中搜索Lua模块文件。
  3. ;;:表示使用默认的搜索路径,通常是Nginx的安装目录下的 lua 目录。

通过设置 lua_package_path,你可以指定自定义的Lua模块搜索路径,以便Nginx能够正确加载和使用你的Lua模块。

lua_code_cache

代码语言:lua复制
http {
    lua_code_cache on;  

    server {
        ...
    }
}

lua_code_cache on; 用于启用Lua代码缓存。

lua_code_cache设置为on时,Nginx会将已经加载和编译的Lua代码缓存起来,以便在后续的请求中重复使用。这样可以提高性能,减少每个请求中重新加载和编译Lua代码的开销。

启用Lua代码缓存可以显著提高Nginx服务器处理Lua脚本的效率,特别是在高并发的情况下。缓存的Lua代码将在内存中保留,以便在需要时快速执行,而不必每次都重新加载和编译。

需要注意的是,当你修改了Lua代码时,需要重启或重新加载Nginx服务器,以使新的代码生效。否则,Nginx将继续使用缓存中的旧代码。

init_worker_by_lua_file

代码语言:lua复制
http {
    init_worker_by_lua_file service/init_cache.lua;

    server {
        ...
    }
}

init_worker_by_lua_file 用于在Nginx worker进程启动时执行Lua代码。

当使用 init_worker_by_lua_file 指令时,你可以指定一个Lua脚本文件的路径,Nginx会在每个worker进程启动时加载并执行该Lua脚本。

这个指令的作用是在Nginx worker进程启动时执行一些初始化的操作,通常用于执行一些全局的、只需执行一次的任务,例如:

  • 预加载Lua模块或库文件。
  • 初始化全局变量或共享内存。
  • 启动定时任务或后台进程。
  • 进行一些初始化的配置或设置。

通过使用 init_worker_by_lua_file,可以在Nginx启动时执行自定义的Lua代码,以满足特定的需求。这样可以在Nginx运行期间进行一些额外的初始化操作,提高灵活性和扩展性。

需要注意的是,init_worker_by_lua_file 只会在worker进程启动时执行一次,而不是每个请求都执行。如果需要在每个请求中执行Lua代码,可以使用 access_by_lua_filecontent_by_lua_file 指令。

0 人点赞