使用Redis作分佈式緩存;使用lua API來訪問redis緩存;使用nginx向客戶端提供服務,ngx_lua將lua嵌入到nginx,讓nginx執行lua腳本,高併發,非阻塞的處理各類請求。url請求nginx服務器,而後lua查詢redis,返回json數據。html
系統環境:Ubuntu 14.0 (64位)linux
Redis服務安裝:apt-get install redis-servernginx
安裝Git:apt-get install gitgit
安裝Lua:github
# 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 出現的錯誤信息:redis
make[1]: *** [objs/addon/src/ngx_stream_lua_socket_tcp.o] Error 1
解決辦法:shell
apt-get install lua-socket
一、當前目錄:/home/www 目錄下面json
二、下載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
三、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
四、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
五、set-misc-nginx-module 下載。是標準的HttpRewriteModule指令的擴展,提供更多的功能,如URI轉義與非轉義、JSON引述,Hexadecimal、MD五、SHA一、Base3二、Base64編碼與解碼、隨機數等等
wget https://github.com/openresty/set-misc-nginx-module/archive/v0.31.tar.gz
tar -zxvf v0.31.tar.gz
六、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
七、Nginx 下載
wget http://nginx.org/download/nginx-1.10.3.tar.gz
tar -zxvf nginx-1.10.3.tar.gz
一、查看全部下載完的包
root@iZ236j3sofdZ:/home/www# ls echo-nginx-module-0.60 lua-nginx-module-0.10.7 nginx-1.10.3 nginx-1.10.3.tar.gz
ngx_devel_kit-0.3.0 redis2-nginx-module-0.13 redis-lua-2.0.4 set-misc-nginx-module-0.31
二、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-sha1=/usr/include/openssl --with-md5=/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[1]: Leaving directory `/home/www/nginx-1.10.3' 什麼意思
解決辦法:
到你的源碼目錄內,先make clean 而後./config ...
三、安裝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/
四、使用Redis的提示錯誤
[error] 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;;";
一、配置nginx.conf(如下是部分代碼)
# nginx.conf http { ..... lua_package_path "/usr/local/nginx/lua/lua-resty-redis/lib/?.lua;;"; #gzip on;
server { listen 80; server_name localhost; location / { root html; index index.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: [alert] 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
一、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。
二、如下錯誤解決辦法
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
wget http://luajit.org/download/LuaJIT-2.0.4.tar.gz tar -zxvf LuaJIT-2.0.4.tar.gz make && sudo make install
告訴nginx的構建系統在哪裏能夠找到LuaJIT 2.0:
export LUAJIT_INC=/usr/local/include/luajit-2.0