魏长东

weichangdong

东邪

lua学习-高级篇

Nginx Lua模块指令

Nginx共11个处理阶段,而相应的处理阶段是可以做插入式处理,即可插拔式架构;另外指令可以在http、server、server if、location、location if几个范围进行配置:

指令

所处处理阶段

使用范围

解释

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阶段处理,比如记录访问量/统计平均响应时间

 

更详细的解释请参考http://wiki.nginx.org/HttpLuaModule#Directives。如上指令很多并不常用,因此我们只拿其中的一部分做演示。

init_by_lua

每次Nginx重新加载配置时执行,可以用它来完成一些耗时模块的加载,或者初始化一些全局配置;在Master进程创建Worker进程时,此指令中加载的全局变量会进行Copy-OnWrite,即会复制到所有全局变量到Worker进程。

#共享全局变量,在所有worker间共享  
lua_shared_dict shared_data 1m;  
  
init_by_lua_file html/init.lua;  

代码:

init.lua 文件

--初始化耗时的模块  
local redis = require 'resty.redis'  
local cjson = require 'cjson'  
  
--全局变量,不推荐  
count = 10  
  
--共享全局内存  
local shared_data = ngx.shared.shared_data  
shared_data:set("count", 100)  

test7.lua文件

count = count + 1  
ngx.say("global variable : ", count)  
local shared_data = ngx.shared.shared_data  
ngx.say("======================<br />") 

ngx.say(", shared memory : ", shared_data:get("count"))
shared_data:incr("count", 1)
ngx.say("hello world")

会发现全局变量一直不变,而共享内存一直递增(我在本地环境测试了,发现全局变量是一直不变,但是共享内从变量也不变,但是我在前面分明吧这个功能测试成功了,难道是我是用的win环境)

 

init_worker_by_lua

用于启动一些定时任务,比如心跳检查,定时拉取服务器配置等等;此处的任务是跟Worker进程数量有关系的,比如有2个Worker进程那么就会启动两个完全一样的定时任务。

 

1、nginx.conf配置文件中的http部分添加如下代码

init_worker_by_lua_file html/init_work.lua; 

init_worker.lua 代码

local count = 0  
local delayInSeconds = 3  
local heartbeatCheck = nil  
local str='weichangdong'
  
heartbeatCheck = function(args)  
   count = count + 1  
   ngx.log(ngx.ERR, "do check ", count)  
  
   local ok, err = ngx.timer.at(delayInSeconds, heartbeatCheck)  
  
   if not ok then  
      ngx.log(ngx.ERR, "failed to startup heartbeart worker...", err) 
   else
	ngx.log(ngx.ERR, "wcd ", str) 
   end  
end  
  
heartbeatCheck() 

 

随便访问localhost

看logs下的error.log文件,部分输出

2016/04/10 12:02:40 [error] 9116#8224: [lua] init_work.lua:8: do check 17, context: ngx.timer
2016/04/10 12:02:40 [error] 9116#8224: [lua] init_work.lua:15: wcd weichangdong, context: ngx.timer
2016/04/10 12:02:43 [error] 9116#8224: [lua] init_work.lua:8: do check 18, context: ngx.timer
2016/04/10 12:02:43 [error] 9116#8224: [lua] init_work.lua:15: wcd weichangdong, context: ngx.timer
2016/04/10 12:02:46 [error] 9116#8224: [lua] init_work.lua:8: do check 19, context: ngx.timer
2016/04/10 12:02:46 [error] 9116#8224: [lua] init_work.lua:15: wcd weichangdong, context: ngx.timer
2016/04/10 12:02:49 [error] 9116#8224: [lua] init_work.lua:8: do check 20, context: ngx.timer
2016/04/10 12:02:49 [error] 9116#8224: [lua] init_work.lua:15: wcd weichangdong, context: ngx.timer

ngx.timer.at:延时调用相应的回调方法;ngx.timer.at(秒单位延时,回调函数,回调函数的参数列表);可以将延时设置为0即得到一个立即执行的任务,任务不会在当前请求中执行不会阻塞当前请求,而是在一个轻量级线程中执行。

 

另外根据实际情况设置如下指令

lua_max_pending_timers 1024;  #最大等待任务数

lua_max_running_timers 256;    #最大同时运行任务数