目录
一、介绍
lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
官网:https://www.lua.org/
二、安装
1、apt安装
apt install lua5.3
2、测试hello world
1)、在linux虚拟机的任意目录下,新建hello.lua文件
cd /tmp
touch hello.lua
2)、添加内容
vim hello.lus
# 添加打印
print("Hello World!")
3)、运行
lua hello.lua
3、命令模式
# 输入lua回车即可
lua
三、lua语法
1、数据类型
可以通过type函数测试给定变量或值的类型:
# lua进入命令模式
root@sony-HP-Notebook:/tmp# lua
Lua 5.3.3 Copyright (C) 1994-2016 Lua.org, PUC-Rio
> print(type('hello'))
string
> print(type(true))
boolean
> print(type(11))
number
> print(print)
function
2、变量
Lua申明变量的时候,并不需要指定数据类型
访问table:
-- 访问数组,lua数组的角标从1开始
print(arr[1])
-- 访问table
print(map['name'])
print(map.name)
3、拼接字符串…
lua
> local str1 = 'hello' .. 'world' print(str1)
helloworld
4、循环
- 遍历数组
-- 申明数组 key为索引的table
local arr = {'java', 'python', 'lua'}
-- 遍历数组
for index,value in ipairs(arr) do
print(index, value)
end
- 遍历table
-- 申明map,也就是table
local map = {name='java', age=21}
-- 遍历table
for key,value in pairs(map) do
print(key, value)
end
5、函数
定义函数的语法:
function function_name( argument1, argument2, argument3..., argumentn)
-- 函数体
return 返回值
end
例如,定义一个函数,用来打印数组
function printArr( arr)
for index,value in ipairs(arr) do
print(index, value)
end
end
print('调用函数')
local arr2 = {100, 200, 300}
printArr(arr2)
6、条件控制
类似java的条件控制,例如if、else语法
if(布尔表达式)
then
-- [true时执行]
else
-- [false时执行]
end
与java不同,布尔表达式中的逻辑运算是基于英文单词
案例
local function printArr( arr)
-- 判断arr是否为空
if (not arr) then
print('数组不能为空!');
return nil
end
for index,value in ipairs(arr) do
print(index, value)
end
end
print('调用函数')
local arr2 = {100, 200, 300}
printArr(arr2)
printArr(nil)
四、库模块
1、cjson
介绍
OpenResty中的cjson库可以完成JSON数据的序列化和反序列化等工作。
cjson有两个模块:cjson和cjson.safe,前者在解析失败后会抛出异常,而后者则返回nil。
文档地址:https://github.com/openresty/lua-cjson
引入
# 解析失败不会抛异常
local cjson = require "cjson.safe"
# 解析失败会抛异常
local cjson = require "cjson"
序列化
local obj = {
code = 0,
msg = "请求成功"
}
local json = cjson.encode(obj)
反序列化
local json = '{{"id":10001,"name":"SALSA AIR"}'
-- 反序列化
local obj = cjson.decode(json)
cjson.decode([[{"code":0,"msg":"请求成功"}]])
2、Redis模块
openResty提供了操作Redis的模块,我们只需要引入该模块就能直接使用:
引入
-- 引入redis模块
local redis = require('resty.redis')
-- 初始化Redis对象
local red = redis:new()
-- 设置redis超时时间
red:set_timeout(1000, 1000, 1000)
封装连接池函数
用来释放Redis连接,其实是释放连接池
-- 关闭redis连接的工具方法,其实是放入连接池
local function close_redis(red)
local pool_max_idle_time = 10000 -- 连接的空闲时间,单位是毫秒
local pool_size = 100 --连接池大小
local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
if not ok then
ngx.log(ngx.ERR, "放入redis连接池失败: ", err)
end
end
封装获取数据的函数
-- 查询redis的方法 ip和port是redis地址,key是查询的key
local function read_redis(ip, port, key)
-- 获取一个连接
local ok, err = red:connect(ip, port)
if not ok then
ngx.log(ngx.ERR, "连接redis失败 : ", err)
return nil
end
-- 查询redis
local resp, err = red:get(key)
-- 查询失败处理
if not resp then
ngx.log(ngx.ERR, "查询Redis失败: ", err, ", key = " , key)
end
--得到的数据为空处理
if resp == ngx.null then
resp = nil
ngx.log(ngx.ERR, "查询Redis数据为空, key = ", key)
end
close_redis(red)
return resp
end
封装需要密码和db索引的函数
– 密码和选择的库
red:auth(password)
red:select(db_index)
local function read_redis(ip, port, password, db_index, key)
-- 获取一个连接
local ok, err = red:connect(ip, port)
if not ok then
ngx.log(ngx.ERR, "连接redis失败 : ", err)
return nil
end
-- 密码和选择的库
red:auth(password)
red:select(db_index)
-- 查询redis
local resp, err = red:get(key)
-- 查询失败处理
if not resp then
ngx.log(ngx.ERR, "查询Redis失败: ", err, ", key = " , key)
end
--得到的数据为空处理
if resp == ngx.null then
resp = nil
ngx.log(ngx.ERR, "查询Redis数据为空, key = ", key)
end
close_redis(red)
return resp
end
五、nginx高级使用
获取请求参数
-- 获取路径参数
local id = ngx.var[1]
封装http查询函数
我们可以把http查询的请求封装成一个函数,放到OpenResty函数中,方便后期使用
在/usr/local/openresty/lualib目录下创建common.lua文件
vi //usr/local/openresty/lualib/common.lua
在common.lua中封装http查询的函数
-- 封装函数,发送http请求,并解析响应
local function read_http(path, params)
local resp = ngx.location.capture(path,{
method = ngx.HTTP_GET,
args = params,
})
if not resp then
-- 记录错误信息,返回404
ngx.log(ngx.ERR, "http not found, path: ", path , ", args: ", args)
ngx.exit(404)
end
return resp.body
end
-- 将方法导出
local _M = {
read_http = read_http
}
return _M
nginx本地缓存
OpenResty为Nginx提供了shard dict的功能,可以在nginx的多个worker之间共享数据,实现缓存功能。
nginx开启共享字典,在nginx.conf的http下添加配置
# 共享字典,也就是本地缓存,名称叫做:item_cache,大小150m
lua_shared_dict item_cache 150m;
lua操作共享字典
-- 获取本地缓存对象
local item_cache = ngx.shared.item_cache
-- 存储,指定key、value、过期时间,单位s,默认为0代表永不过期
item_cache:set('key', 'value', 1000)
-- 读取
local val = item_cache:get('key')