nginx有11个处理阶段,如下图所示:
每一个处理阶段描述
指令 | 所处处理阶段 | 使用范围 | 解释 |
---|---|---|---|
init_by_lua init_by_lua_file | loading-config | http | nginx Master进程加载配置时执行;通常用于初始化全局配置/预加载Lua模块 |
init_worker_by_lua init_worker_by_lua_file | starting-worker | http | 每个Nginx Worker进程启动时调用的计时器,如果Master进程不允许则只会在init_by_lua之后调用;通常用于定时拉取配置/数据,或者后端服务的健康检查 |
set_by_lua set_by_lua_file | rewrite | server,server if,location,location if | 设置nginx变量,可以实现复杂的赋值逻辑;此处是阻塞的,Lua代码要做到非常快; |
rewrite_by_lua rewrite_by_lua_file | rewrite tail | http,server,location,location if | rrewrite阶段处理,可以实现复杂的转发/重定向逻辑; |
access_by_lua access_by_lua_file | access tail | http,server,location,location if | 请求访问阶段处理,用于访问控制 |
content_by_lua content_by_lua_file | content | location,location if | 内容处理器,接收请求处理并输出响应 |
header_filter_by_lua header_filter_by_lua_file | output-header-filter | http,server,location,location if | 设置header和cookie |
body_filter_by_lua body_filter_by_lua_file | output-body-filter | http,server,location,location if | 对响应数据进行过滤,比如截断、替换。 |
log_by_lua log_by_lua_file | log | http,server,location,location if | log阶段处理,比如记录访问量/统计平均响应时间 |
一般我们在开发过程中常用到的阶段如下:
set_by_lua、rewrite_by_lua、access_by_lua、content_by_lua、header_filter_by_lua、body_filter_by_lua、log_by_lua、
1.set_by_lua
做流程分支判断,判断变量初始化
2.rewrite_by_lua
转发重定向,缓存功能
3.access_by_lua
ip准入,接口合法权限判断,根据iptable做防火墙的功能
4.content_by_lua
内容生产
5.header_filter_by_lua
增加头部信息
6.body_filter_by_lua
内容过滤
7.log_by_lua
记录日志
先开发好lua脚本:ikong_api.lua
-- Require Modules
local conf = require "ik_config"
local cjson = require "cjson.safe"
local precheck = require "ik_precheck"
-- Performance Optimization
local pcall = pcall
local error = error
local str_format = string.format
local io_open = io.open
local math_randomseed = math.randomseed
local math_rand = math.random
local new_timer = ngx.timer.at
local DEBUG = ngx.DEBUG
local INFO = ngx.INFO
local ERR = ngx.ERR
local HTTP_OK = ngx.HTTP_OK
local cjson_encode = cjson.encode
local debug_mode = ngx.config.debug
local ngx_log = ngx.log
local ngx_var = ngx.var
local ngx_now = ngx.now
local ngx_redirect = ngx.redirect
local ngx_exit = ngx.exit
local ngx_req_read_body = ngx.req.read_body
local ngx_req_get_body_data = ngx.req.get_body_data
local ngx_header = ngx.header
local ngx_say = ngx.say
local ngx_shm = ngx.shared
local ik_conf_server = conf.ik_server
local ikong_ctrl_shm = ngx_shm[conf.ik_ctrl_shared_dict_name]
local ik_xx_key = conf.ik_xx_key
local _M = {}
_M._VERSION = '1.0.0'
-- enable check
local function enable()
ngx_req_read_body()
local body = ngx_req_get_body_data() //这里获取到body,必须先调用上面ngx_req_read_body函数,才能拿到body的data
ngx_header.content_type = "application/json"
if succ then
-- set to file
-- enable
if ikong_ctrl_shm:get(ik_xx_key) == false then
ikong_ctrl_shm:set(ik_xx_key, true, 0)
info("enable ik module")
end
-- response data
ngx_say(cjson_encode({
["success"] = true,
["msg"] = ""
}))
else
ngx_say(cjson_encode({
["success"] = false,
["msg"] = err
}))
end
end
-- disable check
local function disable()
ngx_exit(HTTP_OK)
end
local function update_conf()
ngx_exit(HTTP_OK)
end
-- check timeout
local function check_timeout()
ngx_exit(HTTP_OK)
end
-- get status
local function status()
ngx_exit(HTTP_OK)
end
if ngx_var.request_method == "POST" then
if ngx_var.uri == conf.ik_api_enable then
return enable()
end
if ngx_var.uri == conf.ik_api_disable then
return disable()
end
if ngx_var.uri == conf.ik_api_conf then
return update_conf()
end
if ngx_var.uri == conf.ik_api_check_timeout then
return check_timeout()
end
elseif ngx_var.request_method == "GET" then
if ngx_var.uri == conf.ik_api_status then
return status()
end
end
return ngx_exit(HTTP_FORBIDDEN)
nginx下加入conf的配置
lua_shared_dict ikong_ctrl_shm 1M; //定义shm缓存
# ikong server
server {
listen 8009;
location ~ ^/ikong-api/([-_a-zA-Z0-9]+) {
allow 127.0.0.1;
deny all;
content_by_lua_file /Users/ikong/ikong_api.lua;
}
}