OpenResty入门之使用Lua扩展Nginx

释放双眼,带上耳机,听听看~!

本文目录

记住一点:nginx配置文件很多坑来源自你的空格少了或多了。

1.Centos下载安装

如果你的系统是 Centos 或 RedHat 可以使用以下命令:

yum install readline-devel pcre-devel openssl-devel

接下我们可以在官方(https://openresty.org/cn/)下载最新的 OpenResty 源码包并解压编译安装:

wget https://openresty.org/download/ngx_openresty-1.9.7.1.tar.gz   # 下载
tar xzvf ngx_openresty-1.9.7.1.tar.gz       # 解压
cd ngx_openresty-1.9.7.1/ 
./configure
make 
make install

默认情况下程序会被安装到 /usr/local/openresty 目录,你可以使用 ./configure --help 查看更多的配置选项。

2.HelloWorld实例

安装成功后,我们就可以使用 openresty 直接输出 html 页面。

首先我们可以创建一个工作目录:

mkdir /home/www
cd /home/www/
mkdir logs/ conf/

其中 logs 目录用于存放日志,conf 用于存放配置文件。

接着,我们在 conf 目录下创建一个 nginx.conf 文件 代码如下:

worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}
http {
    server {
        listen 9000;
        location / {
            default_type text/html;
            content_by_lua \'
                ngx.say(\"<p>Hello, World!</p>\")
            \';
        }
    }
}

如果你熟悉 nginx 的配置,应该对以上代码就很熟悉。这里我们将 html 代码直接写在了配置文件中。

启动 openresty

默认情况下 openresty 安装在 /usr/local/openresty 目录中,启动命令为:

/usr/local/openresty/nginx/sbin/nginx -p /home/www/ -c conf/nginx.conf

如果没有任何输出,说明启动成功,-p 指定我们的项目目录,-c 指定配置文件。

接下来我们可以使用 curl 来测试是否能够正常范围:

curl http://localhost:9000/

输出结果为:

<p>Hello, World!</p>

3.调用Lua脚本文件

在 HelloWorld 实例中,我们直接在 nginx.conf 中写Lua脚本,很多时候,Lua脚本是一个文件。下面演示使用 content_by_lua_file 指令调用Lua脚本文件。

在conf文件夹下创建helloworld.lua:

ngx.say(\"<p>Hello, World!</p>\")

修改你的 nginx.conf 文件内容为:

worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}
http {
    server {
        listen 9000;
        location / {
            default_type text/html;
            content_by_lua_file \'conf/helloworld.lua\';
        }
    }
}

停止已启动的nginx进程:

killall -9 nginx

启动nginx进程:

/usr/local/openresty/nginx/sbin/nginx -p /home/www/ -c conf/nginx.conf

接下来我们可以使用 curl 来测试是否能够正常范围:

curl \'localhost:9000\'

输出结果为:

<p>Hello, World!</p>

4.set_by_lua指令

使用 set_by_lua 指定可以用类似调用函数的形式去调用Lua脚本。语法:

set_by_lua $res <lua-script-str> [$arg1 $arg2 ...]

修改你的conf/nginx.conf文件:

worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}
http {
    server {
        listen 9000;
        location / {
            default_type text/html;
            set_by_lua $res \'
                local a = tonumber(ngx.arg[1])
                local b = tonumber(ngx.arg[2])
                return a+b\' $arg_a $arg_b;
            echo $res;
        }
    }
}

停止已启动的nginx进程,命令:

killall -9 nginx

启动nginx进程:

/usr/local/openresty/nginx/sbin/nginx -p /home/www/ -c conf/nginx.conf

接下来我们可以使用 curl 来测试是否能够正常范围:

curl \'localhost:9000/?a=2&b=5\'

输出结果为:

7

5.set_by_lua_file指令

set_by_lua_file可以调用本地Lua脚本文件。语法与set_by_lua相同:

set_by_lua_file $res <lua-script-str> [$arg1 $arg2 ...]

在conf文件夹下创建hello.lua文件:

local a = tonumber(ngx.arg[1])
local b = tonumber(ngx.arg[2])
return a+b

在conf文件夹下创建nginx_lua.conf文件:

worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}
http {
    server {
        listen 9000;
        location = / {
            default_type text/html;
            set_by_lua_file $res \"conf/hello.lua\" $arg_a $arg_b;
            echo $res;
        }
    }
}

启动nginx进程:

/usr/local/openresty/nginx/sbin/nginx -p /home/www/ -c conf/nginx_lua.conf

接下来我们可以使用 curl 来测试是否能够正常范围:

curl \'localhost:9000/?a=2&b=5\'

输出结果为:

7

6.设置nginx变量

在conf文件夹下创建nginx.conf文件:

worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}
http {
    server {
        listen 9000;
        location / {
            set $a $host;
            set $b \'hello world\';
            default_type text/html;
            content_by_lua_file \'conf/hello.lua\';
        }
    }
}

在conf文件夹下创建hello.lua:

local var = ngx.var
ngx.say(\"ngx.var.a : \", var.a, \"<br/>\")
ngx.say(\"ngx.var.b : \", var.b, \"<br/>\")
ngx.say(\"<br/>\")

启动nginx进程:

/usr/local/openresty/nginx/sbin/nginx -p /home/www/ -c conf/nginx_lua.conf

接下来我们可以使用 curl 来测试是否能够正常范围:

curl \'localhost:9000\'

输出结果为:

ngx.var.a : localhost<br/>
ngx.var.b : hello world<br/>

7.运行周期

现在已经学会了content_by_lua 与 set_by_lua 指令,其它类似的指令还有很多,那么这些指令都是有什么区别呢?主要区别是指令的运行周期不同,如图所示。(图片来源于网络)

OpenResty入门之使用Lua扩展Nginx

8.其它指令

指令 所处处理阶段 使用范围 解释
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阶段处理,比如记录访问量/统计平均响应时间

9.Nginx API

将下面的lua脚本复制到你的content_by_lua_file指定的lua文件中即可。

--请求头
local headers = ngx.req.get_headers()
ngx.say(\"headers begin\", \"<br/>\")
ngx.say(\"Host : \", headers[\"Host\"], \"<br/>\")
ngx.say(\"user-agent : \", headers[\"user-agent\"], \"<br/>\")
ngx.say(\"user-agent : \", headers.user_agent, \"<br/>\")
for k, v in pairs(headers) do
    if type(v) == \"table\" then
        ngx.say(k, \" : \", table.concat(v, \",\"), \"<br/>\")
    else
        ngx.say(k, \" : \", v, \"<br/>\")
    end
end
ngx.say(\"headers end\", \"<br/>\")
ngx.say(\"<br/>\")

--get请求uri参数
ngx.say(\"uri args begin\", \"<br/>\")
local uri_args = ngx.req.get_uri_args()
for k, v in pairs(uri_args) do
    if type(v) == \"table\" then
        ngx.say(k, \" : \", table.concat(v, \", \"), \"<br/>\")
    else
        ngx.say(k, \": \", v, \"<br/>\")
    end
end
ngx.say(\"uri args end\", \"<br/>\")
ngx.say(\"<br/>\")

--post请求参数
ngx.req.read_body()
ngx.say(\"post args begin\", \"<br/>\")
local post_args = ngx.req.get_post_args()
for k, v in pairs(post_args) do
    if type(v) == \"table\" then
        ngx.say(k, \" : \", table.concat(v, \", \"), \"<br/>\")
    else
        ngx.say(k, \": \", v, \"<br/>\")
    end
end
ngx.say(\"post args end\", \"<br/>\")
ngx.say(\"<br/>\")

--请求的http协议版本
ngx.say(\"ngx.req.http_version : \", ngx.req.http_version(), \"<br/>\")
--请求方法
ngx.say(\"ngx.req.get_method : \", ngx.req.get_method(), \"<br/>\")
--原始的请求头内容
ngx.say(\"ngx.req.raw_header : \", ngx.req.raw_header(), \"<br/>\")
--请求的body内容体
ngx.say(\"ngx.req.get_body_data() : \", ngx.req.get_body_data(), \"<br/>\")
ngx.say(\"<br/>\")

local request_uri = ngx.var.request_uri;
ngx.say(\"request_uri : \", request_uri, \"<br/>\");
--解码
ngx.say(\"decode request_uri : \", ngx.unescape_uri(request_uri), \"<br/>\");
--MD5
ngx.say(\"ngx.md5 : \", ngx.md5(\"123\"), \"<br/>\")
--http time
ngx.say(\"ngx.http_time : \", ngx.http_time(ngx.time()), \"<br/>\")

--当前时间
ngx.update_time()
local now = ngx.now()
ngx.say(\"nowTime : \", now, \"<br/>\")

Lua如何调用系统shell呢?

--调用系统命令
local t = io.popen(\'cat /home/www/conf/hello.lua\')
local a = t:read(\"*all\")
t:close()
ngx.say(a)

参考文章:https://blog.csdn.net/qq_21860077/article/details/83623888

Nginx API for Lua:https://www.cnblogs.com/wangxusummer/p/4309007.html

给TA打赏
共{{data.count}}人
人已打赏
随笔日记

大白话5分钟带你走进人工智能-第十七节逻辑回归之交叉熵损失函数(2)

2020-11-9 4:39:51

随笔日记

机器学习中的矩阵向量求导(三) 矩阵向量求导之微分法,机器学习中的矩阵向量求导(二) 矩阵向量求导之定义法

2020-11-9 4:39:53

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索