nginx+lua+openresty动态二维码生成方案
乐果 发表于 2017 年 09 月 13 日 标签:nginxlua
最近,公司系统与阿里体育对接,在门票业务上我们需要返回二维码图片给对方(可能线下过闸机识别的需要),有几个方案可以选择,公司后端技术栈都集中在php,但用php动态生成效率不高,于是考虑用golang,网上也有一些类库包:github.com/skip2/go-qrcode,但后来发现有人用nginx扩展即实现了,所以我决定也尝试下,顺便熟悉下lua、openresty。
一、安装nginx_lua_module以及echo-nginx-module
Ngx_lua手动编译进Nginx。
首先,我的 Nginx 安装路径为:/usr/local/nginx。
我将尝试编译的两个模块:echo,lua。
所需要的模块如下:
luajit http://luajit.org
lua http://www.lua.org
ngx_devel_kit https://github.com/simpl/ngx_devel_kit
echo-nginx-module https://github.com/agentzh/echo-nginx-module
lua-nginx-module https://github.com/chaoslawful/lua-nginx-module
前期准备工作:
1、安装nginx,版本必须大于1.6,如果已经安装了nginx,则需要重新编译安装下,把conf备份下。
2、安装lua,按官网默认路径安装,注意lua最好安装5.2以下版本,不然版本太新会出现各种兼容问题。我本次lua版本为:5.1。
wget https://www.lua.org/ftp/lua-5.1.5.tar.gz .
tar -xzvf lua-5.1.5.tar.gz
cd lua-5.1.5
make linux
#以下报错。。。
gcc -O2 -Wall -DLUA_USE_LINUX -c -o lua.o lua.c
gcc -o lua lua.o liblua.a -lm -Wl,-E -ldl -lreadline -lhistory -lncurses
/usr/bin/ld: cannot find -lncurses
collect2: error: ld returned 1 exit status
make[2]: *** [lua] Error 1
make[2]: Leaving directory `/data/soft/lua-5.1.5/src'
make[1]: *** [linux] Error 2
make[1]: Leaving directory `/data/soft/lua-5.1.5/src'
make: *** [linux] Error 2
原因是没有安装libncurses5-dev,ubuntu安装:
apt-get install libncurses5-dev
#继续
make linux
cd src && make linux
make[1]: Entering directory `/data/soft/lua-5.1.5/src'
make all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses"
make[2]: Entering directory `/data/soft/lua-5.1.5/src'
gcc -o lua lua.o liblua.a -lm -Wl,-E -ldl -lreadline -lhistory -lncurses
gcc -O2 -Wall -DLUA_USE_LINUX -c -o luac.o luac.c
gcc -O2 -Wall -DLUA_USE_LINUX -c -o print.o print.c
gcc -o luac luac.o print.o liblua.a -lm -Wl,-E -ldl -lreadline -lhistory -lncurses
make[2]: Leaving directory `/data/soft/lua-5.1.5/src'
make[1]: Leaving directory `/data/soft/lua-5.1.5/src'
...
make install
cd src && mkdir -p /usr/local/bin /usr/local/include /usr/local/lib /usr/local/man/man1 /usr/local/share/lua/5.1 /usr/local/lib/lua/5.1
cd src && install -p -m 0755 lua luac /usr/local/bin
cd src && install -p -m 0644 lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp /usr/local/include
cd src && install -p -m 0644 liblua.a /usr/local/lib
cd doc && install -p -m 0644 lua.1 luac.1 /usr/local/man/man1
3、安装luajit版本luajit-2.1:
wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz .
tar -xzvf LuaJIT-2.0.5.tar.gz
...
make
...
...
make install
==== Installing LuaJIT 2.0.5 to /usr/local ====
mkdir -p /usr/local/bin /usr/local/lib /usr/local/include/luajit-2.0 /usr/local/share/man/man1 /usr/local/lib/pkgconfig /usr/local/share/luajit-2.0.5/jit /usr/local/share/lua/5.1 /usr/local/lib/lua/5.1
cd src && install -m 0755 luajit /usr/local/bin/luajit-2.0.5
cd src && test -f libluajit.a && install -m 0644 libluajit.a /usr/local/lib/libluajit-5.1.a || :
rm -f /usr/local/bin/luajit /usr/local/lib/libluajit-5.1.so.2.0.5 /usr/local/lib/libluajit-5.1.so /usr/local/lib/libluajit-5.1.so.2
cd src && test -f libluajit.so && \
install -m 0755 libluajit.so /usr/local/lib/libluajit-5.1.so.2.0.5 && \
ldconfig -n /usr/local/lib && \
ln -sf libluajit-5.1.so.2.0.5 /usr/local/lib/libluajit-5.1.so && \
ln -sf libluajit-5.1.so.2.0.5 /usr/local/lib/libluajit-5.1.so.2 || :
cd etc && install -m 0644 luajit.1 /usr/local/share/man/man1
cd etc && sed -e "s|^prefix=.*|prefix=/usr/local|" -e "s|^multilib=.*|multilib=lib|" luajit.pc > luajit.pc.tmp && \
install -m 0644 luajit.pc.tmp /usr/local/lib/pkgconfig/luajit.pc && \
rm -f luajit.pc.tmp
cd src && install -m 0644 lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h /usr/local/include/luajit-2.0
cd src/jit && install -m 0644 bc.lua v.lua dump.lua dis_x86.lua dis_x64.lua dis_arm.lua dis_ppc.lua dis_mips.lua dis_mipsel.lua bcsave.lua vmdef.lua /usr/local/share/luajit-2.0.5/jit
ln -sf luajit-2.0.5 /usr/local/bin/luajit
==== Successfully installed LuaJIT 2.0.5 to /usr/local ====
4、ngx_devel_kit、echo-nginx-module、lua-nginx-module分别git clone 到本地目录,假如我们都下载到 /usr/local/src 目录下面(目录将在nginx编译参数中需要指定)。
5、设置环境变量:
-- luajit --
# tell nginx's build system where to find LuaJIT:
# export LUAJIT_LIB=/path/to/luajit/lib
# export LUAJIT_INC=/path/to/luajit/include/luajit-2.0.2
# 例如,我本机为:
export LUAJIT_LIB=/usr/local/lib
export LUAJIT_INC=/usr/local/include/luajit-2.1
-- lua --
# or tell where to find Lua if using Lua instead:
# export LUA_LIB=/path/to/lua/lib
# export LUA_INC=/path/to/lua/include
export LUA_LIB=/usr/local/lib/lua
export LUA_INC=/usr/local/include
nginx重新编译: 我本机安装的是tengin,不过没关系,编译一样的
./configure --prefix=/data/service/tengin \
--sbin-path=/data/service/tengin/sbin \
--conf-path=/data/service/tengin/conf/nginx.conf \
--pid-path=/data/service/tengin/logs/nginx.pid \
--lock-path=/data/service/tengin/lock/nginx.lock \
--error-log-path=/data/service/tengin/logs/error.log \
--http-log-path=/data/service/tengin/logs/access.log \
--http-scgi-temp-path=/data/service/tengin/scgi \
--http-uwsgi-temp-path=/data/service/tengin/uwsgi \
--http-proxy-temp-path=/data/service/tengin/proxy \
--http-fastcgi-temp-path=/data/service/tengin/fastcig \
--http-client-body-temp-path=/data/service/tengin/body \
--user=www-data \
--group=www-data \
--with-ipv6 \
--with-debug \
--with-file-aio \
--with-rtsig_module \
--with-http_ssl_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_xslt_module \
--with-http_geoip_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_gzip_static_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-http_stub_status_module \
--with-http_random_index_module \
--with-http_image_filter_module \
/**注意下面四行**/
--with-ld-opt="-Wl,-rpath,$LUAJIT_LIB" \
--add-module=/usr/local/src/ngx_devel_kit \
--add-module=/usr/local/src/echo-nginx-module \
--add-module=/usr/local/src/lua-nginx-module
/**注意make先后顺序**/
make -j2
make install
二、添加nginx扩展配置
1、依赖包:libqrencode, libpng
ubuntu:
sudo apt-get install libqrencode-dev libpng12-dev
centos:
yum install libpng-devel
wget http://ftp.riken.jp/Linux/centos/7/os/x86_64/Packages/qrencode-devel-3.4.1-3.el7.x86_64.rpm
rpm -ivh qrencode-devel-3.4.1-3.el7.x86_64.rpm
MacOS:
brew install libqrencode
2、安装lua扩展
git clone https://github.com/vincascm/qrencode.git
cd qrencode
#可以查看Makefile,需要luarocks
#
make
#make正常完成之后,目录下会生成动态库qrencode.so文件
cp qrencode.so /usr/local/openresty/lualib/
#测试qrencode.so是否可以正常运行,如下命令,如果命令行窗口能看到二维码图形则ok了
lua ./test/test.lua
3、nginx站点配置
server {
listen 8080;
server_name img.papa.com.cn;
location / {
default_type image/png;
content_by_lua_block {
local qr = require("qrencode")
local args = ngx.req.get_uri_args()
local text = args.text
if text == nil or text== "" then
ngx.say('need a text param')
ngx.exit(404)
end
ngx.say(qr {
text=text,
level="L",
kanji=false,
ansi=false,
size=4,
margin=2,
symversion=0,
dpi=78,
casesensitive=true,
foreground="000000",
background="FFFFFF"
})
}
add_header Expires "Fri, 01 Jan 1980 00:00:00 GMT";
add_header Pragma "no-cache";
add_header Cache-Control "no-cache, max-age=0, must-revalidate";
#add_header Content-Type image/png;
}
}
访问测试下,http://img.papa.com.cn/qrcode?text=baidu.com 如果二维码png图片出现了,则恭喜说明成功了。