您的位置:首页 > 数据库 > Redis

nginx lua调用redis和mongo

2015-07-06 15:59 681 查看
参考
http://blog.csdn.net/vboy1010/article/details/7892120 http://www.zhangjixuem.com.cn/2014/4/1/01037.html https://github.com/bigplum/lua-resty-mongol
安装:

下载ngx_openresty-1.7.2.1.tar.gz

./configure --prefix=/data/nginx/openresty/resty --with-luajit

make

make install

修改nginx.conf

注意default_type text/plain;

否则浏览器触发是下载

charset utf-8,gbk;

否则可能会乱码

Java代码


worker_processes 1;

events {

worker_connections 1024;

}

http {

include mime.types;

charset utf-8,gbk;

# default_type application/octet-stream;

default_type text/plain;

lua_package_path "/data/www/lua/?.lua;;";

sendfile on;

keepalive_timeout 65;

server {

listen 80;

server_name localhost;

lua_code_cache off;

location /lua {

content_by_lua_file /data/www/lua/test.lua;

}

location /lua_mongo {

content_by_lua_file /data/www/lua/test_mongo.lua;

}

location /lua_get {

content_by_lua_file /data/www/lua/test_get.lua;

}

location / {

root html;

index index.html index.htm;

}

#

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

}

}

}

Java代码


local redis = require "resty.redis"

local cache = redis.new()

local ok, err = cache.connect(cache, '127.0.0.1', '6379')

cache:set_timeout(60000)

if not ok then

ngx.say("failed to connect:", err)

return

end

res, err = cache:set("dog", "an aniaml")

if not ok then

ngx.say("failed to set dog: ", err)

return

end

ngx.say("set result: ", res)

local res, err = cache:get("dog")

if not res then

ngx.say("failed to get dog: ", err)

return

end

if res == ngx.null then

ngx.say("dog not found.")

return

end

ngx.say("dog: ", res)

local ok, err = cache:close()

if not ok then

ngx.say("failed to close:", err)

return

end

结果

Java代码


[root@VM_192_107_centos lua]# !curl

curl http://localhost/lua
set result: OK

dog: an aniaml

[root@VM_192_107_centos lua]#

#---------------mongo的基本操作--------------
http://wenku.baidu.com/link?url=K2rmB_5ypVHErZPvi1UucFXfnfEXk4IrvgSQzeSabKJx50W_gpD2cFvCEPQZm0sZgMvHGJTmZahK96Ee3n7OgZTb4gHgybQdZsQ2xGV4nZm
启动mongo

./mongod --dbpath=../data/db --logpath=../log/mongodb.log

Java代码


show dbs

use admin

show collections

db.startup_log.count()

db.startup_log.find()

db.startup_log.find().forEach(function(doc){print(tojson(doc));});

u={name:"haoning",age:21}

db.haoning.insert(u)

db.haoning.insert({name:"ningning",age:10})

db.haoning.find({name:"haoning"});

db.haoning.find({age:18,name:"ning"});

db.haoning.find().sort({age:1});

db.haoning.find().sort({age:-1});

db.haoning.find().limit(2);

db.haoning.find().skip(2).limit(2);

db.haoning.find({age:{$gt:9,$lt:20},name:"ning"});

db.haoning.find({age:{$gt:9,$lt:20}});

$gte $lte $ne

db.haoning.find({age:{$in:[10,18]}});

db.haoning.find({$or:[{age:10},{age:21}]});

db.haoning.update({name:'ning'},{$set:{age:100,sex:0}});

db.haoning.update({name:'haohao'},{$inc:{age:10}},false,true);

db.haoning.findOne({name:"ningning"});

id=db.haoning.findOne({name:"ningning"})._id

db.haoning.remove(id);

db.haoning.ensureIndex({name:1})

db.haoning.ensureIndex({name:1},{backgrand:true})

db.haoning.ensureIndex({name:1},{unique:true})

db.haoning.ensureIndex({created_at:-1})

db.haoning.ensureIndex({name:1,created_at:-1})

db.haoning.distinct("name");

mongo的安装

git clone https://github.com/bigplum/lua-resty-mongol.git
make PREFIX=/data/nginx/openresty/resty install

/data/nginx/openresty/resty 为已经安装的resty的安装路径

会在/data/nginx/openresty/resty/lualib/resty

下面添加mongol的一些lua脚本

mongo的test的lua脚本:

参考
http://www.zhangjixuem.com.cn/2014/4/1/01037.html
Java代码


local mongo = require "resty.mongol"

local conn = mongo:new()

conn:set_timeout(1000)

local ok, err = conn:connect("127.0.0.1",27017)

if not ok then

ngx.say("connect failed: "..err)

end

local db=conn:new_db_handle("test")

local col = db:get_col("test")

local r = col:find_one({name="dog"},{_id=0})

for k,v in pairs(r) do

ngx.say(k..": "..v)

end

mongo的测试

Java代码


[root@VM_192_107_centos lua]# mongo

MongoDB shell version: 2.6.6

connecting to: test

> use test

switched to db test

> db.test.insert({name:"dog"})

WriteResult({ "nInserted" : 1 })

> ^C

bye

[root@VM_192_107_centos lua]# ^C

[root@VM_192_107_centos lua]# !curl

curl http://localhost/lua
set result: OK

dog: an aniaml

[root@VM_192_107_centos lua]# curl http://localhost/lua_mongo
name: dog

[root@VM_192_107_centos lua]#

另外,nginx向lua传值

Java代码


local request_method = ngx.var.request_method

local args = nil

local param = nil

local param2 = nil

if "GET" == request_method then

args = ngx.req.get_uri_args()

elseif "POST" == request_method then

ngx.req.read_body()

args = ngx.req.get_post_args()

end

param = args["p"]

ngx.say("request: ", param)

配置文件:

Java代码


location /lua_get {

content_by_lua_file /data/www/lua/test_get.lua;

}

测试

Java代码


[root@VM_192_107_centos lua]# !curl

curl http://localhost/lua_mongo
name: dog

[root@VM_192_107_centos lua]#

[root@VM_192_107_centos sbin]# curl -d "p='bbb'" http://127.0.0.1/lua_get?
post

request: 'bbb'

[root@VM_192_107_centos sbin]#

参考http://www.server110.com/nginx/201310/2800.html

#-----------------使用request的 data_body,及json的参数--------

[root@VM_192_107_centos lualib]# ls

cjson.so rds redis resty

[root@VM_192_107_centos lualib]# pwd

/data/nginx/openresty/resty/lualib

看下面有个cjson.so

就是可以require cjson了哈

Java代码


local json = require("cjson")

local request_method = ngx.var.request_method

local args = nil

local param = nil

local param2 = nil

--获取参数的值

if "GET" == request_method then

args = ngx.req.get_uri_args()

elseif "POST" == request_method then

ngx.req.read_body()

args = ngx.req.get_post_args()

end

param = args["param"]

param2 = args["param2"]

--升级版(能处理content-type=multipart/form-data的表单):

local function explode ( _str,seperator )

local pos, arr = 0, {}

for st, sp in function() return string.find( _str, seperator, pos, true ) end do

table.insert( arr, string.sub( _str, pos, st-1 ) )

pos = sp + 1

end

table.insert( arr, string.sub( _str, pos ) )

return arr

end

local args = {}

local file_args = {}

local is_have_file_param = false

local function init_form_args()

local receive_headers = ngx.req.get_headers()

local request_method = ngx.var.request_method

if "GET" == request_method then

args = ngx.req.get_uri_args()

ngx.say("request get: ", args)

elseif "POST" == request_method then

ngx.say("request: post ")

ngx.req.read_body()

ngx.say(string.sub(receive_headers["content-type"],1,33))

--if string.sub(receive_headers["content-type"],1,20) == "multipart/form-data;" then--判断是否是multipart/form-data类型的表单

if string.sub(receive_headers["content-type"],1,33) == "application/x-www-form-urlencoded" then--判断是否是multipart/form-data类型的表单

ngx.say("request: post 1")

is_have_file_param = true

content_type = receive_headers["content-type"]

body_data = ngx.req.get_body_data()--body_data可是符合http协议的请求体,不是普通的字符串

ngx.say("body_data:",body_data)

value = json.encode(body_data)

ngx.say(value)

a = json.decode(value)

ngx.say(a['aa'])

--请求体的size大于nginx配置里的client_body_buffer_size,则会导致请求体被缓冲到磁盘临时文件里,client_body_buffer_size默认是8k或者16k

if not body_data then

local datafile = ngx.req.get_body_file()

if not datafile then

error_code = 1

error_msg = "no request body found"

else

local fh, err = io.open(datafile, "r")

if not fh then

error_code = 2

error_msg = "failed to open " .. tostring(datafile) .. "for reading: " .. tostring(err)

else

fh:seek("set")

body_data = fh:read("*a")

fh:close()

if body_data == "" then

error_code = 3

error_msg = "request body is empty"

end

end

end

end

local new_body_data = {}

--确保取到请求体的数据

if not error_code then

local boundary = "--" .. string.sub(receive_headers["content-type"],31)

local body_data_table = explode(tostring(body_data),boundary)

local first_string = table.remove(body_data_table,1)

local last_string = table.remove(body_data_table)

for i,v in ipairs(body_data_table) do

local start_pos,end_pos,capture,capture2 = string.find(v,'Content%-Disposition: form%-data; name="(.+)"; filename="(.*)"')

if not start_pos then--普通参数

local t = explode(v,"\r\n\r\n")

local temp_param_name = string.sub(t[1],41,-2)

local temp_param_value = string.sub(t[2],1,-3)

args[temp_param_name] = temp_param_value

else--文件类型的参数,capture是参数名称,capture2是文件名

file_args[capture] = capture2

table.insert(new_body_data,v)

end

end

table.insert(new_body_data,1,first_string)

table.insert(new_body_data,last_string)

--去掉app_key,app_secret等几个参数,把业务级别的参数传给内部的API

body_data = table.concat(new_body_data,boundary)--body_data可是符合http协议的请求体,不是普通的字符串

end

else

ngx.say("request: post else")

args = ngx.req.get_post_args()

ngx.say("request: args ",args['p'])

end

end

end

init_form_args()

结果

Java代码


[root@VM_192_107_centos lualib]# !curl

curl -d "{aa:'cc'}" http://localhost/lua_get_post?p=cc
request: post

application/x-www-form-urlencoded

request: post 1

body_data:{aa:'cc'}

"{aa:'cc'}"

nil

[root@VM_192_107_centos lualib]#

结合mongo加cjson的例子

Java代码


[root@VM_192_107_centos lua]# cat getChannels.lua

local mongo = require "resty.mongol"

local json = require("cjson")

local conn = mongo:new()

conn:set_timeout(1000)

local ok, err = conn:connect("127.0.0.1",27017)

if not ok then

ngx.say("connect failed: "..err)

end

local db=conn:new_db_handle("meedo-service")

local col = db:get_col("channels")

local r = col:find_one({_id=1})

value = json.encode(r)

ngx.say(value)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: