OpenResty 是一个基于 Nginx 的可伸缩的 Web 平台,提供了很多高质量的第三方模块;它也是一个强大的 Web 应用服务器,开发人员可以使用 Lua 脚本语言调用 Nginx 支持的各种 C 以及 Lua 模块。
今天介绍下 OpenResty 在 Ubuntu 1804 上的安装。
安装依赖
安装依赖时,执行以下命令:
1
| apt-get install libpcre3-dev libssl-dev perl make build-essential curl
|
需要注意的是,执行上面的命令时,可能会出现以下错误:
1
| E: py3compile:243: Requested versions are not installed
|
这是因为我们安装的 python3 版本与 py3compile 不一致引起的,py3compile 是属于 python3-minimal 的,我们只需要安装对应的 python3-minimal 即可。python3-minimal 的下载地址为:
1
| https://mirrors.edge.kernel.org/ubuntu/pool/main/p/python3-defaults/
|
下载完成后,执行以下命令安装:
1
| sudo dpkg -i python3-minimal_3.6.7-1~18.04_amd64.deb
|
安装 python3-minimal 可能还会出现以下错误:
1
| /var/lib/dpkg/info/python3-minimal.postinst: py3compile: not found
|
这是因为安装过程中,python3-minimal 会寻找 python3.6(根据安装版本不同而不同),我的系统中 /usr/bin 下只有python3,这时候添加一个 python3.6 的软链接即可。
下载及安装
依赖安装完成后,可以到以下地址下载相应版本的 OpenResty :
1
| http://openresty.org/cn/download.html
|
下载完成后,解压缩:
1
| tar -xzvf openresty-1.17.8.2.tar.gz
|
执行配置及安装命令:
1 2 3
| sudo ./configure --prefix=/usr/local/openresty --with-luajit sudo make sudo make install
|
命令执行完成后,在 /usr/local 下会生成一个 openrestry 目录,里面就行 openrestry 的一些源码文件、配置文件和可执行文件。
其它系统的安装步骤可以参考:
1
| http://openresty.org/cn/installation.html
|
简单使用
hello world的例子
我们可以在 /usr/local/openresty 目录下新建一个文件 conf/openrestry.conf 配置文件,文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| worker_processes 1; error_log logs/error.log; events { worker_connections 1024; } http { server { listen 8080; location / { default_type text/html; content_by_lua_block { ngx.say("<p>hello, world</p>") } } } }
|
然后启动 openrestry 服务:
1
| sudo ./nginx -c /usr/local/openresty/conf/openrestry.conf
|
执行命令,请求 openrestry 服务:
1
| curl http://localhost:8080/
|
请求后,会返回下面的信息:
接收请求参数
openresty 中接收客户端请求参数的配置为:
conf/params.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| events { worker_connections 1024; } http { server { listen 8080;
location /test { default_type text/html; content_by_lua ' local params = ngx.req.get_uri_args(); ngx.print(params.name); ngx.print(params.age); '; }
} }
|
在终端请求 http://localhost:8080/test/?name=aaa&age=12 时,返回的内容为:
ngx.req.get_uri_args 的用法如下:
1 2 3
| args, err = ngx.req.get_uri_args(),用于获取客户端请求 uri 中的参数。
它的说明文档为:https://github.com/openresty/lua-nginx-module#ngxreqget_uri_args
|
其中,ngx.print() 函数的功能是将参数作为响应体返回给调用的客户端,未返回响应头时,首先返回响应头,再返回响应体。
还有一个 ngx.say() 方法,它与 ngx.print() 方法的功能一样,但是 ngx.say() 最后会返回一个换行符。
上面的方法 ngx.req.get_uri_args() 是接收 get 请求的参数,接收 post 请求参数的配置为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| events { worker_connections 1024; } http { server { listen 8080;
location /test { default_type text/html; content_by_lua_block { ngx.req.read_body(); local params = ngx.req.get_post_args(); ngx.say(params.name); ngx.say(params.age); } }
} }
|
在终端执行以下命令:
1
| curl http://localhost:8080/test -X POST -d 'name=aaa&age=12'
|
得到的结果为:
接收 post 请求使用的是 ngx.req.get_post_args()。,在使用该方法之前,需要调用方法:ngx.req.read_body()。ngx.req.read_body() 的作用是:在不阻塞 nginx event loop 的请求下,异步读取客户端的请求体数据。
内部调用
在 openresty 中,可以进行内部 location 之间的调用,配置例子如下:
conf/inner.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| events { worker_connections 1024; } http { server { listen 8080;
location /test { default_type text/html; content_by_lua ' local res = ngx.location.capture( "/getname", {args={name=ngx.var["arg_name"], age=18}} ) ngx.say(ngx.var["arg_name"]); ngx.say("status:", res.status, " resp:", res.body) '; }
location /getname { content_by_lua ' local params = ngx.req.get_uri_args(); ngx.print(params.name); '; } } }
|
上面的例子中,当访问 http://localhost:8080/test/?name=xxx 时,会打印出以下内容:
配置文件中,ngx.location.capture 的作用如下:
1 2 3 4 5 6 7
| 功能:在 nginx 内部调用其它 location 块 语法:res = ngx.location.capture(uri, options) 上面的配置文件中,它的作用域是 content_by_lua 开头的模块
ngx.location.capture 会返回一个 lua table 对象,有以下4个属性:res.status, res.header, res.body, and res.truncated
ngx.location.capture 的说明文档为:https://github.com/openresty/lua-nginx-module#ngxlocationcapture
|
指定lua脚本文件
在 openresty 的 location 中,可以指定 lua 脚本来执行,配置例子为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| events { worker_connections 1024; } http { server { listen 8080;
location = /test { default_type text/html; content_by_lua_file /usr/local/openresty/lua_code/test.lua; } } }
|
上面的例子中,使用 content_by_lua_file 来指定请求进来时需要运行的 lua 脚本文件。
test.lua 的内容为:
1
| ngx.say("lua test file");
|
在终端执行 curl http://localhost:8080/test 后,会返回 lua test file。
连接redis
openresty 中通过 lua 连接 redis 的例子如下:redis.lua:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| -- redis use
local resty_redis = require('resty.redis') local redis = resty_redis:new()
redis:settimeout(1000)
local ok, err = redis:connect('127.0.0.1', 6379) if not ok then ngx.say(err) ngx.eof() end
-- 连接 redis 后进行密码验证 local res, err = redis:auth('wyzane') if not res then ngx.say("failed to auth:", err) return end
local res, err = redis:get("name") if not res then ngx.say("failed to get name:", err) return end
ngx.say(res)
local ok, err = redis:set_keepalive(10000, 100) if not ok then ngx.say("failed to set keeplive:", err) return end
|
redis.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| events { worker_connections 1024; } http { server { listen 8080;
location = /test { default_type text/html; content_by_lua_file /home/wyzane/lua_code/redis.lua; } } }
|
连接mysql
openresty 中使用 lua 连接 mysql 的例子如下:mysql.lua:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
local resty_mysql = require("resty.mysql") local cjson = require("cjson")
local db, err = resty_mysql:new()
if not db then ngx.say('init mysql failed', err) return end
db:set_timeout(1000)
local ok, err, errcode, sqlstate = db:connect({ host = "127.0.0.1", post = 3306, database = "test_koa", user = "root", password = "wyzane", })
if not ok then ngx.say("failed to connect mysql:", err) return end
res, err, errcode, sqlstate = db:query("select * from tb_user") if not res then nga.say("query failed:", err) return end
db:set_keepalive(0, 100) ngx.say(cjson.encode(res))
|
mysql.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| events { worker_connections 1024; } http { server { listen 8080;
location = /test { default_type text/html; content_by_lua_file /home/wyzane/lua_code/mysql.lua; } } }
|
Openresty 官网:
1
| http://openresty.org/cn/
|
Openresty的 github 地址为:
1
| https://github.com/openresty
|
Openresty最佳实践:
1
| https://www.kancloud.cn/allanyu/openresty-best-practices/82658
|