Lua集成Redis及Nginx
http://www.lua.org/
Lua脚本的作用:嵌入到应用程序中,给应用程序提供扩展功能。
https://www.lua.org/manual/5.4/
运行方法
可以编写xxx.lu脚本,通过lua xxx.lua
运行,或者通过 lua -i
交互式编程
helloworld
[root@q101 lua_script]# vi helloworld.lua
[root@q101 lua_script]# lua helloworld.lua
hello!
运行方法
可以编写xxx.lu脚本,通过
lua xxx.lua
运行,或者通过 lua -i
交互式编程helloworld
[root@q101 lua_script]# vi helloworld.lua
[root@q101 lua_script]# lua helloworld.lua
hello!
注释
单行:两个减号
--
多行注释
--[[
多行注释
多行注释
--]]
变量
全局变量:默认情况下,定义一个变量都是全局变量;
局部变量:局部变量声明时使用local
关键字,例如:
--全局变量
a=1
--局部变量
local b=2
如果变量没有初始化,则默认值为nil
这和Java中的null
不同,例如
[root@q101 ~]# lua -i
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> name="hello"
> local address="beijin"
> print(name)
hello
> print(address)
nil
>
数据类型
Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。 Lua 中有 8 个基本类型分别为:nil
、boolean
、number
、string
、userdata
、function
、thread
和 table
。
数据类型 | 描述 |
---|---|
nil | 只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。 |
boolean | 包含两个值:false和true。nil和false是 false |
number | 表示双精度类型的实浮点数 |
string | 字符串由一对双引号或单引号来表示 |
function | 由 C 或 Lua 编写的函数 |
userdata | 表示任意存储在变量中的C数据结构 |
thread | 表示执行的独立线路,用于执行协同程序 |
table | Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字 符串或表类型。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用 来创建一个空表。 |
lua中可以通过type
函数查看对象类型,例如
> print(type("hello"))
string
> print(type(10.4))
number
> print(type(print))
function
> print(type(type))
function
> print(type(true))
boolean
> print(type(nil))
nil
https://github.com/openresty/redis2-nginx-module
openresty自带redis2-nginx-module,可以直接使用
Nginx配置
location = /foo {
default_type text/html;
redis2_query set k1 'aaa';
# 请求转发Redis
redis2_pass 127.0.0.1:6379;
}
location = /foo {
default_type text/html;
redis2_query set k1 'aaa';
# 请求转发Redis
redis2_pass 127.0.0.1:6379;
}
重启后访问http://192.168.88.101/foo,查看Redis中k1值
get请求
# 访问 ip/get?key=xxx
location = /get {
default_type text/html;
redis2_pass 127.0.0.1:6379;
#redis2_query auth 123123;
set_unescape_uri $key $arg_key; # this requires ngx_set_misc
redis2_query get $key;
}
set请求
location = /set {
default_type text/html;
redis2_pass 127.0.0.1:6379;
#redis2_query auth 123123;
# $arg_xxx未自定义
set_unescape_uri $key $arg_uid; # this requires ngx_set_misc
set_unescape_uri $val $arg_uname; # this requires ngx_set_misc
redis2_query set $key $val;
}
请求http://192.168.88.101/set?uid=11111&uname=zhangsan,查看Redis
操作集群
upstream redis_cluster {
server 192.168.88.101:6379;
server 192.168.88.102:6379;
}
location = /redis {
default_type text/html;
redis2_next_upstream error timeout invalid_response;
redis2_query get foo;
redis2_pass redis_cluster;
}
其他更多方法,参考官方文档。通过redis2-nginx-module需要对Nginx配置进行修改,不适用于复杂场景。通常使用更多的是通过外置lua脚本编写业务逻辑,Nginx conf引用lua,比如lua-resty-redis。
http://192.168.88.101/luaresty
更多使用参考:https://github.com/openresty/lua-resty-redis
redis-cluster支持
参考:https://github.com/steve0511/resty-redis-cluster
http://openresty.org/cn/linux-packages.html
yum install yum-utils
yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
yum install openresty -y
yum install openresty-resty -y
yum install yum-utils
yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
yum install openresty -y
yum install openresty-resty -y
启动\关闭\重启等命令
# 启动
systemctl start openresty
# 查看状态
systemctl status openresty
# 加载配置
systemctl reload openresty
# 关闭
systemctl stop openresty
查看版本openresty -v
[root@q101 utils]# openresty -v
nginx version: openresty/1.19.9.1
测试lua脚本
vi /usr/local/openresty/nginx/conf/nginx.conf
# 在nginx.conf server中写入
location /lua {
default_type text/html;
content_by_lua 'ngx.say("Hello, OpenResty!
")';
}
# 保存后重新加载配置
systemctl reload openresty
浏览器访问http://192.168.88.101/lua
获取请求nginx uri中的变量
nginx配置修改
location /nginx_var {
default_type text/html;
content_by_lua_block {
# arg_a表示获取参数名为a的参数值
ngx.say(ngx.var.arg_a)
}
}
重新加载配置后浏览器访问:http://192.168.88.101/nginx_var?a=123123
https://github.com/ledgetech/lua-resty-http
下载后将lua-resty-http/lib/resty下所有文件上传到/usr/local/openresty/lualib/resty

编写脚本
vi /usr/local/openresty/nginx/script/resty1.lua
内容如下
local http = require("resty.http")
local httpc = http.new()
--http://www.baidu.com/s?wd=test
local resp, err = httpc:request_uri("http://www.baidu.com", {
method = "GET",
path = "/s?wd=test",
headers = {
["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36"
}
})
if not resp then
ngx.say("request error :", err)
return
end
ngx.status = resp.status
for k, v in pairs(resp.headers) do
if k ~= "Transfer-Encoding" and k ~= "Connection" then
ngx.header[k] = v
end
end
ngx.say(resp.body)
httpc:close()
local http = require("resty.http")
local httpc = http.new()
--http://www.baidu.com/s?wd=test
local resp, err = httpc:request_uri("http://www.baidu.com", {
method = "GET",
path = "/s?wd=test",
headers = {
["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36"
}
})
if not resp then
ngx.say("request error :", err)
return
end
ngx.status = resp.status
for k, v in pairs(resp.headers) do
if k ~= "Transfer-Encoding" and k ~= "Connection" then
ngx.header[k] = v
end
end
ngx.say(resp.body)
httpc:close()
配置nginx
resolver 8.8.8.8;
location /resty1 {
default_type text/html;
content_by_lua_file script/resty1.lua;
}
测试
访问:http://192.168.88.101/resty1
http://192.168.88.101/resty2?id=1
访问:http://192.168.88.101/resty2?id=4