lua 分享
配置参数 lua_code_cache on
当配置参数lua_code_cache 为 off 的时候, 每次修改lua代码会生效。init_by_lua_block 每次执行请求都会执行。 不能使用lrucache 并且不能缓存。 init_worker_by_lua_block 执行work线程数的次数。
。lua_code_cache 为off 情况下可以用于代码调试,不过会产生很多bug。
当配置参数lua_code_cache 为 ok 的时候, init_by_lua_block 执行一次。能够使用lrucache。init work 阶段一样。
在使用lua_code_cache on 的情况下用于一次性全流程测试。不能说明调通就证明cache on 就正确。 推荐使用方式,段代码微调使用off ,测试使用 on ,线上使用on
配置参数 lua_shared_dict config 100m; 共享字典与lur cache
lua_shared_dict 所有work 进程共享, lru cache 本 work 进程共享。
根据c 的结构体发现 能够存储以下三种类型 boolean 、number 、string。 而 lru cache 能够存储lua的所有类型
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,
};
使用lru cached 需要开启 lua_code_cache on;使用 lua_shared_dict 需要在配置文件中配置。
lua_shared_dict 存储 表接口数据需要 encode 到string , decode 到 table。
set_header() 与 get_headers() 方法
ngx.req.set_header(“Accept-Encoding”, v) 只能设置一个值, v 如果是table 也是取得table中的第一个字赋值给Accept-Encoding
ngx.req.get_headers() 可能是string 也可能是 table ,如果是table 类型相当于多参数, 当使 用set_header 方法table只能修改其中一个。
math.random(1, #list) 方法
math random 随机不离散, 必须借助于随机种子,随机种子只需要种植一次。 这个与java 完全不同。
随机种子在 init 阶段设置就可以 math.randomseed(ngx.time())
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)
nginx http{include 与 default_type} 对 ngx.resp.get_headers() 中 Content-Type 的影响
配置了include 与 default_type 如果后端没有返回Content-Type nginx会根据include和返回的body自动匹配。 如果include没有匹配的则Content-Type为defaul ttype
ngx.resp.get_headers() 取到的是已经匹配了Content-Type的值,所以说后端没有返回Content-Type nginx会设置上并且ngx.resp.get_headers()会取到。
这样说来ngx.resp.get_headers()的执行是在nginx模块http的后面
http {
#文件扩展名与文件类型映射表
include mime.types;
#默认文件类型,默认为text/plain
default_type text/html;
...
say 和 exit 组合使用 问题 : 晶大神的 blog https://segmentfault.com/a/1190000004534300
当传入的status >= 200(200即为ngx.HTTP_OK),ngx.exit() 会中断当前请求,并将传入的状态码(status)返回给nginx。
当传入的status == 0(0即为ngx.OK)则 ngx.exit() 会中断当前执行的phrase(ngx-lua模块处理请求的阶段,如content_by_lua*),进而继续执行下面的phrase。
对于 ngx.exit() 需要进一步注意的是参数status的使用,status可以传入ngx-lua所定义的所有的HTTP状态码常量(如:ngx.HTTP_OK、ngx.HTTP_GONE、ngx.HTTP_INTERNAL_SERVER_ERROR等)和两个ngx-lua模块内核常量(只支持NGX_OK和NGX_ERROR这两个,如果传入其他的如ngx.AGAIN等则进程hang住)。
say 相当于直接执行header filter 和 bodyfilter 等阶段,一直到结束。
一般情况下 先say 然后 在exit 。 当 status >=200 的时候中断请求,然后执行响应阶段, 其他情况中断当前阶段继续执行下一个阶段。
say之后做exit依然会到body阶段,并可根据arg[1]修改返回内容。
只是做exit 状态直接返回。
pairs 和 ipairs
pairs 主要用于map , ipairs 主要用于数组
ipairs 有序, 下标 1开始, 如果遇到没有下标的值就结束。相当于有些值是表结构或者 下标为字符串结构的不能遍历
pairs 用于 map 能遍历出来所有,无序。
ngx.var.upstream_host 自定义变量的使用
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
ngx.header.content_length 巧用
获取请求参数问题 问题
1、 ngx.req 所涉及方法都十分耗时
2、 ngx.req 获取参数如果有相同key返回格式
参数可能存在table类型 eg: url?aa=123&aa=456 --> {aa={123,456}}
返回的数据类型不限于string也会有boolean
ngx.req.get_uri_args
ngx.req.get_post_args 使用前先调用ngx.req.read_body() 或者在配置中加入lua_need_request_body on;
ngx.req.get_headers
对于获取参数这种频繁操作透明代理解决方案, 封装到ngx.ctx.req
各阶段不可使用API
body_filter_by_lua 这个阶段不允许用sql
body_filter_by_lua 这个阶段不允许用say
body_filter_by_lua 也不能用exit
body_filter_by_lua 修改返回的header不会生效
pcall xpcall 问题