
ipip.net IP 数据库之 openresty 版,为了方便 nginx 使用 ip 数据所封装的拓展包。
本脚本封装了 ipip.net 的主要接口配制好后就可以直接使用,并不需要再去复杂的内部实现。
需要注意的是如果使用 api 访问需要 http 拓展包。
代码我已提交至 GitHub: https://github.com/icowan/lua-resty-17mon
如果对 lua 不了解请看我前段时间写的: 《 Lua 基础学习方式 (一天学会) 》
如果还没安装 openresty 请看: 《优雅的安装 openresty 》
`
要使用首先得载入自己写义的 lualib ,这个根据你安装的或使用方式去修改路径。
lua_package_path "/usr/local/openresty/lualib/?.lua;/var/www/lua-resty-17mon/lualib/?.lua;;"; lua_package_cpath "/usr/local/openresty/lualib/?.so;;"; error_log /var/www/lua-resty-17mon/logs/lua-resty-17mon.debug.log debug; server { listen 8080; server_name localhost; charset utf-8; location /ipLocation { resolver 8.8.8.8; # 如果要使用 api 的话 需要 dns 这可以改成中国的会快一些 default_type "text/plain"; content_by_lua_file "/var/www/lua-resty-17mon/script/ip_location.lua"; } } -- /var/www/lua-resty-17mon/script/ip_location.lua ngx.req.read_body() ngx.header.content_type = "application/json;charset=" local cjson = require "cjson" local success = function(con) return cjson.encode({ success = true, body = con }) end local failure = function(err) return cjson.encode({ success = false, errors = err }) end -- 参数获取 local request_args = ngx.req.get_uri_args() local ip_address = request_args['ip'] -- 如果不需要验证可以不用此拓展 local checkIp = require("ip_check"):new(ip_address) -- 验证 ip local ok, err = checkIp:checkIp() if not ok then ngx.say(failure(err)) return end -- 使用本地数据库 local ipdetail, err = require("ip_location"):new(ip_address, "/var/www/lua-resty-17mon/file/17monipdb.dat") if not ipdetail then ngx.log(ngx.ERR, err) ngx.say(failure(err)) return end local ipLocation, err = ipdetail:location() if not ipLocation then ngx.log(ngx.ERR, err) ngx.say(failure(err)) return end ngx.say(success(ipLocation)) 如果通过 api 获取数据需要使用 http 服务,这里需要使用lua-resty-http 这里我已经把它直接放到
lualib/resty目录了,可以直接使用 感谢pintsized提供的脚本
-- /var/www/lua-resty-17mon/script/ip_location.lua local ipdetail, err = require("ip_location"):new(ip_address) if not ipdetail then ngx.log(ngx.ERR, err) ngx.say(failure(err)) return end local ipLocation, err = ipdetail:locationApiFree() if not ipLocation then ngx.log(ngx.ERR, err) ngx.say(failure(err)) return end ngx.say(success(ipLocation)) -- /var/www/lua-resty-17mon/script/ip_location.lua local ipdetail, err = require("ip_location"):new(ip_address, "", "your token") if not ipdetail then ngx.log(ngx.ERR, err) ngx.say(failure(err)) return end local ipLocation, err = ipdetail:locationApiFree() if not ipLocation then ngx.log(ngx.ERR, err) ngx.say(failure(err)) return end ngx.say(success(ipLocation)) -- /var/www/lua-resty-17mon/script/ip_location.lua local ipdetail, err = require("ip_location"):new(ip_address, "your token") if not ipdetail then ngx.log(ngx.ERR, err) ngx.say(failure(err)) return end local ipLocation, err = ipdetail:apiStatus() if not ipLocation then ngx.log(ngx.ERR, err) ngx.say(failure(err)) return end ngx.say(success(ipLocation)) Response
返回类型: JSON
| 参数 | 类型 | 备注 | | --- | --- | --- | | success | bool | true or false | | errors or body | string | 当 success 为 false 时 errors 有值否则返回 body |
body 返回参数详情
| 参数 | 类型 | 备注 | | --- | --- | --- | | country | string | 国家 | | city | string | 省会或直辖市(国内) | | region | string | 地区或城市 (国内) | | place | string | 学校或单位 (国内) | | operator | string | 运营商字段 | | latitude | string | 纬度 | | longitude | string | 经度 | | timeZone | string | 时区一, 可能不存在 | | timeZoneCode | string | 时区码 | | administrativeAreaCode | string | 中国行政区划代码 | | internationalPhoneCode | string | 国际电话代码 | | countryTwoDigitCode | string | 国家二位代码 | | worldContinentCode | string | 世界大洲代码 |
返回结果参考:
{ "success": true, "body": { "country": "", // 国家 "city": "", // 省会或直辖市(国内) "region": "", // 地区或城市 (国内) "place": "", // 学校或单位 (国内) "operator": "", // 运营商字段(只有购买了带有运营商版本的数据库才会有) "latitude": "", // 纬度 (每日版本提供) "longitude": "", // 经度 (每日版本提供) "timeZone": "", // 时区一, 可能不存在 (每日版本提供) "timeZoneCode": "", // 时区码, 可能不存在 (每日版本提供) "administrativeAreaCode": "", // 中国行政区划代码 (每日版本提供) "internationalPhoneCode": "", // 国际电话代码 (每日版本提供) "countryTwoDigitCode": "", // 国家二位代码 (每日版本提供) "worldContinentCode": "" // 世界大洲代码 (每日版本提供) } } ERROR 结果参考
{ "success": false, "erros": "retun messages..." } 查询状态结果参考
{ "success": true, "body": { "limit": false, // 是否已受访问限制 "hour": 99680, // 一个小时内剩余次数 "day": 999680, // 24 小时内剩余次数 } } 难得为开源社区贡献一份力量,希望有同样需求的同学们可以不用再去写复杂的底层逻辑,应该更多的把时间估计业务流程上。
同样希望这个脚本能提供给 ipip.net 官方推荐脚本。
如有任何疑问欢迎联系我: [email protected]
或访问我 网站: LatteCake
修复一处错误:
local ipLocation, err = ipdetail:locationApi("your sid", "your uid") if not ipLocation then ngx.log(ngx.ERR, err) ngx.say(failure(err)) return end 负费的应该使用ipdetail:locationApi("yor sid", "your uid") 这个方法
1 ivmm 2016-10-22 17:15:12 +08:00 关于 OpenResty 有个疑惑。 它都是基于 Nginx 主线版本的,如果要用于生产环境那么稳定性如何呢? 还是说生产环境需要自己用 Nginx 安装相关模块? |
2 ysz1121 OP @ivmm OpenResty 已经把 nginx 的主要模块包含进来了,你可以查看 openresty 包目录里的 nginx 目录。 |
4 ivmm 2016-10-22 21:10:21 +08:00 @ysz1121 不是,我是说 OpenResty 是基于 Nginx mainline 的版本,而不是 stable 的版本。 生产环境怎么用。 可靠么,而且它 OpenResty 的主线更新还不及时 |
5 cnZary 2016-10-23 11:16:12 +08:00 双标题 |
6 neoblackcap 2016-10-23 12:31:44 +08:00 @ivmm cloudflare 在生产环境里面都是用 OpenRestry ,还是挺可靠的 |