2.3、example.conf配置文件
location ~ /lua_dkjson {
default_type 'text/html';
lua_code_cache on;
content_by_lua_file /usr/example/lua/test_dkjson.lua;
}
2.4、访问如http://192.168.1.2/lua_dkjson将得到如下结果
{ "hobby":["film","music","read"], "is_male":false, "name":"zhangsan", "id":1 }
nil
true
film
编码转换
我们在使用一些类库时会发现大部分库仅支持UTF-8编码,因此如果使用其他编码的话就需要进行编码转换的处理;而Linux上最常见的就是iconv,而lua-iconv就是它的一个Lua API的封装。
安装lua-iconv可以通过如下两种方式:
ubuntu下可以使用如下方式
apt-get install luarocks
luarocks install lua-iconv
cp /usr/local/lib/lua/5.1/iconv.so /usr/example/lualib/
源码安装方式,需要有gcc环境
wget https://github.com/do^Cloads/ittner/lua-iconv/lua-iconv-7.tar.gz
tar -xvf lua-iconv-7.tar.gz
cd lua-iconv-7
gcc -O2 -fPIC -I/usr/include/lua5.1 -c luaiconv.c -o luaiconv.o -I/usr/include
gcc -shared -o iconv.so -L/usr/local/lib luaiconv.o -L/usr/lib
cp iconv.so /usr/example/lualib/
1、test_iconv.lua
ngx.say("中文")
此时文件编码必须为UTF-8,即Lua文件编码为什么里边的字符编码就是什么。
2、example.conf配置文件
location ~ /lua_iconv {
default_type 'text/html';
charset gbk;
lua_code_cache on;
content_by_lua_file /usr/example/lua/test_iconv.lua;
}
通过charset告诉浏览器我们的字符编码为gbk。
3、访问 http://192.168.1.2/lua_iconv会发现输出乱码;
此时需要我们将test_iconv.lua中的字符进行转码处理:
local iconv = require("iconv")
local togbk = iconv.new("gbk", "utf-8")
local str, err = togbk:iconv("中文")
ngx.say(str)
通过转码我们得到最终输出的内容编码为gbk, 使用方式iconv.new(目标编码, 源编码)。
有如下可能出现的错误:
nil
没有错误成功。
iconv.ERROR_NO_MEMORY
内存不足。
iconv.ERROR_INVALID
有非法字符。
iconv.ERROR_INCOMPLETE
有不完整字符。
iconv.ERROR_FINALIZED
使用已经销毁的转换器,比如垃圾回收了。
iconv.ERROR_UNKNOWN
未知错误
iconv在转换时遇到非法字符或不能转换的字符就会失败,此时可以使用如下方式忽略转换失败的字符
local togbk_ignore = iconv.new("GBK//IGNORE", "UTF-8")
另外在实际使用中进行UTF-8到GBK转换过程时,会发现有些字符在GBK编码表但是转换不了,此时可以使用更高的编码GB18030来完成转换。
位运算
Lua 5.3之前是没有提供位运算支持的,需要使用第三方库,比如LuaJIT提供了bit库。
1、test_bit.lua
local bit = require("bit")
ngx.say(bit.lshift(1, 2)) lshift进行左移位运算,即得到4。
cache
ngx_lua模块本身提供了全局共享内存ngx.shared.DICT可以实现全局共享,另外可以使用如Redis来实现缓存。另外还一个lua-resty-lrucache实现,其和ngx.shared.DICT不一样的是它是每Worker进程共享,即每个Worker进行会有一份缓存,而且经过实际使用发现其性能不如ngx.shared.DICT。但是其好处就是不需要进行全局配置。
1、创建缓存模块来实现只初始化一次:
vim /usr/example/lualib/mycache.lua
local lrucache = require("resty.lrucache")
--创建缓存实例,并指定最多缓存多少条目
local cache, err = lrucache.new(200)
if not cache then
ngx.log(ngx.ERR, "create cache error : ", err)
end
local function set(key, value, ttlInSeconds)
cache:set(key, value, ttlInSeconds)
end
local function get(key)
return cache:get(key)
end
local _M = {
set = set,
get = get
}
return _M
此处利用了模块的特性实现了每个Worker进行只初始化一次cache实例。
2、test_lrucache.lua
local mycache = require("mycache")
local count = mycache.get("count") or 0
count = count + 1
mycache.set("count", count, 10 * 60 * 60) --10分钟
ngx.say(mycache.get("count"))
可以实现诸如访问量统计,但仅是每Worker进程的。
3、example.conf配置文件
location ~ /lua_lrucache {
default_type 'text/html';
lua_code_cache on;
content_by_lua_file /usr/example/lua/test_lrucache.lua;
}
访问如http://192.168.1.2/lua_lrucache测试。
字符串处理
Lua 5.3之前没有提供字符操作相关的函数,如字符串截取、替换等都是字节为单位操作;在实际使用时尤其包含中文的场景下显然不能满足需求;即使Lua 5.3也仅提供了基本的UTF-8操作。
Lua UTF-8库
https://github.com/starwing/luautf8
LuaRocks安装
#首先确保git安装了
apt-get install git
luarocks install utf8
cp /usr/local/lib/lua/5.1/utf8.so /usr/example/lualib/
源码安装
wget https://github.com/starwing/luautf8/archive/master.zip
unzip master.zip
cd luautf8-master/
gcc -O2 -fPIC -I/usr/include/lua5.1 -c utf8.c -o utf8.o -I/usr/include
gcc -shared -o utf8.so -L/usr/local/lib utf8.o -L/usr/lib
1、test_utf8.lua
local utf8 = require("utf8")
local str = "abc中文"
ngx.say("len : ", utf8.len(str), "
")
ngx.say("sub : ", utf8.sub(str, 1, 4)) 文件编码必须为UTF8,此处我们实现了最常用的字符串长度计算和字符串截取。