4485

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、依赖包:libqrencodelibpng

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图片出现了,则恭喜说明成功了。

附一些openresty资源:

  1. nginx中文文档
  2. agentzh 的 Nginx 教程(版本 2016.07.21)
  3. Nginx+Lua入门
  4. Tengine的Nginx开发从入门到精通
  5. nginx 配置指令的执行顺序
  6. OpenResty 最佳实践

乐果   发表于   2017 年 09 月 13 日 标签:nginxlua

0

文章评论