惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
V
Visual Studio Blog
P
Privacy International News Feed
月光博客
月光博客
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
Lohrmann on Cybersecurity
N
News and Events Feed by Topic
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Apple Machine Learning Research
Apple Machine Learning Research
阮一峰的网络日志
阮一峰的网络日志
Webroot Blog
Webroot Blog
T
Threatpost
宝玉的分享
宝玉的分享
The Last Watchdog
The Last Watchdog
小众软件
小众软件
L
LINUX DO - 最新话题
C
Cisco Blogs
T
Troy Hunt's Blog
Schneier on Security
Schneier on Security
酷 壳 – CoolShell
酷 壳 – CoolShell
www.infosecurity-magazine.com
www.infosecurity-magazine.com
雷峰网
雷峰网
G
GRAHAM CLULEY
有赞技术团队
有赞技术团队
Know Your Adversary
Know Your Adversary
博客园 - 叶小钗
罗磊的独立博客
V
V2EX
博客园 - Franky
P
Proofpoint News Feed
SecWiki News
SecWiki News
腾讯CDC
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Jina AI
Jina AI
博客园 - 三生石上(FineUI控件)
S
Secure Thoughts
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google DeepMind News
Google DeepMind News
Attack and Defense Labs
Attack and Defense Labs
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
PCI Perspectives
PCI Perspectives
V2EX - 技术
V2EX - 技术
Google DeepMind News
Google DeepMind News
Last Week in AI
Last Week in AI
aimingoo的专栏
aimingoo的专栏
Cisco Talos Blog
Cisco Talos Blog
N
News and Events Feed by Topic
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
SegmentFault 最新的问题

博客园 - 灰太狼2号

开源.net微博组建维护团队 封装SQL2005数据库操作的Framework [转]Team Foundation Server 2008 單一伺服器簡易安裝說明 (Win2003+SQL2005+TFS2008) CHFMake代码生成器Beta版下载 Huntor中国CRM评估报告连载(二) Huntor中国CRM评估报告连载(一) 汉拓中国CRM评估报告简介 子曾经曰过:先有司,赦小过,举贤才 山寨版Windows.Forms用户控件 山寨版WCF 通过SQL语句生成日历表格 浅谈WebControl中的ScriptManager与ClientScriptManager的区别(附上一个弹出多选的控件源代码) 互联网公司如何有效执行流程的心得 自定义方法的C#代码生成器 [导入].Net CLR Hosting原理及实践 [导入]CLR引擎初始化分析 [导入]CLR探索系列:Server and Workstation Garbage Collection探索(垃圾回收系列) [导入]CLR探索系列:GC 中的Card table和Brick Table(垃圾回收系列) [导入]CLR探索系列:GC Heap架构及其实现(垃圾回收系列)
用Nginx+Lua+Redis给百度鹰眼API服务搭建缓存服务中间件(记录过程)
灰太狼2号 · 2019-04-22 · via 博客园 - 灰太狼2号

一、环境安装部分

Centos7,Nginx1.14,Redis5.0,luajit-2.1,ngx_devel_kit-0.3.1rc1,lua-nginx-module-0.10.14.

下载安装包:

wget http://nginx.org/download/nginx-1.14.0.tar.gz
wget https://github.com/simplresty/ngx_devel_kit/archive/v0.3.1rc1.tar.gz
wget https://github.com/openresty/lua-nginx-module/archive/v0.10.14.tar.gz
wget http://luajit.org/download/LuaJIT-2.1.0-beta3.tar.gz
wget http://download.redis.io/releases/redis-5.0.4.tar.gz

安装配置过程:

解压ngx_devel_kit和lua-nginx-module

tar xzvf v0.3.1rc1.tar.gz
tar xzvf v0.10.14.tar.gz

解压LuaJIT,进入目录编译安装

make PREFIX=/usr/local/luajit
make install PREFIX=/usr/local/luajit
export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.1

解压Nginx,给编译参数追加上面三个模块的目录再编译

nginx -V #已安装Nginx执行该命令查看现有编译参数
configure arguments: 
--prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --user=www --group=www --with-http_ssl_module --with-pcre --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module

#执行./configure命令,在现有编译参数最后追加luajit,ngx_devel_kit和lua-nginx-module
./configure --prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --user=www --group=www --with-http_ssl_module --with-pcre --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module--with-ld-opt=-Wl,-rpath,/usr/local/luajit/lib --add-module=/data/lua/ngx_devel_kit-0.3.1rc1 --add-module=/data/lua/lua-nginx-module-0.10.14

service nginx stop
make #编译
cp objs/nginx /usr/sbin/

service nginx start
nginx -V #检查模块是否添加上

解压Redis,进入目录编译

make PREFIX=/usr/local/redis
make install PREFIX=/usr/local/redis
cd /usr/local/redis/bin
./redis-server & #启动
./redis-cli #测试set a a; keys *; flushall


二、Lua代码编写部分

下载插件拷贝lua文件至目录 /usr/local/lib/lua/resty
resty.http:https://github.com/ledgetech/lua-resty-http
resty.redis:https://github.com/openresty/lua-resty-redis
resty.redis_iresty:https://github.com/moonbingbing/9915c66346e8fddcefb5

配置Nginx文件

#http下添加lua路径
lua_package_path "/usr/local/lib/lua/?.lua;;";

#server下添加DNS,字符集和location
resolver 8.8.8.8;
charset utf-8;
#地理解码
location /geocoder/{
  default_type "application/json;charset=utf-8";
  content_by_lua_file "/usr/local/lib/lua/resty/geocoder.lua"
  #也可以用content_by_lua_block{直接将代码写到nginx内部}
}
#鹰眼服务
location /api/ {
  default_type "application/json;charset=utf-8";
  content_by_lua_file "/usr/local/lib/lua/resty/api.lua"
}

编写lua代码文件

地理解码文件/usr/local/lib/lua/resty/geocoder.lua
数据隐私保护:客户端发送请求url可以不需要携带ak和service_id参数
二次请求缓存:第二请求传递坐标数据时,直接从redis拿坐标对应位置

local url = ngx.var.request_uri.."&ak=你的ak参数&service_id=你的鹰眼服务id"
local redis = require "resty.redis_iresty"
local red = redis:new()
local res, err = red:get(url)
if not res or res == ngx.null then
    local http = require "resty.http"
    local httpc = http.new()
    local res, err = httpc:request_uri("http://api.map.baidu.com"..url)
    if res.status == ngx.HTTP_OK then
        red:set(url, res.body)
        ngx.print(res.body)
        return
    else
        ngx.exit(res.status)
    end
end

ngx.print(res)

鹰眼服务API文件/usr/local/lib/lua/resty/api.lua
支持post请求,可编辑post参数内容,对post参数追加ak和service_id
为防止错乱,只对包含参数end_time且值小于今天的请求结果进行缓存
客户端可用http://yourdomain.com/api/* 代替 http://yingyan.baidu.com/api/*

local http = require "resty.http"
local httpc = http.new()

if ngx.var.request_method == "POST" then
    ngx.req.read_body();
    local postargs = ngx.req.get_post_args()
    local postdata = "ak=你的ak参数&service_id=你的鹰眼服务id"
    for k,v in pairs(postargs) do
        postdata = postdata.."&"..k.."="..v
    end
    local res = httpc:request_uri("http://yingyan.baidu.com"..ngx.var.uri, { method = "POST", body = postdata, headers = { ["Content-Type"] = "application/x-www-form-urlencoded", ["Content-Length"] = nil } })
    if res.status == ngx.HTTP_OK then
        ngx.print(res.body)
        return
    else
        ngx.exit(res.status)
    end
end

local end_time = nil
local args = ngx.req.get_uri_args()
local url = ngx.var.request_uri.."&ak=你的ak参数&service_id=你的鹰眼服务id"
for k,v in pairs(args) do
    if(k == "end_time") then
        end_time = v
        break
    end
end
if(end_time ~= nil) then
    local now_time = os.date("*t")
    local today_time = os.time({day=now_time.day, month=now_time.month,year=now_time.year, hour=0, minute=0, second=0})
    if(tonumber(end_time) < today_time) then
        local redis = require "resty.redis_iresty"
        local red = redis:new()
        local res = red:get(url)
        if not res or res == ngx.null then
            local res = httpc:request_uri("http://yingyan.baidu.com"..url)
            if res.status == ngx.HTTP_OK then
                red:set(url, res.body)
                ngx.print(res.body)
                return
            else
                ngx.exit(res.status)
            end
        end

        ngx.print(res)
        return
    end
end

local res = httpc:request_uri("http://yingyan.baidu.com"..url)
if res.status == ngx.HTTP_OK then
    ngx.print(res.body)
else
    ngx.exit(res.status)
end

以上开发调试工具:https://openresty.org/download/openresty-1.13.6.2-win64.zip,https://moonbingbing.gitbooks.io/openresty-best-practices/content/lua/build_env.html

PS:原创文章,转载请标注来源。@轻云科技,by海飞。