记住一点: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 指令,其它类似的指令还有很多,那么这些指令都是有什么区别呢?主要区别是指令的运行周期不同,如图所示。(图片来源于网络)

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/>")

访问 http://127.0.0.1:9000/?a=8&b=55 ,手动输入两个Cookie,输出结果:

headers begin
Host : 127.0.0.1:9000
user-agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
user-agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
accept-language : zh-CN,zh;q=0.9
connection : keep-alive
accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
cache-control : max-age=0
host : 127.0.0.1:9000
cookie : hello=world; Heelo=Sdd
accept-encoding : gzip, deflate
upgrade-insecure-requests : 1
user-agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
headers end

uri args begin
b: 55
a: 8
uri args end

post args begin
post args end

ngx.req.http_version : 1.1
ngx.req.get_method : GET
ngx.req.raw_header : GET /?a=8&b=55 HTTP/1.1 Host: 127.0.0.1:9000 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: hello=world; Heelo=Sdd
ngx.req.get_body_data() : nil

request_uri : /?a=8&b=55
decode request_uri : /?a=8&b=55
ngx.md5 : 202cb962ac59075b964b07152d234b70
ngx.http_time : Mon, 29 Apr 2019 14:53:17 GMT

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

OpenResty入门之使用Lua扩展Nginx的更多相关文章

  1. OpenResty入门之使用Lua开发Nginx插件

    记住一点:nginx配置文件很多坑来源自你的空格少了或多了. OpenResty OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第 ...

  2. OpenResty:通过 Lua 扩展 NGINX 实现的可伸缩的 Web 平台

    关于 http://openresty.org/cn/about.html 这个开源 Web 平台主要由章亦春(agentzh)维护.在 2011 年之前曾由淘宝网赞助,在后来的 2012 ~ 201 ...

  3. 通过 Lua 扩展 NGINX 实现的可伸缩的 Web 平台OpenResty®

    OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方便地搭建能够处理超高并发.扩展性极高的动态 W ...

  4. 通过lua扩展nginx

    1. 安装 准备主要的三个安装包,分别是 nginx-1.15.9.tar.gz LuaJIT-2.0.5.tar.gz lua-nginx-module-0.10.14.tar.gz 相关版本可以去 ...

  5. 用lua扩展你的Nginx(整理)-----openresty

    用lua扩展你的Nginx(整理) 首先得声明.这不是我的原创,是在网上搜索到的一篇文章,原著是谁也搞不清楚了.按风格应该是属于章亦春的文章. 整理花了不少时间,所以就暂写成原创吧. 一. 概述 Ng ...

  6. 给lnmp一键包中的nginx安装openresty的lua扩展

    lnmp一键包(https://lnmp.org)本人在使用之后发现确实好用,能帮助我们快速搭建起lnmp.lamp和lnmpa的web生产环境,因此推荐大家可以多试试.但有的朋友可能需要使用open ...

  7. 用lua扩展你的Nginx(整理)

    首先得声明.这不是我的原创,是在网上搜索到的一篇文章,原著是谁也搞不清楚了.按风格应该是属于章亦春的文章. 整理花了不少时间,所以就暂写成原创吧. 一. 概述 Nginx是一个高性能.支持高并发的,轻 ...

  8. OpenResty 最佳实践 lua与nginx的结合 --引用自https://moonbingbing.gitbooks.io/openresty-best-practices/content/

    系统的说明了lua在nginx上的开发 请大家到源址查看 OpenResty最佳实践

  9. Lua在Nginx的应用

    当 Nginx 标准模块和配置不能灵活地适应系统要求时,就可以考虑使用 Lua 扩展和定制 Nginx 服务.OpenResty集成了大量精良的 Lua 库.第三方模块,可以方便地搭建能够处理超高并发 ...

随机推荐

  1. 快速开发跨平台应用之Xamarin技术

    Xamarin 介绍 Xamarin 是一个允许开发人员有效创建可跨 iOS.Android.Windows 应用程序的开发工具集.Xamarin是免费且开源的,遵循 MIT (麻省理工学院许可证)协 ...

  2. springboot 学习之路 6(定时任务)

    目录:[持续更新.....] spring 部分常用注解 spring boot 学习之路1(简单入门) spring boot 学习之路2(注解介绍) spring boot 学习之路3( 集成my ...

  3. (其他)Thinkpad笔记本装系统

    电脑城装一次系统收你40元,不如自己装系统. 虽然百度上装系统的文章泛滥,但是还是自己尝试. 前3个小时thinkpad e570是不是坏掉了,怎么就进不去BIOS,这个时候直接搜索这个型号,问题输入 ...

  4. MySQL 约束、表连接、表关联、索引

    一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为空,用来保证数据完整性. 外键:是另一表的唯一性 ...

  5. Orchard详解--第一篇 介绍

    Orchard是一个开源的内容管理系统(CMS),它提供了简单的向导式的安装方法,用于快速建站(如WordPress).对于.Net的开发者来说,Orchard有更好的学习价值,所以本系列文章将对Or ...

  6. 使用Visual Studio Team Services敏捷规划和项目组合管理(二)——VSTS中的工作项

    使用Visual Studio Team Services敏捷规划和项目组合管理(二)--VSTS中的工作项 1.通过project/team下拉菜单选择MyHealthClinic\Web,导航到W ...

  7. Java中数组定义的三种方式

    方法一: 1.先声明 2.分配空间 3.赋值 public class arr{ public static void main(String[] args){ int[] arr; //先声明 ar ...

  8. 转: OVER() 系列函数介绍

    OVER(PARTITION BY)函数介绍 开窗函数               Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返 ...

  9. LeetCode算法题-Single Number(Java实现)

    这是悦乐书的第175次更新,第177篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第34题(顺位题号是136).给定一个非空的整数数组,除了一个元素外,每个元素都会出现两 ...

  10. 【DB2基础】DB2编目和数据库连接

    1.编目节点和编目数据库 编目(Catalog),是在本地或远程建立客户端到服务器的数据库连接的过程.其目的在于获取编目信息,即生成用来访问数据库的目录. 系统数据库目录包含一个列表和指针,通过目录可 ...