基于 OpenResty 的短信驗證碼平臺接口網(wǎng)關(guān)設(shè)計
來源:原創(chuàng) 時間:2017-10-13 瀏覽:0 次
本文講述基于 OpenResty 的
短信驗證碼平臺接口關(guān)設(shè)計,主要談及接口網(wǎng)關(guān)的請求路由與安全認證(IP 與 URI 白名單、加解密與驗簽名流程等)這兩部分內(nèi)容,其中涉及到的 Nginx、OpenResty 等相關(guān)內(nèi)容會作簡單介紹。
談?wù)劵?OpenResty 的接口網(wǎng)關(guān)設(shè)計
〇、前言
一、什么是接口網(wǎng)關(guān)
1.1 定位
1.2 功能
二、為什么需要接口網(wǎng)關(guān)
2.1 請求路由
2.2 安全認證
三、如何開發(fā)接口網(wǎng)關(guān)
3.2.1 兩層 HAProxy 代理
3.2.2 接口網(wǎng)關(guān)
3.2.3 架構(gòu)總結(jié)
3.2.2.1 主流程設(shè)計
3.2.2.2 配置服務(wù)設(shè)計
3.2.2.3 安全服務(wù)設(shè)計
3.1.1 Nginx 簡介
3.1.1 OpenResty 簡介
3.1 Nginx 與 OpenResty 簡介
3.2 接口網(wǎng)關(guān)的架構(gòu)
〇、前言
筆者曾參與開發(fā)兩個
短信驗證碼平臺接口網(wǎng)關(guān)的項目,一個是基于 Tomcat 的應(yīng)用提供的網(wǎng)關(guān)服務(wù),另一個是基于 OpenResty 的 Nginx 應(yīng)用提供的網(wǎng)關(guān)服務(wù)。經(jīng)過兩個網(wǎng)關(guān)項目的開發(fā),筆者在接口網(wǎng)關(guān)開發(fā)方面稍微積累了一些經(jīng)驗,故在此把這些經(jīng)驗分享出來一起交流學習。由于基于 OpenResty 的 Nginx 網(wǎng)關(guān)普遍被認為是更優(yōu)的方案,故本文主要針對基于 OpenResty 的 Nginx 網(wǎng)關(guān)進行講述。當然,由于不同的并發(fā)數(shù)量級,不同的業(yè)務(wù)場景,接口網(wǎng)關(guān)的設(shè)計多種多樣,本文所述其中較為簡單且輕量級的一種。
注:由于筆者經(jīng)驗與知識有限,文章中如有錯誤或偏頗,歡迎探討和指正(作業(yè)部落提供文章按塊批注功能,非常歡迎提批注,筆者會及時修正)。
一、什么是接口網(wǎng)關(guān)
1.1 定位
接口網(wǎng)關(guān),顧名思義,是企業(yè) IT 在系統(tǒng)邊界上提供給外部訪問內(nèi)部接口服務(wù)的統(tǒng)一入口。這里的外部可以指客戶端、瀏覽器或者第三方應(yīng)用等,在這種情況下,接口網(wǎng)關(guān)可以有多種定位:
提供后端服務(wù)面向 Web App 或者 Mobile App 的 APIGateway
作為開放平臺面向 Partner 的 OpenAPI
...
在筆者的工作中,同樣把面向客戶端的網(wǎng)關(guān)稱作 APIGateway,把作為開放平臺提供給第三方服務(wù)的網(wǎng)關(guān)稱作 OpenApi。本文主要以 OpenApi 作為接口網(wǎng)關(guān)為例來講述。
1.2 功能
作為企業(yè) IT 系統(tǒng)的統(tǒng)一入口,接口網(wǎng)關(guān)可提供請求路由與組合、協(xié)議轉(zhuǎn)換、安全認證、服務(wù)鑒權(quán)、流量控制與日志監(jiān)控等服務(wù)。在筆者的工作中,主要在接口網(wǎng)關(guān)上實現(xiàn)了請求路由與安全認證的功能,題目中所說的“設(shè)計”,主要是指請求路由與安全認證方面,暫不涉及流量控制或日志監(jiān)控等其他方面的設(shè)計。
二、為什么需要接口網(wǎng)關(guān)
正如上文所言,
短信驗證碼平臺接口為企業(yè)應(yīng)用提供了豐富的功能,而筆者在工作中開發(fā)的接口網(wǎng)關(guān)主要提供請求路由與安全認證的功能,那么在回答“為什么需要接口網(wǎng)關(guān)”的時候,需要對這兩者多加闡述。
2.1 請求路由
企業(yè)提供內(nèi)外兩網(wǎng),在沒有接口網(wǎng)關(guān)時,提供外部服務(wù)的應(yīng)用需要部署在外網(wǎng)。隨著服務(wù)的增多,部署在外網(wǎng)的應(yīng)用越來越多,在服務(wù)的安全壓力與維護成本增大的情況下,需要一個統(tǒng)一的接口網(wǎng)關(guān)“隔離”內(nèi)外服務(wù)。企業(yè)提供的服務(wù)(無論內(nèi)部服務(wù)還是外部服務(wù))均部署在內(nèi)網(wǎng),而由部署在外網(wǎng)的網(wǎng)關(guān)接受請求,并路由到內(nèi)網(wǎng)服務(wù)。在這種情況下,既有利于對外屏蔽企業(yè)內(nèi)部服務(wù)部署細節(jié),提供統(tǒng)一的服務(wù)訪問地址,又便于管理與維護內(nèi)外部服務(wù)接口,便于演進與重構(gòu)服務(wù)。這是接口網(wǎng)關(guān)提供請求路由的作用。
2.2 安全認證
在沒有接口網(wǎng)關(guān)時,企業(yè)對外服務(wù)直接由外部訪問,身份驗證與數(shù)據(jù)加解密等工作都需要每一個對外服務(wù)本身去處理,增加了服務(wù)本不該有的職責,并且增加了服務(wù)開發(fā)的難度與工作量。實際在大多數(shù)情況下,可以將身份驗證與數(shù)據(jù)加解密等安全工作可以從服務(wù)抽離,統(tǒng)一由接口網(wǎng)關(guān)負責處理。接口網(wǎng)關(guān)作為入口,對外驗證調(diào)用方的 IP,身份以及接口訪問權(quán)限等,并且可以解密數(shù)據(jù)后再將請求路由到服務(wù)。這是接口網(wǎng)關(guān)提供安全認證的功能。
以上是實際工作中涉及的為什么需要接口網(wǎng)關(guān)的其中兩個原因,當然原因遠不止此,有興趣的讀者可以閱讀其他文章,比如 《談API網(wǎng)關(guān)的背景、架構(gòu)以及落地方案》 或者 《微服務(wù):從設(shè)計到部署》(英文原文:Microservices: From Design to Deployment)。接下來的章節(jié)我們開始探討如何開發(fā)接口網(wǎng)關(guān)。
三、如何開發(fā)接口網(wǎng)關(guān)
我們先看看工作中設(shè)計的提供請求路由與安全認證功能的接口網(wǎng)關(guān)的架構(gòu)。
不過在介紹接口網(wǎng)關(guān)的設(shè)計之前,我們先來了解一下關(guān)于 Nginx 與 OpenResty 的基礎(chǔ)知識。
3.1 Nginx 與 OpenResty 簡介
3.1.1 Nginx 簡介
Nginx 是世界第二大 Web 服務(wù)器,僅次于 Apache,然而由于其極高的性能可處理海量的互聯(lián)網(wǎng)請求,現(xiàn)在已經(jīng)成為業(yè)界高性能 Web 服務(wù)器的代名詞。
它的主要特征是高性能、高擴展性、高可靠性、低內(nèi)存消耗、單機支持 10 萬以上的并發(fā)連接,支持熱部署,以及使用較自由的 BSD 許可協(xié)議。其中,Nginx 可以處理高并發(fā)壓力下的并發(fā)請求的原因如下:
事件驅(qū)動模型設(shè)計
全異步的網(wǎng)絡(luò) I/O 處理機制
極少的進程切換
內(nèi)存消耗低,極度“壓榨”服務(wù)器硬件資源
除了基于事件驅(qū)動的架構(gòu)使其支持百萬級的 TCP 連接,另外高度模塊化的設(shè)計和自由的許可證使其擁有非常多擴展其功能的第三方模塊,也是它的重要特性。所以,后來才會有 OpenResty 的誕生。
我們看一個 Nginx 作簡單配置來提供服務(wù)的例子:
worker_processes 1;
events {
worker_connections 1024;
}
http {
upstream backend {
server 127.0.0.1:8080
}
server {
location /back {
proxy_pass http://backend;
}
}
}
上述配置文件中,分別在 event、http、server 以及 location 塊配置項中做了一些簡單的配置,當安裝完并啟動 Nginx后(監(jiān)聽 80 端口),訪問到 /back 路徑下的請求會被轉(zhuǎn)發(fā)到本地 127.0.0.1:8080 服務(wù)上。
3.1.1 OpenResty 簡介
根據(jù)官網(wǎng)定義,OpenResty 是一個通過 Lua 擴展 Nginx 實現(xiàn)的可伸縮的 Web 平臺。其核心是基于 Nginx 一個 C 模塊將 Lua 語言嵌入到 Nginx 服務(wù)器中,對外提供一套完整的 Lua Web 的 API,并透明支持非阻塞 I/O,提供協(xié)程 —— “輕量級線程”、定時器等,從而極大地降低了高性能服務(wù)端的開發(fā)難度和開發(fā)周期。
OpenResty 將兩個極為優(yōu)秀的組件 Nginx 與 Lua 進行糅合,一方面保留了 Nginx 高性能 web 服務(wù)特征,另一方面有提供 Lua 特性在極少損失性能情況下便于業(yè)務(wù)功能的開發(fā)。根據(jù)官網(wǎng)介紹,OpenResty 非常便于用來搭建能夠處理超高并發(fā)、擴展性極高的動態(tài) Web 應(yīng)用、Web 服務(wù)和動態(tài)網(wǎng)關(guān)。
我們也是因為 OpenResty 的這些特性,特別是它對搭建動態(tài)網(wǎng)關(guān)的友好支持,才選擇了基于 OpenResty 來開發(fā)我們的接口網(wǎng)關(guān) —— APIGateway 與 OpenApi。
開發(fā)接口網(wǎng)關(guān)使用到的 OpenResty 一個重要知識:OpenResty 對于一個請求的處理流程。Nginx 把一個請求分為不同的階段,從而讓第三方模塊通過掛載行為在不同的階段來定制自己的行為;OpenResty 擁有同樣的特性,不過在不同階段掛載的是 Lua 腳本。下圖是基于《OpenResty 最佳實踐》原圖重繪而來:
從上圖可知,OpenResty 處理請求大致分為四個階段:
初始化階段(Initialization Phase)
重寫與訪問階段(Rewrite / Access Phase)
內(nèi)容生成階段(Content Phase)
日志記錄階段(Log Phase)
我們看一個 OpenResty 作簡單配置來提供服務(wù)的例子:
worker_processes 1;
events {
worker_connections 1024;
}
http {
resolver 127.0.0.1;
lua_package_path '$prefix/lua/?.lua;;';
init_by_lua_block {
# ...
}
init_worker_by_lua_file lua/init_work_by_lua.lua;
server {
listen 80;
location / {
rewrite_by_lua_file lua/rewrite_by_lua.lua;
access_by_lua_file lua/access_by_lua.lua;
proxy_pass http://<url>;
}
}
}
上述配置文件中,分別在 event、http、server 以及 location 塊配置項中做了一些簡單的配置,當安裝完并啟動 Nginx后(監(jiān)聽 80 端口),首先執(zhí)行 init_by_lua_block、init_worker_by_lua_file 進行初始化,接著接受請求,所有的請求都會匹配上 "/" 路徑,進而執(zhí)行 rewrite_by_lua_file、access_by_lua_file 進行重寫與訪問,最后轉(zhuǎn)發(fā)請求到本地 127.0.0.1 服務(wù)上。
在實際的接口網(wǎng)關(guān)開發(fā)中,我們主要是使用到了 OpenResty 中初始化階段的 init_by_lua*、init_worker_by_lua*、重寫與訪問階段 的 rewrite_by_lua*、access_by_lua* 以及內(nèi)容生成階段 content_by_lua* 過程。
3.2 接口網(wǎng)關(guān)的架構(gòu)
這一節(jié)是本文的核心內(nèi)容,重點講述接口網(wǎng)關(guān)的架構(gòu)設(shè)計。如前文所述,本文主要以 OpenApi 為例來講述接口網(wǎng)關(guān)的架構(gòu)設(shè)計。先看圖:
下面我們來一步步來分析架構(gòu)圖的各個部分,首先是兩層的 HAProxy 。
3.2.1 兩層 HAProxy 代理
根據(jù)維基百科定義,HAProxy 是一個使用 C 語言編寫的自由及開放源代碼軟件,其提供高可用性、負載均衡,以及基于 TCP 和 HTTP 的應(yīng)用程序代理。
如圖所示,隔離的內(nèi)網(wǎng)與外網(wǎng)上分別提供了 HAProxy 代理, 外層暫且稱為 HAProxy internet ,內(nèi)層稱為 HAProxy internal。外層暴露于外網(wǎng)中,使用統(tǒng)一地址如 http://openapi.company.com 來接受外部請求(這里指第三方的請求);中間是基于 OpenResty 的 Nginx 網(wǎng)關(guān)層,外部請求經(jīng)過網(wǎng)關(guān)后通過 HAProxy internal 轉(zhuǎn)發(fā)到內(nèi)網(wǎng)的服務(wù)上,內(nèi)網(wǎng)服務(wù)遵循 Restful 風格,網(wǎng)關(guān)轉(zhuǎn)發(fā)到內(nèi)網(wǎng)的地址由接口網(wǎng)關(guān)控制。
然而,目前的代理架構(gòu)受到了當前整體架構(gòu)的約束,實際上兩層的 HAProxy 代理并不是必需的。
對于外層 HAProxy internet,由于我們使用了與 HAProxy 緊密結(jié)合的 Openshift 架構(gòu),所以多了一層 HAProxy 的轉(zhuǎn)發(fā);一般情況下,基于 OpenResty 的 Nginx 網(wǎng)關(guān)層可以直接在外網(wǎng)上提供服務(wù)。
對于內(nèi)層的 HAProxy internal,由于我們當前還沒有實現(xiàn)服務(wù)治理,所以需要內(nèi)層的 HAProxy internal 進行一層轉(zhuǎn)發(fā);當實現(xiàn)了服務(wù)治理,可以消除內(nèi)層 HAProxy 代理,減少轉(zhuǎn)發(fā)消耗。
在我們當前的系統(tǒng)量級下,這兩層 HAProxy 轉(zhuǎn)發(fā)消耗非常小可以被接受,所以調(diào)整架構(gòu)的優(yōu)先級還不高,以后再慢慢演進。
3.2.2 接口網(wǎng)關(guān)
接下來這一節(jié)是最為重點的接口網(wǎng)關(guān)的設(shè)計。接口網(wǎng)關(guān)主要利用前文所述的 OpenResty 執(zhí)行階段對請求與響應(yīng)進行流程處理,包括接口地址的重寫,IP 與資源白名單的控制,請求的解密與驗簽,請求的路由以及響應(yīng)的簽名與加密等。
這里分成主流程,配置服務(wù),安全服務(wù)三部分進行講述。
3.2.2.1 主流程設(shè)計
主流程是網(wǎng)關(guān)的核心,是請求處理的控制中心;它是通過 OpenResty 的 Lua 腳本處理流程來實現(xiàn)對請求的處理。
A. 主流程
在 OpenResty 服務(wù)啟動之后,首先通過 init_by_lua_block 階段初始化常量(包括調(diào)用配置服務(wù)以及安全服務(wù)所需的主機地址、端口、URL 地址等)、引入依賴(包括常用的 http 以及 cjson 依賴等)等作為全局使用;
接著通過 init_worker_by_lua_file 階段設(shè)置定時任務(wù)調(diào)用內(nèi)網(wǎng)配置服務(wù)來緩存配置,為處理第三方的請求做準備,其中加載的配置可供 URL 重寫(即接口映射)、IP 以及資源(URI)白名單限制、請求的解密驗簽以及響應(yīng)的簽名加密使用,詳情查看配置服務(wù)一節(jié)。
當?shù)谌秸埱笸ㄟ^ HAProxy Internet 進入到網(wǎng)關(guān)后,根據(jù)配置通過 rewrite_by_lua_file 階段做 URL 重寫(即接口映射)。
服務(wù)接口 URL 發(fā)生變更,為了兼容舊的第三方調(diào)用,需要重寫第三方請求 URL 到新服務(wù)接口上
Restful 接口的 Path Variable 在 Nginx 環(huán)境與在 Tomcat 環(huán)境上正則匹配的差異
需要重寫的原因可能有:
URL 重寫后,通過 access_by_lua_file 進入訪問控制階段,此時根據(jù)授權(quán)的第三方 IP 白名單列表,授權(quán)予第三方的開放接口列表,校驗請求的 IP 以及 URL。
IP 與 URI 校驗通過后,同樣在 access_by_lua_file 階段根據(jù)配置調(diào)用內(nèi)網(wǎng)的安全服務(wù)進行請求的解密與驗簽,獲取明文。
在 content_by_lua_file 階段通過 ngx.location.capture 將原請求頭部信息以及參數(shù)等信息封裝到子請求中,借助子請求轉(zhuǎn)發(fā)原請求到開發(fā)接口服務(wù)中。
注意:根據(jù)官方文檔說明,ngx.location.capture 發(fā)送子請求會緩存響應(yīng)在內(nèi)存中,直到整個請求處理結(jié)束。那么,當有響應(yīng)報文特別長或者請求并發(fā)非常高時,需要使用 cosocket 來替代 ngx.location.capture,避免因內(nèi)存不足造成網(wǎng)關(guān)服務(wù)失效。
同樣在 content_by_lua_file 階段根據(jù)配置調(diào)用安全服務(wù)進行響應(yīng)的簽名與加密,獲取簽名與密文返回給第三方。
B. 文件結(jié)構(gòu)
項目的大致結(jié)構(gòu)如下,主要分為 Lua 代碼目錄和環(huán)境配置目錄。
--openapi
--lua
--access_by_lua.lua
--cache_management.lua
--content_by_lua.lua
--init_work_by_lua.lua
--rewrite_by_lua.lua
--security.lua
--prod
--Dockerfile
--nginx.conf
--sit
--Dockerfile
--nginx.conf
--README.md
C. 主流程在 conf 中的配置
# Nginx worker 進程個數(shù),直接影響性能。
# 如果確認不會出現(xiàn)阻塞式調(diào)用,那么有多少 CPU 內(nèi)核設(shè)置多少個進程
# 如果有可能出現(xiàn)阻塞式調(diào)用,需要配置多一些進程
worker_processes 1;
events {
worker_connections 1024;
}
http {
# 內(nèi)網(wǎng)地址
resolver xxx.x.x.xxx yyy.y.y.yyy;
# 日志格式配置
log_format graylog2_format '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'<msec=$msec|connection=$connection|connection_requests=$connection_requests|millis=$request_time>';
# 日志路徑配置
access_log syslog:server=<host>:<port> graylog2_format;
error_log syslog:server=<host>:<port> warn;
# 配置 Lua 包地址
lua_package_path '$prefix/lua/?.lua;;';
init_by_lua_block {
# 引入依賴(可能會污染全局環(huán)境,待研究)
http = require "resty.http"
cjson = require "cjson"
cache_management = require "cache_management"
...
}
# 設(shè)置定時任務(wù)緩存配置,及上面的 cache_management 模塊
init_worker_by_lua_file lua/init_work_by_lua.lua;
# Nginx Web 服務(wù)配置
server {
listen 80;
# ngx.location.capture 子請求代理,轉(zhuǎn)發(fā)原請求到接口服務(wù)
location = /ngx_proxy/ {
internal;
proxy_set_header Accept-Encoding '';
proxy_pass http://$context$http_host_suffix$proxy_uri;
}
# 匹配所有請求,進行 URL 重寫、訪問控制、轉(zhuǎn)發(fā)請求以及響應(yīng)處理(各階段的處理在此配置)。
location / {
set $context '';
...
rewrite_by_lua_file lua/rewrite_by_lua.lua;
access_by_lua_file lua/access_by_lua.lua;
content_by_lua_file lua/content_by_lua.lua;
}
}
}
D. URL 規(guī)范
內(nèi)網(wǎng)服務(wù)遵循的 URL 格式為 http://<host>:<port>/<context>/path/to/your/api,應(yīng)用上下文根緊跟在 <host>:<port>之后,以便統(tǒng)一獲取來找到配置。比如:http://172.0.8.177:8080/user/users/{uid}/info,其中 user 為應(yīng)用上下文根,緊跟在 172.0.8.177:8080 之后。
E. 樣例
內(nèi)網(wǎng)用戶信息服務(wù)由原來的 API:/user/users/{uid}/info 提供,后來遷移至 API:/user/users/{uid}/user-info,當?shù)谌?CampA (IP 為 172.0.1.172) 發(fā)起 GET 請求時,請求 URL 為 http://openapi.company.com/user/users/27/info?thirdparty=CampA&cp=fj375x...sign=abxuos8nb...。
初始化常量和依賴等
通過 CampA 與 user Context 獲取第三方配置
HAProxy Internet 接收請求發(fā)到 OpenApi 接口網(wǎng)關(guān),OpenApi 把 /user/users/27/info URI 重寫為 /user/users/27/user-info/
校驗第三方請求 IP,在 IP 白名單中,校驗通過;校驗 URI /user/users/27/user-info 在授權(quán)的 URI 中,校驗通過
調(diào)用安全服務(wù)對請求進行解密與驗簽,解密成功,驗簽通過,獲取明文
將擁有明文的請求轉(zhuǎn)發(fā)到開放接口服務(wù)
獲取響應(yīng),調(diào)用安全服務(wù)對響應(yīng)報文進行簽名與加密,返回給第三方 CampA。
3.2.2.2 配置服務(wù)設(shè)計
A. 數(shù)據(jù)庫表設(shè)計
openapi_thirdparty_config
id third_party need_check_ip ips req_need_verify_sign resp_need_sign
1 CompA 1 172.0.25.187, 172.0.25.188 1 1
openapi_api_config
id third_party method url req_need_decrypt resp_need_encrypt
1 CompA GET /user/users/[^/]+/userinfo 1 1
openapi_api_mapping
id from_api to_api
1 GET /old/1/user/users/(.+)/userinfo GET /users/$1/userinfo
B. 配置服務(wù)接口響應(yīng)
{
# 接口映射配置
"apiMapping":{
"$context":{
"$fromApi":"$toApi"
}
},
# 接口白名單配置、加解密配置
"apiConfig":{
"$channel $context":{
"$httpMethod $uri":{
"reqNeedDecrypt":false,
"respNeedEncrypt":false
}
}
},
# IP 白名單配置,驗簽名配置
"channelConfig":{
"$channel":{
ips:{
"$ip":1
},
"reqNeedVerifySign":false,
"respNeedSign":false,
"needCheckIp":false
}
}
}
3.2.2.3 安全服務(wù)設(shè)計
為了保證請求或響應(yīng)的完整性、以及請求或響應(yīng)來源的合法性,雙方傳輸需要進行簽名;另外,由于可能開放接口的請求或響應(yīng)會包含敏感信息,需要進行加密傳輸。這里的安全服務(wù)就是指請求的解密與驗簽和響應(yīng)的簽名與加密服務(wù)。
A. 算法約定
對稱加密算法:3DES(DESede/ECB/PKCS5Padding)
非對稱加密算法:RSA(RSA/ECB/PKCS1Padding)
簽名算法:SHA1WithRSA
B. 公鑰約定
雙方預(yù)先交換 RSA 公鑰
雙方公鑰編碼方式:UTF-8 編碼的 Base64String
雙方進行加解密與驗簽名可使用同一把 RSA 公私鑰或者分別使用各自的公私鑰,雙方約定即可
C. 第三方請求流程示意
其中,添加統(tǒng)一參數(shù)為必選步驟,請求簽名、請求加密、響應(yīng)解密、以及響應(yīng)驗簽都是可選步驟。
無論是 GET、POST 或者其他方式的請求,第三方在訪問平臺開放接口前,都需要添加統(tǒng)一參數(shù)到 request parameter 中
統(tǒng)一參數(shù)包括第三方應(yīng)用名、請求時間戳、隨機不重復(fù)字符串 nonce 等
驗簽名屬于應(yīng)用維度 —— 針對應(yīng)用做驗簽名(比如:按照約定需要對第三方應(yīng)用 A 進行驗簽,則應(yīng)用 A 訪問平臺任何接口都需要簽名)
加解密屬于接口維度 —— 針對接口做加解密(比如:同一個第三方訪問 A 接口需要加密,而訪問 B 接口可以不需加密)
D. 加解密示意(以第三方請求為例)
E. 驗簽名示意(以第三方請求為例)
3.2.3 架構(gòu)總結(jié)
由于 Nginx 與 Lua 本身杰出的性能,在當前的系統(tǒng)量級與整體 IT 架構(gòu)下,我們使用這樣的接口網(wǎng)關(guān)架構(gòu)已經(jīng)可以支撐較大的并發(fā)請求。在最后的這一節(jié),我們不妨回顧一下前文講述的接口網(wǎng)關(guān)架構(gòu),看看目前性能上仍存在著的兩個主要待改進的地方。
兩層 HAProxy 代理:在使用更優(yōu)產(chǎn)品替代 Openshift 架構(gòu)的情況下,直接部署接口網(wǎng)關(guān)到公網(wǎng),可消除外層 HAProxy 代理;在實現(xiàn)服務(wù)治理的情況下,由接口網(wǎng)關(guān)直接轉(zhuǎn)發(fā)請求到服務(wù),可消除內(nèi)層 HAProxy 代理。
安全服務(wù)性能:加解密驗簽名等安全服務(wù)是以內(nèi)部服務(wù)的方式提供給接口網(wǎng)關(guān),而且使用了性能不太好的 ngx.location.capture 轉(zhuǎn)發(fā)原請求,在系統(tǒng)量級增大后會遇到性能瓶頸,可通過使用高性能的 Lua 腳本在接口網(wǎng)關(guān)層提供安全服務(wù),從而提升安全服務(wù)性能。
除了以上主要的兩點,隨著系統(tǒng)量級的提升與整體 IT 架構(gòu)的演進,接口網(wǎng)關(guān)的架構(gòu)也會隨之調(diào)整和演進,在各個方面都盡可能地優(yōu)化性能,以適應(yīng)更大系統(tǒng)量級的需求。