×

OpenResty笔记

2021-04-12 19:53:28 Falcon

OpenResty

 

中文官网(起步页):https://openresty.org/cn/getting-started.html

 

安装方式:

http://openresty.org/cn/linux-packages.html#rhel

 

安装后

 

配置文件位于:/usr/local/openresty/nginx/conf, 配置默认当前目录为:/usr/local/openresty/nginx

nginx路径:/usr/local/openresty/nginx/sbin/nginx

 

==============

 

acme.sh为openresty安装证书

acme.sh --installcert -d hk64.my.to --key-file /usr/local/openresty/nginx/conf/ssl/hk64.my.to.key.pem --fullchain-file /usr/local/openresty/nginx/conf/ssl/hk64.my.to.cert.pem --reloadcmd "systemctl force-reload openresty"

 

==============

 

nginx 的参数-p:

 

 

nginx -p 指定安装目录,此时会寻找conf下的nginx.conf作为配置文件 , 也是实际上是 ngx.config.prefix() 输出的路径

 

nginx -p ~/openresty-test

 

目录结构:

 

除了conf/nginx.conf和logs,其余都是自动建立的目录

 

停止命令:

nginx -s stop -p /root/openresty-test

============= 

ngx.location.capture_multi 并行执行

 

利用 ngx.location.capture_multi 函数,直接完成了两个子请求并行执行。

当两个请求没有相互依赖,这种方法可以极大提高查询效率。

https://moonbingbing.gitbooks.io/openresty-best-practices/content/openresty/work_with_location.html

 

 

 

============= 

 

ngx.location.capture 这里有个小技巧,args 参数可以接受字符串或Lua 表

 

 

local res = ngx.location.capture('/print_param',

         {

            method = ngx.HTTP_POST,

            args = {a = 1, b = '2&'}, -- 普通写法是使用函数转义 args = ngx.encode_args({a = 1, b = '2&'}) 或者手写转义,如body的写法

            body = 'c=3&d=4%26'

        }

     )

ngx.say(res.body)

 

============= 

获取请求 uri 参数

官方 API 文档,获取一个 uri 有两个方法:ngx.req.get_uri_args、ngx.req.get_post_args,二者主要的区别是参数来源有区别。

 

server {

   listen    80;

   server_name  localhost;

 

   location /print_param {

       content_by_lua_block {

           local arg = ngx.req.get_uri_args()

           for k,v in pairs(arg) do

               ngx.say("[GET ] key:", k, " v:", v)

           end

 

           ngx.req.read_body() -- 解析 body 参数之前一定要先读取 body

           local arg = ngx.req.get_post_args()

           for k,v in pairs(arg) do

               ngx.say("[POST] key:", k, " v:", v)

           end

       }

   }

}

 

 

 

============= 

nginx默认不读取请求体body

 

需要打开 lua_need_request_body ;

 

..

# 默认读取 body

 

        lua_need_request_body on;

 

        location /test {

            content_by_lua_block {

                local data = ngx.req.get_body_data()

                ngx.say("hello ", data)

            }

        }

...

 

或者如果只需要在特定接口读取时,需要显式调用 ngx.req.read_body() 接口:

 location /test {

            content_by_lua_block {

                ngx.req.read_body()

                local data = ngx.req.get_body_data()

                ngx.say("hello ", data)

            }

        }

 

==============

 

body 偶尔读取不到的解决方法

 

ngx.req.get_body_data() 读请求体,会偶尔出现读取不到直接返回 nil 的情况。

如果请求体尚未被读取,请先调用 ngx.req.read_body (或打开 lua_need_request_body 选项强制本模块读取请求体,此方法不推荐)。

如果请求体已经被存入临时文件,请使用 ngx.req.get_body_file 函数代替。

如需要强制在内存中保存请求体,请设置 client_body_buffer_size 和 client_max_body_size 为同样大小。

 

参考:https://moonbingbing.gitbooks.io/openresty-best-practices/content/openresty/get_req_body.html

 

==============

 

流式响应大文件 (HTTP1.1的chunk特性)

 

location /test {

    content_by_lua_block {

        -- ngx.var.limit_rate = 1024*1024

        local file, err = io.open(ngx.config.prefix() .. "data.db","r")

        if not file then

            ngx.log(ngx.ERR, "open file error:", err)

            ngx.exit(ngx.HTTP_SERVICE_UNAVAILABLE)

        end

 

        local data

        while true do

            data = file:read(1024)

            if nil == data then

                break

            end

            ngx.print(data)

            ngx.flush(true)

        end

        file:close()

    }

}

==============

日志输出

 

定义日志输出的级别

 

error_log  logs/error.log error;    # 日志级别

 

使用ngx.log(ngx.log_level,  内容)如

 

```

local foo = "bar"

ngx.log(ngx.INFO, "foo var is : ",foo)

```

 

print  语句相当于INFO级别的日志

如:print([[I am logger]])

 

日志输出

2021/04/12 19:39:21 [notice] 29805#29805: *37 [lua] content_by_lua(log.conf:12):4: I am logger, client: xxxx, server: , request: "GET /log HTTP/1.1", host:  ...

 

日志级别

 

ngx.STDERR     -- 标准输出

ngx.EMERG      -- 紧急报错

ngx.ALERT      -- 报警

ngx.CRIT       -- 严重,系统故障,触发运维告警系统

ngx.ERR        -- 错误,业务不可恢复性错误

ngx.WARN       -- 告警,业务中可忽略错误

ngx.NOTICE     -- 提醒,业务比较重要信息

ngx.INFO       -- 信息,业务琐碎日志信息,包含不同情况判断等

ngx.DEBUG      -- 调试

 

网络日志库、

 

lua-resty-logger-socket 的目标是替代 Nginx 标准的 ngx_http_log_module 以非阻塞 IO 方式推送 access log 到远程服务器上。对远程服务器的要求是支持 syslog-ng 的日志服务。

==============

 

 

 

本文收录于