1.1 说明 #环境 centos + openresty + lua-resty-mongol # nginx.conf http: lua_shared_dict ipdb 45m; init_by_lua_file '/root/test/src/test/init.lua'; location: set $region ''; rewrite_by_lua_file '/root/test/src/test/set.lua'; access_by_lua_file '/root/test/src/test/mongo.lua'; content_by_lua 'ngx.say("hello,caoqing")'; # ip库格式 1.0.0.0 1.0.0.255 澳大利亚 1.0.1.0 1.0.3.255 福建省 1.0.4.0 1.0.7.255 澳大利亚 1.0.8.0 1.0.15.255 广东省 1.0.16.0 1.0.31.255 日本 1.0.32.0 1.0.63.255 广东省 1.0.64.0 1.0.127.255 日本 1.0.128.0 1.0.255.255 泰国 ...... # 功能 解析客户端地址,并将相应变量写入mongodb 1.2 加载ip到共享内存 -- init.lua -- 2013.12.11 qing cao (lucifer) local cjson = require "cjson" local sfind = string.find local ssub = string.sub local tinsert = table.insert local ilines = io.lines local tonumber = tonumber local ipdb = ngx.shared.ipdb function string_split(source_str, split_char) local find_index, start_index, num, split_array = 1, 1, 1, {} while true do local find_index, _ = sfind(source_str, split_char, start_index) if not find_index then split_array[#split_array + 1] = ssub(source_str, start_index, #source_str) break end local sub_str = ssub(source_str, 1, find_index - 1) split_array[#split_array + 1] = sub_str source_str = ssub(source_str, find_index + 1, #source_str) num = num + 1 end return num, split_array end local ipTab = {} for i = 0, 255 do ipTab[i] = {} end for item in ilines("/root/test/src/iplist") do local _, arr = string_split(item, " ") _, _, startIpa, startIpb, startIpc, startIpd = sfind(arr[1], "(%d+).(%d+).(%d+).(%d+)") startIpnum = startIpa*16777216 + startIpb*65536 + startIpc*256 + startIpd _, _, endIpa, endIpb, endIpc, endIpd = sfind(arr[2], "(%d+).(%d+).(%d+).(%d+)") endIpnum = endIpa*16777216 + endIpb*65536 + endIpc*256 + endIpd tinsert(ipTab[tonumber(startIpa)], {startIpnum, endIpnum, arr[3]}) end for i = 0, 255 do local setInfo = cjson.encode(ipTab[i]) ipdb:set("group:" .. i, setInfo) end 1.3 判断地址库,赋值nginx变量 -- set.lua -- 2013.12.11 qing cao (lucifer) local sfind = string.find local tonumber = tonumber local cjson = require "cjson" local ipdb = ngx.shared.ipdb local ip = ngx.var.remote_addr local _, _, ipa, ipb, ipc, ipd = sfind(ip, "(%d+).(%d+).(%d+).(%d+)") local ipnum = ipa*16777216 + ipb*65536 + ipc*256 + ipd local groupId = tonumber(ipa) local ipGroup = cjson.decode(ipdb:get("group:" .. groupId)) local groupTot = #ipGroup for i = 1, groupTot do if (ipnum >= ipGroup[i][1]) and (ipnum <= ipGroup[i][2]) then _res = ipGroup[i][3] break end end ngx.var.region = _res 1.4 将数据写入mongodb -- mongo.lua -- 2013.12.11 qing cao (lucifer) local M_server_addr = ngx.var.server_addr local M_addr = ngx.var.remote_addr local M_region = ngx.var.region local M_user = ngx.var.remote_user local M_time = ngx.var.time_local local M_method = ngx.var.request_method local M_scheme = ngx.var.scheme local M_host = ngx.var.host local M_uri = ngx.var.request_uri local M_protocol = ngx.var.server_protocol local M_referer = ngx.var.http_referer or "" local M_agent = ngx.var.http_user_agent local M_forwarded = ngx.var.http_x_forwarded_for local mongo = require "resty.mongol" conn = mongo:new() conn:set_timeout(1000) local ok, err = conn:connect("192.168.1.208", "27017") if not ok then ngx.say("connect failed: " .. err) end local db = conn:new_db_handle ( "ddb" ) local ok, err = db:auth("admin","admin") if not ok then ngx.say("failed to log in: " .. err) end local collection = "cq_log" local col = db:get_col(collection) local log_record = {{ server_add = M_server_addr, region = M_region, remote_addr = M_addr, remote_user = M_user, time_local = M_time, request_method = M_method, scheme = M_scheme, http_host = M_host, request_uri = M_uri, server_protocol = M_protocol, request_body = M_body, status = M_status, body_bytes_sent = M_sent, http_referer = M_referer, http_user_agent = M_agent, http_x_forwarded_for = M_forwarded}} local r, err = col:insert(log_record, nil, true) if not r then ngx.status = 400 ngx.say("filed to set key: " .. err) end local ok, err = conn:set_keepalive(0,1000) if not ok then ngx.say("failed to set keepalive: ", err) return end 1.5 简单测试 # test.py import urllib2 import datetime startime = datetime.datetime.now() for i in range(1000): reponse = urllib2.urlopen('http://localhost/') # headers = reponse.info() # data = reponse.read() # print headers, data endtime = datetime.datetime.now() print 'START :', startime print 'END :', endtime print 'runningtime :', endtime - startime # result START : 2013-12-11 15:08:49.708147 END: 2013-12-11 15:09:32.323040 runningtime: 0:00:42.614893