起因
事情的起因是因?yàn)樵蹅兘涌诒凰⒘肆苫埃孕枰鳇c(diǎn)安全方面的操作
然后剛好我有這方面的經(jīng)驗(yàn)(OpenResty) 所以就接手這需求康聂,開始設(shè)計(jì)一個(gè)屬于自己的api gateway荔棉。雖然已經(jīng)有成熟的開源項(xiàng)目濒募,但是比較重坪郭,可能未必完全貼合我們的要求,個(gè)性化難以滿足 嗶哩吧啦 所以開始了踩坑之旅侣监。
引用介紹
OpenResty官網(wǎng):http://openresty.org/cn/
OpenResty最佳實(shí)踐:https://moonbingbing.gitbooks.io/openresty-best-practices/content/
開發(fā)一個(gè)需求 我一般有4步鸭轮, 計(jì)劃、執(zhí)行橄霉、檢查窃爷、修復(fù)
計(jì)劃:
計(jì)劃也就是需求分析,初步挖掘自己要做什么姓蜂,簡單的分析后列出如下幾個(gè)需求:
1按厘、防止別有用心的人使用程序刷接口 可從ip入手,限制同ip的訪問覆糟,畢竟ip庫是要錢的 成本太高也沒人會(huì)刷
2刻剥、請(qǐng)求頭過濾、咱們的app和h5都有特別的請(qǐng)求頭用于標(biāo)識(shí)身份滩字,雖然這個(gè)限制并沒有啥暖用
3造虏、灰度發(fā)布
第一版本,也不要求太高麦箍,先從簡單的入手
本來做出我是想通過在nginx上面配置一個(gè)統(tǒng)一的location 然后根據(jù)動(dòng)態(tài)的規(guī)則調(diào)整uri映射到后端服務(wù)漓藕,但是最終放棄了這個(gè)想法,因?yàn)閷?duì)我們現(xiàn)成的配置改動(dòng)較大挟裂,也不方便應(yīng)用nginx的原生模塊 如proxy_pass享钞、upstream 最終選擇維持現(xiàn)有的配置不變,為每一個(gè)location需要特別處理的執(zhí)行階段加入需要的處理腳本
這里引用:https://moonbingbing.gitbooks.io/openresty-best-practices/content/ngx_lua/phase.html 的介紹
set_by_lua: 流程分支處理判斷變量初始化
rewrite_by_lua: 轉(zhuǎn)發(fā)诀蓉、重定向栗竖、緩存等功能(例如特定請(qǐng)求代理到外網(wǎng))
access_by_lua: IP 準(zhǔn)入暑脆、接口權(quán)限等情況集中處理(例如配合 iptable 完成簡單防火墻)
content_by_lua: 內(nèi)容生成
header_filter_by_lua: 響應(yīng)頭部過濾處理(例如添加頭部信息)
body_filter_by_lua: 響應(yīng)體過濾處理(例如完成應(yīng)答內(nèi)容統(tǒng)一成大寫)
log_by_lua*: 會(huì)話完成后本地異步完成日志記錄(日志可以記錄在本地,還可以同步到其他機(jī)器)
ip防刷和請(qǐng)求頭過濾都通過在access_by_lua階段狐肢,設(shè)置相應(yīng)的執(zhí)行腳本完成
灰度發(fā)布通過 proxy_pass添吗、upstream、balancer_by_lua 配合完成
初始化加載配置通過 init_worker_by_lua*完成
重載配置 通過配置特殊location 由后端服務(wù)主動(dòng)發(fā)起
我假定讀者理解nginx基本運(yùn)行原理 熟悉配置份名,知道m(xù)aster與worker進(jìn)程 也理解lua語言 最好還有一部分的后端編程經(jīng)驗(yàn)
程序的大概工作流程是:
1碟联、先必須啟動(dòng)后端服務(wù)(java)
2、啟動(dòng)nginx僵腺,啟動(dòng)階段通過后端服務(wù)提供的http接口獲取運(yùn)行時(shí)配置鲤孵,含黑名單策略,緩存服務(wù)器地址等辰如。
nginx接收到請(qǐng)求普监,以ip加接口地址為key存入redis(使用lua腳本實(shí)現(xiàn)incr與expire的原子操作),當(dāng)達(dá)到閾值丧没,調(diào)用后端服務(wù)提供的添加黑名單http接口
3鹰椒、后端服務(wù)監(jiān)控指定的負(fù)載均衡列表的服務(wù)器的端口锡移,發(fā)生變化時(shí)推送最新配置到nginx呕童,或者是在手動(dòng)修改權(quán)重時(shí)推送。
api gateway的配置我保存在mysql數(shù)據(jù)庫淆珊,使用java與spring boot構(gòu)建后端程序用于與nginx交互夺饲,提供配置或者推送配置,都是通過http接口施符。黑名單ip存放在redis