andyyuduo 发表于 2017-12-21 11:52:49

【重要】Nginx模块Lua-Nginx

源码地址:https://github.com/Tinywan/Lua-Nginx-Redis

一、 目标
  使用Redis做分布式缓存;使用lua API来访问redis缓存;使用nginx向客户端提供服务,ngx_lua将lua嵌入到nginx,让nginx执行lua脚本,高并发,非阻塞的处理各种请求。url请求nginx服务器,然后lua查询redis,返回json数据。

二、准备工作
  系统环境:Ubuntu 14.0 (64位)
  Redis服务安装:apt-get install redis-server
  安装Git:apt-get install git
  安装Lua:
  

# apt-get install lua5.1  
# apt-get install liblua5.1-dev
  

# apt-get install liblua5.1-socket2  

# apt-get install -y lua5.1 liblua5.1-0 liblua5.1-0-dev  

  补充:安装模块:stream-lua-nginx-module 出现的错误信息:
  

make: *** Error 1  

  解决办法:
  

apt-get install lua-socket  


三、下载库
  1、当前目录:/home/www 目录下面
  2、下载ngx_devel_kit (NDK(nginx development kit)模块,是一个拓展nginx服务器核心功能的模块,第三方模块开发可以基于它来快速实现。
  

wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz  
tar -zxvf v0.3.0.tar.gz
  

  3、lua-nginx-module 下载。可在 Nginx 中嵌入 Lua 语言,让 Nginx 可以支持 Lua 强大的语法。
  

wget https://github.com/openresty/lua-nginx-module/archive/v0.10.7.tar.gz  
tar -zxvf v0.10.7.tar.gz
  

  4、redis2-nginx-module 下载。是一个支持 Redis 2.0 协议的 Nginx upstream 模块,它可以让 Nginx 以非阻塞方式直接防问远方的 Redis 服务,同时支持 TCP 协议和 Unix Domain Socket 模式,并且可以启用强大的 Redis 连接池功能。
  

wget https://github.com/openresty/redis2-nginx-module/archive/v0.13.tar.gz  
tar -zxvf v0.13.tar.gz
  

  5、set-misc-nginx-module 下载。是标准的HttpRewriteModule指令的扩展,提供更多的功能,如URI转义与非转义、JSON引述,Hexadecimal、MD5、SHA1、Base32、Base64编码与解码、随机数等等
  

wget https://github.com/openresty/set-misc-nginx-module/archive/v0.31.tar.gz  
tar -zxvf v0.31.tar.gz
  

  6、echo-nginx-module 下载,是一个 Nginx 模块,提供直接在 Nginx 配置使用包括 "echo", "sleep", "time" 等指令。
  

wget https://github.com/openresty/echo-nginx-module/archive/v0.60.tar.gz  
tar -zxvf v0.60.tar.gz
  

  7、Nginx 下载
  

wget http://nginx.org/download/nginx-1.10.3.tar.gz  
tar -zxvf nginx-1.10.3.tar.gz
  


四、安装
  1、查看所有下载完的包
  

root@iZ236j3sofdZ:/home/www# ls  
echo-nginx-module-0.60lua-nginx-module-0.10.7nginx-1.10.3nginx-1.10.3.tar.gz
  ngx_devel_kit-0.3.0redis2-nginx-module-0.13redis-lua-2.0.4set-misc-nginx-module-0.31
  

  2、Nginx 配置文件检测
  

cd nginx-1.10.3/  ./configure --prefix=/usr/local/nginx --with-debug --with-http_addition_module \
  --with-http_perl_module --with-http_realip_module --with-http_secure_link_module \
  --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module \
  --with-=/usr/include/openssl --with-=/usr/include/openssl \
  --add-module=../ngx_devel_kit-0.3.0 \
  --add-module=../echo-nginx-module-0.60 \
  --add-module=../lua-nginx-module-0.10.7 \
  --add-module=../redis2-nginx-module-0.13 \
  --add-module=../set-misc-nginx-module-0.31
  

  【错误信息1】:
  

./configure: error: ngx_http_lua_module requires the Lua library  

  解决办法:
  

apt-get install lua5.1-0-dev  

  【错误信息3】:
  

./configure: error: the HTTP rewrite module requires the PCRE library.  

  解决办法:
  

apt-get install libreadline-dev libncurses5-dev libpcre3-dev \  
libssl-dev perl make build-essential curl
  

  【错误信息2】:
  

/usr/bin/ld: cannot find -lperl  
collect2
: error: ld returned 1 exit status  

  说明:/usr/bin/ld: cannot find -lxxx意思是编译过程找不到对应库文件。其中,-lxxx表示链接库文件 libxxx.so。了解更多cannot find -lxxx
  解决办法:
  

apt-get install lperl-dev  


五、编译
  

make  
make install
  

  编译过程出现这个问题:
  

make: Leaving directory `/home/www/nginx-1.10.3' 什么意思  

  解决办法:
  

到你的源码目录内,先make clean然后./config ...  

  3、安装lua-redis-parser,lua-resty-redis是openresty(1.9.15.1)的一个组件,简单来说,它提供一个lua语言版的redis API,使用socket(lua sock)和redis通信。
  

//下载源码包:  
git
clone https://github.com/openresty/lua-resty-redis.git  

  移动该源码包到/usr/local/nginx/lua/ 这里去
  

mv lua-resty-redis /usr/local/nginx/lua/  

  4、使用Redis的提示错误
  

    7094#0: *1 lua entry thread aborted: runtime error: /usr/local/nginx/conf/lua/test_redis_basic.lua:11: module 'resty.redis' not found:  no field package.preload['resty.redis']
  no file '/home/www/lua-redis-parser-0.12/resty/redis.lua'
  no file './resty/redis.lua'
  no file '/usr/local/share/lua/5.1/resty/redis.lua'
  no file '/usr/local/share/lua/5.1/resty/redis/init.lua'
  no file '/usr/local/lib/lua/5.1/resty/redis.lua'
  no file '/usr/local/lib/lua/5.1/resty/redis/init.lua'
  no file '/usr/share/lua/5.1/resty/redis.lua'
  no file '/usr/share/lua/5.1/resty/redis/init.lua'
  no file './resty/redis.so'
  no file '/usr/local/lib/lua/5.1/resty/redis.so'
  no file '/usr/lib/x86_64-linux-gnu/lua/5.1/resty/redis.so'
  no file '/usr/lib/lua/5.1/resty/redis.so'
  no file '/usr/local/lib/lua/5.1/loadall.so'
  no file './resty.so'
  no file '/usr/local/lib/lua/5.1/resty.so'
  no file '/usr/lib/x86_64-linux-gnu/lua/5.1/resty.so'
  no file '/usr/lib/lua/5.1/resty.so'
  no file '/usr/local/lib/lua/5.1/loadall.so'
  
stack traceback:
  

  提示以上错误的原因是Lua的库文件没有加载合适导致的。只需要下载官方的源码包,按照以下应用即可
  

lua_package_path "/usr/local/nginx/lua/lua-resty-redis/lib/?.lua;;";  


六、测试
  1、配置nginx.conf(以下是部分代码)
  

# nginx.conf  
http {
  
  
.....  lua_package_path
"/usr/local/nginx/lua/lua-resty-redis/lib/?.lua;;";#gzipon;  
    server {
  listen      
80;  server_namelocalhost;
  location
/ {  root   html;
  indexindex
.html index.htm;  }
  location
/lua {echo "Hello Lua";  }
  location
/lua_test {  content_by_lua
'  ngx.say("Hello Lua! Tinywan")
';  }
#content_by_lua_block  location =/content_by_lua_block {
  default_type 'text/plain';
  content_by_lua_block {
  ngx.say('Hello : content_by_lua_block')
  }
  }
  location /{
  default_type 'text/html';
  lua_code_cache off;
  content_by_lua_file /usr/local/nginx/conf/lua/test_redis_basic.lua;
  }
  }
  
}
  

  test_redis_basic.lua 添加以下内容:
  

local function close_redis(redis_instance)if not redis_instance then  return
  end
  local ok,err = redis_instance:close();
if not ok then  ngx.say(
"close redis error : ",err);end  
end
  

  
local redis = require("resty.redis");
  
--local redis = require "redis"
  
-- 创建一个redis对象实例。在失败,返回nil和描述错误的字符串的情况下
  
local redis_instance = redis:new();
  
--设置后续操作的超时(以毫秒为单位)保护,包括connect方法
  
redis_instance:set_timeout(1000)
  
--建立连接
  
local ip = '127.0.0.1'
  
local port = 6379
  
--尝试连接到redis服务器正在侦听的远程主机和端口
  
local ok,err = redis_instance:connect(ip,port)
  
if not ok then
  ngx.say("connect redis error : ",err)
  return close_redis(redis_instance);
  
end
  

  
--Redis身份验证
  
--local auth,err = redis_instance:auth("");
  
--if not auth then
  
--    ngx.say("failed to authenticate : ",err)
  
--end
  

  
--调用API进行处理
  
local resp,err = redis_instance:set("msg","hello world")
  
if not resp then
  ngx.say("set msg error : ",err)
  return close_redis(redis_instance)
  
end
  

  
--调用API获取数据
  
local resp, err = redis_instance:get("msg")
  
if not resp then
  ngx.say("get msg error : ", err)
  return close_redis(redis_instance)
  
end
  

  
--得到的数据为空处理
  
if resp == ngx.null then
  resp = 'this is not redis_data'--比如默认值
  
end
  
ngx.say("msg : ", resp)
  
close_redis(redis_instance)
  

  我们通过curl 在shell脚本中测试以上配置文件
  重启Nginx服务器:
  

root@iZ236j3sofdZ:/usr/local/nginx/conf# service nginx restart* Stopping Nginx Server...* Starting Nginx Server...  nginx: lua_code_cache is off; this will hurt performance in /usr/local/nginx/conf/nginx.conf:69
  

  警告:这个alert是因为objstore.conf中把lua_code_cache为off;若设置为off,nginx不缓存lua脚本,每次改变lua代码,不必reload nginx即可生效;这便于开发和测试。但禁用缓存对性能有影响,故正式环境下一定记得设置为on;
  location /lua
  

root@iZ236j3sofdZ:/usr/local/nginx/lua# curl "http://localhost/lua"  
Hello Lua
  

  location /lua_test
  

root@iZ236j3sofdZ:/usr/local/nginx/lua# curl "http://localhost/lua_test"  
Hello Lua! Tinywan
  

  location /content_by_lua_block
  

root@iZ236j3sofdZ:/usr/local/nginx/lua# curl "http://localhost/content_by_lua_block"  
Hello : content_by_lua_block
  

  location /lua_redis_basic
  

root@iZ236j3sofdZ:/usr/local/nginx/lua# curl "http://localhost/lua_redis_basic"  
msg : hello worTinywan
  


七、一些常见误区
  1、redis2-nginx-module和lua-resty-redis
  redis2-nginx-module是一个openresty(1.9.15.1)自带的模块。它能够把请求转发给upstream(redis2_pass)。注意它和lua-resty-redis不同,lua-resty-redis是一个lua语言版的redis API,使用socket(lua sock)和redis通信。而redis2-nginx-module是把请求转发给别的upstream。
  2、以下错误解决办法
  

checking for LuaJIT library in /usr/bin/luajit/lib and(specified by the LUAJIT_LIB and LUAJIT_INC env, with -ldl) ... not found  
checking
for LuaJIT library in /usr/bin/luajit/lib and(specified by the LUAJIT_LIB and LUAJIT_INC env) ... not found  .
/configure: error: ngx_http_lua_module requires the Lua or LuaJIT library and LUAJIT_LIB is defined as  /usr/bin/luajit/lib and LUAJIT_INC (path for lua.h) , but we cannot find LuaJIT there.
  

  下载安装:LuaJIT-2.0.4
  更多版本下载地址:http://luajit.org/download.html
  

wgethttp://luajit.org/download/LuaJIT-2.0.4.tar.gz  
tar
-zxvfLuaJIT-2.0.4.tar.gz  
make && sudo make install
  





  告诉nginx的构建系统在哪里可以找到LuaJIT 2.0:
  

export LUAJIT_INC=/usr/local/include/luajit-2.0  

  http://blog.csdn.net/qq_25551295/article/details/51744815
页: [1]
查看完整版本: 【重要】Nginx模块Lua-Nginx