init_by_lua_block 每次执行请求都会执行。 不能使用lrucache 并且不能缓存。 init_worker_by_lua_block 执行work线程数的次数。
。lua_code_cache 为off 情况下可以用于代码调试,不过会产生很多bug。init_by_lua_block 执行一次。能够使用lrucache。init work 阶段一样。
enum {
SHDICT_TNIL = 0, /* same as LUA_TNIL */
SHDICT_TBOOLEAN = 1, /* same as LUA_TBOOLEAN */
SHDICT_TNUMBER = 3, /* same as LUA_TNUMBER */
SHDICT_TSTRING = 4, /* same as LUA_TSTRING */
SHDICT_TLIST = 5,
};
function _M:init()
math.randomseed(ngx.time())
local server = ngx.shared.server
server:set("local_ip", utils.get_local_ip())
end
local index = math.random(1, 20)
http {
#文件扩展名与文件类型映射表
include mime.types;
#默认文件类型,默认为text/plain
default_type text/html;
...
server {
server_name api.weibo.com;
listen 0.0.0.0:8888;
listen 127.0.0.1:8888;
#listen 10.211.55.3:8888;
error_page 400 404 408 411 412 413 414 417 494 /va_error_handler;
error_page 500 502 503 504 /va_error_handler;
client_body_buffer_size 5m;
lua_need_request_body on;
#real_ip_header X-Real-IP;
#real_ip_recursive off;
location / {
set $upstream_host '';
set $upstream_uri '';
set $ctx_ref '';
使用方式:
if string.find(temp_uri, "?") == nil then
ngx.var.upstream_uri = temp_uri .. "?" .. ctx.req.uri_args_str
else
ngx.var.upstream_uri = temp_uri .. "&" .. ctx.req.uri_args_str
end
xpcall(function() va.header_filter() end, function(err)
ngx.log(ngx.ERR, "\n==>Err. va.header_filter Error: " .. err )
ngx.log(ngx.ERR, "\n==>Err. va.header_filter Error: " .. debug.traceback() )
end)
ngx.log(ngx.ERR, "come here“ )
local status, retval = pcall(
function() auth_client:httpAuth
end
if not status then
ngx.log(ngx.ERR, "auth_client is error: ", retval, " url: ", ngx.var.request_uri .. "\n")
end
access,content等请求之前阶段,调用的ngx.say ngx.status都会到这两个阶段
local strs = {};
for i = 1, 3, 1 do
strs[i] = "helloworld";
end
local startTime = os.clock();
for i = 1, 2000000, 1 do
local result = {};
-- for index, str in ipairs(strs) do
table.insert(result, strs[1])
table.insert(result, strs[2])
table.insert(result, strs[3])
-- end
result = table.concat(result);
end
local endTime = os.clock();
local useTime = endTime - startTime;
print("消耗时间:" .. useTime .. "s");
local strs = {};
for i = 1, 3, 1 do
strs[i] = "helloworld";
end
local startTime = os.clock();
for i = 1, 2000000, 1 do
result = strs[1] .. strs[2] .. strs[3]
end
local endTime = os.clock();
local useTime = endTime - startTime;
print("消耗时间:" .. useTime .. "s");
1、jo 参数的作用
下面是常用的选项:
local url_str = "http://blog.stackoverflow.com/2016/10/Stack-Overflow-92-Podcast-The-Guerilla-Guide-to-Interviewing/?cb=1"
local max = 1000000
local t = os.clock()
for _ = 1, max do
ngx.re.find(url_str, [[^https?://[\w-_?.:/+=%]+$]])
end
ngx.log(ngx.ERR, "ngx.re.find nil cost is ", os.clock() - t)
local t1 = os.clock()
for _ = 1, max do
ngx.re.find(url_str, [[^https?://[\w-_?.:/+=%]+$]], "jo")
end
ngx.log(ngx.ERR, "ngx.re.find jo cost is ", os.clock() - t1)
2018/09/13 06:32:40 [error] 13#13: *14 [lua] init.lua:103: access(): ngx.re.find nil cost is 1.84
2018/09/13 06:32:40 [error] 13#13: *14 [lua] init.lua:110: access(): ngx.re.find jo cost is 0.16
2、string.find ngx.re.find 无正则情况对比
local url_str = "我打死奥的煎熬ID阿吉豆我安静到都弄一你师父哪懂啊达到ID煎熬ID骄傲的"
local max = 1000000
local t = os.clock()
for _ = 1, max do
string.find(url_str, "安静到")
end
ngx.log(ngx.ERR, "string.find cost is ", os.clock() - t)
local t1 = os.clock()
for _ = 1, max do
ngx.re.find(url_str, "安静到", "jo")
end
ngx.log(ngx.ERR, "ngx.re.find jo cost is ", os.clock() - t1)
2018/09/13 07:46:42 [error] 14#14: *33 [lua] init.lua:110: access(): string.find cost is 0
2018/09/13 07:46:42 [error] 14#14: *33 [lua] init.lua:117: access(): ngx.re.find jo cost is 0.05
3、string.find 对正则支持的很弱,不建议使用。 性能也是弱与ngx.re.find的
local url_str = "http://blog.stackoverflow.com/2016/10/Stack-Overflow-92-Podcast-The-Guerilla-Guide-to-Interviewing/?cb=1"
local max = 1000000
local t = os.clock()
for _ = 1, max do
url_str:find("^https?://[%w-_%.%?:/%+=%%]+$")
end
ngx.log(ngx.ERR, "string.find cost is ", os.clock() - t)
local t1 = os.clock()
for _ = 1, max do
ngx.re.find(url_str, "^https?://[%w-_%.%?:/%+=%%]+$", "jo")
end
ngx.log(ngx.ERR, "ngx.re.find jo cost is ", os.clock() - t1)
2018/09/13 06:54:08 [error] 14#14: *88 [lua] init.lua:108: access(): string.find cost is 0.84
2018/09/13 06:54:08 [error] 14#14: *88 [lua] init.lua:115: access(): ngx.re.find jo cost is 0.55
ngx.re.find 注意事项
注意一些正则的特殊字符,需要转义后匹配
例如:
“.” 需要转义为 /.
“*” 需要转义为 /*
static int
ngx_http_lua_shdict_get_helper(lua_State *L, int get_stale)
{
ngx_shmtx_lock(&ctx->shpool->mutex);
rc = ngx_http_lua_shdict_lookup(zone, hash, key.data, key.len, &sd);
switch (value_type) {
case SHDICT_TSTRING:
lua_pushlstring(L, (char *) value.data, value.len); -- 交个lua
break;
default:
ngx_shmtx_unlock(&ctx->shpool->mutex);
return luaL_error(L, "bad value type found for key %s in "
"shared_dict %s: %d", key.data, name.data,
value_type);
}
user_flags = sd->user_flags;
ngx_shmtx_unlock(&ctx->shpool->mutex);
return 1;
}
int
ngx_http_lua_ffi_shdict_get(ngx_shm_zone_t *zone, u_char *key,
size_t key_len, int *value_type, u_char **str_value_buf,
size_t *str_value_len, double *num_value, int *user_flags,
int get_stale, int *is_stale, char **err)
{
ngx_shmtx_lock(&ctx->shpool->mutex);
rc = ngx_http_lua_shdict_lookup(zone, hash, key, key_len, &sd);
switch (*value_type) {
case SHDICT_TSTRING:
*str_value_len = value.len;
ngx_memcpy(*str_value_buf, value.data, value.len); -- 自己搞
break;
default:
ngx_shmtx_unlock(&ctx->shpool->mutex);
return NGX_ERROR;
}
ngx_shmtx_unlock(&ctx->shpool->mutex);
return NGX_OK;
}
15172 str objects: max=2956, avg = 51, min=18, sum=779126
987 upval objects: max=24, avg = 24, min=24, sum=23688
104 thread objects: max=1648, avg = 1622, min=528, sum=168784
431 proto objects: max=226274, avg = 2234, min=78, sum=963196
952 func objects: max=144, avg = 30, min=20, sum=28900
446 trace objects: max=23400, avg = 1857, min=160, sum=828604
2965 cdata objects: max=4112, avg = 17, min=12, sum=51576
18961 tab objects: max=24608, avg = 207, min=32, sum=3943256
9 udata objects: max=176095, avg = 39313, min=32, sum=353822
(gdb) lgcpath 100000 tab
path 000:[registry] ->Tab["_LOADED"] ->Tab["ffi"] ->Tab["gc"] ->cfunc ->env ->Tab sz:196640 (GCobj*)0x40784f58 ->END
path 001:[registry] ->Tab[tv=0x4132e470] ->Tab sz:524328 (GCobj*)0x40783108 ->END
function V.access()
-- @usage: use to check the xctx lib for ab/wrk test
-- if ctx.req.uri_args.f == "a" then
-- ctx.xxxxx = 'a'
-- elseif ctx.req.uri_args.f == "b" then
-- ctx.xxxxx = 'b'
-- end
_v()
xctx.stash_ngx_ctx()
end
这里是先调用的v 然后在进行 ctx 复制
#0 0x00007fd9c5a1cbfa in err_unwind (L=L@entry=0x4192c378, stopcf=0x7fffbb362c00, errcode=errcode@entry=0) at lj_err.c:111
#1 0x00007fd9c5a1cfe5 in lj_err_unwind_dwarf (version=, actions=1, uexclass=5500374307216568836, uex=0x7fd9c64f6720, ctx=0x7fffbb362850)
at lj_err.c:241
#2 0x00007fd9c4d20bb3 in _Unwind_RaiseException () from /lib64/libgcc_s.so.1
#3 0x00007fd9c5a1ce69 in err_raise_ext (errcode=4) at lj_err.c:302
#4 lj_err_throw (L=L@entry=0x4192c378, errcode=errcode@entry=4) at lj_err.c:516
#5 0x00007fd9c5a1d0a3 in lj_err_mem (L=L@entry=0x4192c378) at lj_err.c:552
#6 0x00007fd9c5a1cb30 in lj_mem_newgco (L=L@entry=0x4192c378, size=20) at lj_gc.c:833
#7 0x00007fd9c5a1fb8c in func_newL (L=L@entry=0x4192c378, pt=pt@entry=0x40f927a0, env=0x4192d9d8) at lj_func.c:122
#8 0x00007fd9c5a1fdb0 in lj_func_newL_gc (L=, pt=0x40f927a0, parent=0x41f80018) at lj_func.c:160
#9 0x00007fd9c5a18944 in lj_BC_FNEW () from /usr/local/openresty/luajit/lib/libluajit-5.1.so.2
#10 0x00007fd9c5a2989d in lua_pcall (L=L@entry=0x4192c378, nargs=nargs@entry=0, nresults=nresults@entry=1, errfunc=errfunc@entry=0) at lj_api.c:1129
#11 0x000000000052bc83 in ngx_http_lua_cache_load_code (log=log@entry=0x24f8680, L=L@entry=0x4192c378, key=key@entry=0x24e7ba8 "=log_by_lua(app-prod.conf:199)")
at ../ngx_lua-0.10.13/src/ngx_http_lua_cache.c:56
#12 0x000000000052bdeb in ngx_http_lua_cache_loadbuffer (log=0x24f8680, L=L@entry=0x4192c378,
src=0x24e7958 "\n", ' ' , "local xpcall = xpcall\n", ' ' , "local ngx = ngx\n", ' ' , "xpcall(function() va.log() end, function(err)\n", ' ' , "local ctx = ngx.ctx\n", ' ' , "local err_str = err\n "..., src_len=506,
cache_key=0x24e7ba8 "=log_by_lua(app-prod.conf:199)", name=0x24e7b58 "=log_by_lua(app-prod.conf:199)") at ../ngx_lua-0.10.13/src/ngx_http_lua_cache.c:148
#13 0x000000000053a9cc in ngx_http_lua_log_handler_inline (r=0x24f92a0) at ../ngx_lua-0.10.13/src/ngx_http_lua_logby.c:153
#14 0x000000000053a79b in ngx_http_lua_log_handler (r=0x24f92a0) at ../ngx_lua-0.10.13/src/ngx_http_lua_logby.c:135
#15 0x000000000048e0c0 in ngx_http_log_request (r=r@entry=0x24f92a0) at src/http/ngx_http_request.c:3569
#16 0x000000000048f7d9 in ngx_http_free_request (r=r@entry=0x24f92a0, rc=0) at src/http/ngx_http_request.c:3516
#17 0x000000000048f9a0 in ngx_http_close_request (rc=0, r=) at src/http/ngx_http_request.c:3463
#18 0x000000000048f5b0 in ngx_http_run_posted_requests (c=0x7fd9c63090c0) at src/http/ngx_http_request.c:2274
#19 0x0000000000491cab in ngx_http_process_request_line (rev=0x7fd9b96869f0) at src/http/ngx_http_request.c:1049
#20 0x000000000047b1c7 in ngx_epoll_process_events (cycle=, timer=, flags=)
at src/event/modules/ngx_epoll_module.c:902
#21 0x000000000047264b in ngx_process_events_and_timers (cycle=cycle@entry=0x24c0470) at src/event/ngx_event.c:252
#22 0x0000000000479102 in ngx_worker_process_cycle (cycle=cycle@entry=0x24c0470, data=data@entry=0xb) at src/os/unix/ngx_process_cycle.c:820
#23 0x0000000000477bc4 in ngx_spawn_process (cycle=cycle@entry=0x24c0470, proc=0x479090 , data=0xb, name=0x744b75 "worker process",
respawn=respawn@entry=11) at src/os/unix/ngx_process.c:198
#24 0x000000000047a342 in ngx_reap_children (cycle=0x24c0470) at src/os/unix/ngx_process_cycle.c:687
#25 ngx_master_process_cycle (cycle=cycle@entry=0x24c0470) at src/os/unix/ngx_process_cycle.c:180
#26 0x0000000000453448 in main (argc=, argv=) at src/core/nginx.c:384
local a = 1 local b = 1 a = a + b 局部变量产生的指令
ADD 0 0 1
a = a + b 全局变量产生的指令
GETGLOBAL 0 0 ; a
GETGLOBAL 1 1 ; b
ADD 0 0 1
SETGLOBAL 0 0 ; a
代码测试 demo
local local_demo
local_demo = function()
local t1 =os.clock ()
for i = 1, 1000000000 do
local x = math.sin(i)
end
ngx.update_time()
local t2 =os.clock ()
ngx.log(ngx.ERR, "local_demo cost time ========== " .. t2 - t1)
end
local_demo(): local_demo cost time ========== 0.31
local local_demo2
local_demo2 = function()
local t1 =os.clock ()
local sin = math.sin
for i = 1, 1000000000 do
local x = sin(i)
end
ngx.update_time()
local t2 =os.clock ()
ngx.log(ngx.ERR, "local_demo2 cost time ========== " .. t2 - t1)
end
local_demo2(): local_demo2 cost time ========== 0.33
– 数组的长度越大,提升越高
local local_demo
local_demo = function()
local t1 =os.clock ()
for i = 1, 50000000 do
local a = {}
a[1] = 1;
a[2] = 1;
a[3] = 1;
a[4] = 1;
a[5] = 1;
a[6] = 1;
end
ngx.update_time()
local t2 =os.clock ()
ngx.log(ngx.ERR, "local_demo cost time ========== " .. t2 - t1)
end
local_demo(): local_demo cost time ========== 12.64
local local_demo2
local_demo2 = function()
local t1 =os.clock ()
for i = 1, 50000000 do
local a = {1,2,3,4,5,6}
a[1] = 1;
a[2] = 1;
a[3] = 1;
a[4] = 1;
a[5] = 1;
a[6] = 1;
end
ngx.update_time()
local t2 =os.clock ()
ngx.log(ngx.ERR, "local_demo2 cost time ========== " .. t2 - t1)
end
local_demo2(): local_demo2 cost time ========== 0.02
local local_demo
local_demo = function()
local t1 =os.clock ()
for i = 1, 50000000 do
local a = {}
a[1] = 1;
a[2] = 1;
end
ngx.update_time()
local t2 =os.clock ()
ngx.log(ngx.ERR, "local_demo cost time ========== " .. t2 - t1)
end
local_demo(): local_demo cost time ========== 4.61
local local_demo2
local_demo2 = function()
local t1 =os.clock ()
for i = 1, 50000000 do
local a = {1,2}
a[1] = 1;
a[2] = 1;
end
ngx.update_time()
local t2 =os.clock ()
ngx.log(ngx.ERR, "local_demo2 cost time ========== " .. t2 - t1)
end
local_demo2(): local_demo2 cost time ========== 0.02
local local_demo
local_demo = function()
local t1 =os.clock ()
local a = {}
for i = 1, 5000000 do
a[i] = "a"
end
ngx.update_time()
local t2 =os.clock ()
ngx.log(ngx.ERR, "local_demo cost time ========== " .. t2 - t1)
end
local_demo cost time ========== 0.2
local local_demo2
local_demo2 = function()
local t1 =os.clock ()
local a = {}
for i = 1, 5000000 do
table.insert(a, "a")
end
ngx.update_time()
local t2 =os.clock ()
ngx.log(ngx.ERR, "local_demo2 cost time ========== " .. t2 - t1)
end
local_demo2(): local_demo2 cost time ========== 0.68
local tab = {}
for i = 1, 20000000 do
tab[#tab + 1] = true
end
local time1 = os.clock()
for i = 1, #tab do
tab[i] = true
end
print('正序数值for循环====================', os.clock() - time1)
local time2 = os.clock()
for i = #tab, 1, -1 do
tab[i] = true
end
print('反序数值for循环====================', os.clock() - time2)
local time3 = os.clock()
for k, v in ipairs(tab) do
v = true
end
print('ipairs====================', os.clock() - time3)
local time4 = os.clock()
for k, v in pairs(tab) do
v = true
end
print('pairs====================', os.clock() - time4)
对比结果:
正序数值for循环 0.07
反序数值for循环 0.06
ipairs 0.11
pairs 0.39
local local_demo
local_demo = function(tab)
local t1 =os.clock ()
for k, v in ipairs(tab) do
local a = 1 * 2 + 1 / 2 - 1 + 2
end
ngx.update_time()
local t2 =os.clock ()
ngx.log(ngx.ERR, "local_demo cost time ========== " .. t2 - t1)
end
local_demo(): local_demo cost time ========== 0.09
local func = function (a, b)
a = a * b + a / b - a + b
return a
end
local local_demo2
local_demo2 = function(tab)
local t1 =os.clock ()
for k, v in ipairs(tab) do
local a = func(1, 2)
end
ngx.update_time()
local t2 =os.clock ()
ngx.log(ngx.ERR, "local_demo2 cost time ========== " .. t2 - t1)
end
local_demo2(): local_demo2 cost time ========== 0.1
local local_demo
local_demo = function()
local t1 =os.clock ()
for i = 1, 100000000 do
local str = "monkey" .. "," .. "monkey" .. "," .. "monkey"
end
ngx.update_time()
local t2 =os.clock ()
ngx.log(ngx.ERR, "local_demo cost time ========== " .. t2 - t1)
end
local_demo(): local_demo cost time ========== 0.03
local local_demo2
local_demo2 = function()
local t1 =os.clock ()
for i = 1, 100000000 do
local str = string.format("%s,%s,%s", "monkey","monkey","monkey")
end
ngx.update_time()
local t2 =os.clock ()
ngx.log(ngx.ERR, "local_demo2 cost time ========== " .. t2 - t1)
end
local_demo2(): local_demo2 cost time ========== 0.05