Openresty常用指令和参数

Stella981
• 阅读 751
--[[
参考文档: https://www.nginx.com/resources/wiki/modules/lua/#nginx-api-for-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
    解释:
        每个NginxWorker进程启动时调用的计时器,
        如果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
    解释:
        rewrite阶段处理,可以实现复杂的转发/重定向逻辑;


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

ngx.var
-- nginx变量,如果要赋值如ngx.var.b = 2,此变量必须提前声明;
-- 另外对于nginx location中使用正则捕获的捕获组可以使用ngx.var[捕获组数字]获取;

ngx.var.request_uri
-- 这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看$uri更改或重写URI。


ngx.var.scheme -- ngx.var.server_addr
-- HTTP方法(如http,https)。按需使用

ngx.var.server_addruri
-- 服务器地址,在完成一次系统调用后可以确定这个值,如果要绕开系统调用,则必须在listen中指定地址并且使用bind参数。

ngx.var.uri
-- 请求中的当前URI(不带请求参数,参数位于$args),可以不同于浏览器传递的$request_uri的值,它可以通过内部重定向,或者使用index指令进行修改。

ngx.var.server_name
-- 服务器名称

ngx.var.server_port
-- 请求到达服务器的端口号。

ngx.var.remote_addr
-- 获取远程的IP地址

ngx.var.remote_port
-- 获取远程的端口号

ngx.header
-- 输出响应头;

ngx.print
-- 输出响应内容体;

ngx.say
-- 通ngx.print,但是会最后输出一个换行符;

ngx.exit
-- 指定状态码退出。


ngx.redirect
-- 重定向;

ngx.status = 301
-- 设置响应的状态码;

ngx.resp.get_headers()
-- 获取设置的响应状态码;

ngx.send_headers()
-- 发送响应状态码, ,当调用ngx.say/ngx.print时自动发送响应状态码;

ngx.headers_sent = true
-- 判断是否发送了响应状态码。

ngx.req.get_headers
-- 获取请求头,默认只获取前100,如果想要获取所以可以调用ngx.req.get_headers(0);
-- 获取带中划线的请求头时请使用如headers.user_agent这种方式;
-- 如果一个请求头有多个值,则返回的是table;

ngx.req.get_uri_args
-- 获取url请求参数,其用法和get_headers类似;

ngx.req.get_post_args
-- 获取post请求内容体,其用法和get_headers类似,但是必须提前调用ngx.req.read_body()来读取body体
--(也可以选择在nginx配置文件使用lua_need_request_body on;开启读取body体,但是官方不推荐);

ngx.req.raw_header
-- 未解析的请求头字符串;

ngx.req.get_body_data
-- 为解析的请求body体内容字符串。

ngx.req.set_uri(uri, false)
-- 可以内部重写uri(可以带参数),等价于 rewrite ^ /lua_rewrite_3;
-- 通过配合if/else可以实现 rewrite ^ /lua_rewrite_3 break;
-- 这种功能;此处两者都是location内部url重写,不会重新发起新的

ngx.req.set_uri_args
-- 重写请求参数,可以是字符串(a=1&b=2)也可以是table;

ngx.escape_uri
ngx.unescape_uri
-- uri编码解码;

ngx.encode_args
ngx.decode_args
-- 参数编码解码;

ngx.encode_base64
ngx.decode_base64
-- BASE64编码解码;

ngx.re.match
-- nginx正则表达式匹配;

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



-- 指令: init_by_lua
--[[
    nginx.conf配置文件中的http部分添加如下代码,

    #共享全局变量,在所有worker间共享
    lua_shared_dict shared_data 1m;
    init_by_lua_file /usr/example/lua/init.lua;
]]
--init.lua
--初始化耗时的模块
local redis = require 'resty.redis'
local cjson = require 'cjson'

--全局变量,不推荐
count = 1
--共享全局内存
local shared_data = ngx.shared.shared_data
shared_data:set("count", 1)

-- test.lua
count = count + 1
ngx.say("global variable : ", count)
local shared_data = ngx.shared.shared_data
ngx.say(", shared memory : ", shared_data:get("count"))
shared_data:incr("count", 1)
ngx.say("hello world")

-- 访问如http://192.168.1.2/lua 会发现全局变量一直不变,而共享内存一直递增
-- global variable : 2 , shared memory : 8 hello world
-- 另外注意一定在生产环境开启lua_code_cache,否则每个请求都会创建Lua VM实例。



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

    nginx.conf配置文件中的http部分添加如下代码:
    init_worker_by_lua_file /usr/example/lua/init_worker.lua;

    另外根据实际情况设置如下指令
    lua_max_pending_timers 1024;  #最大等待任务数
    lua_max_running_timers 256;   #最大同时运行任务数
]]

-- init_worker.lua
local count = 0
local delayInSeconds = 3
local heartbeatCheck = nil

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)
    end
end

heartbeatCheck()



-- 指令: set_by_lua
--[[
    设置nginx变量,我们用的set指令即使配合if指令也很难实现负责的赋值逻辑;
    语法set_by_lua_file $var lua_file arg1 arg2...;
    在lua代码中可以实现所有复杂的逻辑,但是要执行速度很快,不要阻塞;

    example.conf配置文件:
    location /lua_set_1 {
        default_type "text/html";
        set_by_lua_file $num /usr/example/lua/test_set_1.lua;
        echo $num;
    }
]]
-- test_set_1.lua
local uri_args = ngx.req.get_uri_args()
local i = uri_args["i"] or 0
local j = uri_args["j"] or 0
return i + j
-- 访问如http://192.168.1.2/lua_set_1?i=1&j=10进行测试。 如果我们用纯set指令是无法实现的。
点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这