為什么使用API-Gateway
- 方便客戶(hù)端維護(hù)– 每個(gè)請(qǐng)求方不用管理多個(gè)api url,統(tǒng)一訪(fǎng)問(wèn)api-gateway即可
- 接口重構(gòu)時(shí)調(diào)用方不須了解接口本身等拆分和聚合
- 客戶(hù)端無(wú)須關(guān)心接口協(xié)議
- 統(tǒng)一權(quán)限控制、接口請(qǐng)求訪(fǎng)問(wèn)日志統(tǒng)計(jì)
- 安全,是保護(hù)內(nèi)部服務(wù)而設(shè)計(jì)的一道屏障
- 開(kāi)源-最大好處
當(dāng)然也有一個(gè)很大的缺點(diǎn),api-gw很可能成為性能瓶頸,因?yàn)樗械恼?qǐng)求都經(jīng)過(guò)這里,可以通過(guò)橫向擴(kuò)展和限流解決這個(gè)問(wèn)題。
在眾多API GATEWAY框架中,Mashape開(kāi)源的高性能高可用API網(wǎng)關(guān)和API服務(wù)管理層——KONG(基于NGINX)特點(diǎn)尤為突出,它可以通過(guò)插件擴(kuò)展已有功能,這些插件(使用lua編寫(xiě))在A(yíng)PI請(qǐng)求響應(yīng)循環(huán)的生命周期中被執(zhí)行。于此同時(shí),KONG本身提供包括HTTP基本認(rèn)證、密鑰認(rèn)證、CORS、TCP、UDP、文件日志、API請(qǐng)求限流、請(qǐng)求轉(zhuǎn)發(fā)及NGINX監(jiān)控等基本功能。目前,Kong在Mashape管理了超過(guò)15,000個(gè)API,為200,000開(kāi)發(fā)者提供了每月數(shù)十億的請(qǐng)求支持。
Kong是一款基于Nginx_Lua模塊寫(xiě)的高可用,由于Kong是基于Nginx的,所以可以水平擴(kuò)展多個(gè)Kong服務(wù)器,通過(guò)前置的負(fù)載均衡配置把請(qǐng)求均勻地分發(fā)到各個(gè)Server,來(lái)應(yīng)對(duì)大批量的網(wǎng)絡(luò)請(qǐng)求。
kong架構(gòu)
Kong主要有三個(gè)組件:
Kong Server :基于nginx的服務(wù)器,用來(lái)接收API請(qǐng)求。 Apache Cassandra/PostgreSQL :用來(lái)存儲(chǔ)操作數(shù)據(jù)。 Kong dashboard:官方推薦UI管理工具,當(dāng)然,也可以使用 restfull 方式 管理admin api。
Kong采用插件機(jī)制進(jìn)行功能定制,插件集(可以是0或N個(gè))在A(yíng)PI請(qǐng)求響應(yīng)循環(huán)的生命周期中被執(zhí)行。插件使用Lua編寫(xiě),目前已有幾個(gè)基礎(chǔ)功能:HTTP基本認(rèn)證、密鑰認(rèn)證、CORS(Cross-Origin Resource Sharing,跨域資源共享)、TCP、UDP、文件日志、API請(qǐng)求限流、請(qǐng)求轉(zhuǎn)發(fā)以及Nginx監(jiān)控。
Kong網(wǎng)關(guān)的特性
Kong網(wǎng)關(guān)具有以下的特性:
可擴(kuò)展性: 通過(guò)簡(jiǎn)單地添加更多的服務(wù)器,可以輕松地進(jìn)行橫向擴(kuò)展,這意味著您的平臺(tái)可以在一個(gè)較低負(fù)載的情況下處理任何請(qǐng)求; 模塊化: 可以通過(guò)添加新的插件進(jìn)行擴(kuò)展,這些插件可以通過(guò)RESTful Admin API輕松配置; 在任何基礎(chǔ)架構(gòu)上運(yùn)行: Kong網(wǎng)關(guān)可以在任何地方都能運(yùn)行。您可以在云或內(nèi)部網(wǎng)絡(luò)環(huán)境中部署Kong,包括單個(gè)或多個(gè)數(shù)據(jù)中心設(shè)置,以及public,private 或invite-only APIs。
Kong核心基于OpenResty構(gòu)建,實(shí)現(xiàn)了請(qǐng)求/響應(yīng)的Lua處理化; Kong插件攔截請(qǐng)求/響應(yīng),如果接觸過(guò)Java Servlet,等價(jià)于攔截器,實(shí)現(xiàn)請(qǐng)求/響應(yīng)的AOP處理; Kong Restful 管理API提供了API/API消費(fèi)者/插件的管理; 數(shù)據(jù)中心用于存儲(chǔ)Kong集群節(jié)點(diǎn)信息、API、消費(fèi)者、插件等信息,目前提供了PostgreSQL和Cassandra支持,如果需要高可用建議使用Cassandra; Kong集群中的節(jié)點(diǎn)通過(guò)gossip協(xié)議自動(dòng)發(fā)現(xiàn)其他節(jié)點(diǎn),當(dāng)通過(guò)一個(gè)Kong節(jié)點(diǎn)的管理API進(jìn)行一些變更時(shí)也會(huì)通知其他節(jié)點(diǎn)。每個(gè)Kong節(jié)點(diǎn)的配置信息是會(huì)緩存的,如插件,那么當(dāng)在某一個(gè)Kong節(jié)點(diǎn)修改了插件配置時(shí),需要通知其他節(jié)點(diǎn)配置的變更。
Kong網(wǎng)關(guān)插件
身份認(rèn)證插件:Kong提供了Basic Authentication、Key authentication、OAuth2.0 authentication、HMAC authentication、JWT、LDAP authentication認(rèn)證實(shí)現(xiàn)。 安全控制插件:ACL(訪(fǎng)問(wèn)控制)、CORS(跨域資源共享)、動(dòng)態(tài)SSL、IP限制、爬蟲(chóng)檢測(cè)實(shí)現(xiàn)。 流量控制插件:請(qǐng)求限流(基于請(qǐng)求計(jì)數(shù)限流)、上游響應(yīng)限流(根據(jù)upstream響應(yīng)計(jì)數(shù)限流)、請(qǐng)求大小限制。限流支持本地、Redis和集群限流模式。 分析監(jiān)控插件:Galileo(記錄請(qǐng)求和響應(yīng)數(shù)據(jù),實(shí)現(xiàn)API分析)、Datadog(記錄API Metric如請(qǐng)求次數(shù)、請(qǐng)求大小、響應(yīng)狀態(tài)和延遲,可視化API Metric)、Runscope(記錄請(qǐng)求和響應(yīng)數(shù)據(jù),實(shí)現(xiàn)API性能測(cè)試和監(jiān)控)。 協(xié)議轉(zhuǎn)換插件:請(qǐng)求轉(zhuǎn)換(在轉(zhuǎn)發(fā)到upstream之前修改請(qǐng)求)、響應(yīng)轉(zhuǎn)換(在upstream響應(yīng)返回給客戶(hù)端之前修改響應(yīng))。 日志應(yīng)用插件:TCP、UDP、HTTP、File、Syslog、StatsD、Loggly等。
Kong網(wǎng)關(guān)請(qǐng)求流程
為了更好地理解系統(tǒng),這是使用Kong網(wǎng)關(guān)的API接口的典型請(qǐng)求工作流程:
請(qǐng)求流程
當(dāng)Kong運(yùn)行時(shí),每個(gè)對(duì)API的請(qǐng)求將先被Kong命中,然后這個(gè)請(qǐng)求將會(huì)被代理轉(zhuǎn)發(fā)到最終的API接口。在請(qǐng)求(Requests)和響應(yīng)(Responses)之間,Kong將會(huì)執(zhí)行已經(jīng)事先安裝和配置好的任何插件,授權(quán)您的API訪(fǎng)問(wèn)操作。Kong是每個(gè)API請(qǐng)求的入口點(diǎn)(Endpoint)。
helm 安裝
先創(chuàng)建pv
apiVersion: v1
metadata:
name: kong-postgre
labels:
release: stable
spec:
capacity:
storage: 8Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
hostPath:
path: /data/pv/kong/postgre
使用helm安裝kong
再創(chuàng)建kong-dashboard
kind: Deployment
metadata:
name: kong-dashboard-deployment
spec:
selector:
matchLabels:
app: kong-dashboard-pod
version: v1.0.0
replicas: 1
template:
metadata:
labels:
app: kong-dashboard-pod
version: v1.0.0
spec:
volumes:
- name: tz-config
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
containers:
- name: kong-dashboard-container
image: pgbi/kong-dashboard
ports:
- containerPort: 8080
args:
- 'start'
- '--kong-url'
- 'http://my-kong-kong-admin:8444'
- '--insecure'
# - '--basic-auth'
# - 'intellif=introcks'
# command: ['sleep','30000']
volumeMounts:
- name: tz-config
mountPath: /etc/localtime
---
apiVersion: v1
kind: Service
metadata:
name: kong-dashboard-service
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
protocol: TCP
nodePort: 31500
name: http-kong-dashboard
selector:
app: kong-dashboard-pod
version: v1.0.0
默認(rèn)情況下,KONG監(jiān)聽(tīng)的端口為:
· 8000:此端口是KONG用來(lái)監(jiān)聽(tīng)來(lái)自客戶(hù)端傳入的HTTP請(qǐng)求,并將此請(qǐng)求轉(zhuǎn)發(fā)到上有服務(wù)器;
· 8443:有的地方使用8443代替8000, 此端口是KONG用來(lái)監(jiān)聽(tīng)來(lái)自客戶(hù)端傳入的HTTP請(qǐng)求的。它跟8000端口的功能類(lèi)似,但是它只是用來(lái)監(jiān)聽(tīng)HTTP請(qǐng)求的,沒(méi)有轉(zhuǎn)發(fā)功能??梢酝ㄟ^(guò)修改配置文件來(lái)禁止它;
· 8001:Admin API,通過(guò)此端口,管理者可以對(duì)KONG的監(jiān)聽(tīng)服務(wù)進(jìn)行配置;
· 8444:有的地方使用8444代替8001,通過(guò)此端口,管理者可以對(duì)HTTP請(qǐng)求進(jìn)行監(jiān)控.
如果不想使用postgre數(shù)據(jù)庫(kù),可以自己進(jìn)入容器配置,或者將配置文件通過(guò)configmap掛載進(jìn)去
/config/local_example.js
# 拷貝一份
cd ./config/
cp local_example.js ./local.js
# 配置默認(rèn)數(shù)據(jù)庫(kù)
vi ./local.js
models: {
connection: process.env.DB_ADAPTER || 'localDiskDb',
},
# 改成
models: {
connection: process.env.DB_ADAPTER || 'mysql', // 這里可以用‘mysql’,‘mongo’,‘sqlserver’,‘postgres’
},
# 保存
# 修改數(shù)據(jù)庫(kù)默認(rèn)配置
vi connections.js
mysql: {
adapter: 'sails-mysql',
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || null,
database: process.env.DB_DATABASE || 'konga_database'
},
# 改成
mysql: {
adapter: 'sails-mysql',
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || 'root',
database: process.env.DB_DATABASE || 'konga_database'
},
# 保存
# 創(chuàng)建數(shù)據(jù)庫(kù)
mysql -uroot -proot // 這里不建議用明文密碼
CREATE DATABASE konga_database CHARACTER SET utf8 COLLATE utf8_general_ci;
向kong中配置一個(gè)服務(wù)
在這一節(jié),你會(huì)添加一個(gè)API到Kong.為了達(dá)到這個(gè)目的,首先你需要添加一個(gè)服務(wù)(Service),這是Kong用來(lái)指定它管理的上游Api和微服務(wù)的名稱(chēng)。
為了達(dá)成目標(biāo),我們將會(huì)創(chuàng)建一個(gè)Service指向Mockbin API,MockBin是一個(gè)”回顯”類(lèi)型的公共網(wǎng)站,它返回請(qǐng)求者的請(qǐng)求,作為響應(yīng)。這非常有助于我們學(xué)習(xí)Kong如何代理你的API請(qǐng)求。
在你開(kāi)始請(qǐng)求Service之前,你需要先添加一個(gè)Route。Route定義了請(qǐng)求在到達(dá)Kong以后如何發(fā)送到他們的Service.一個(gè)Service可以有多個(gè)Route.
在配置完Service和Route以后,你就可以通過(guò)Kong使用他們發(fā)送請(qǐng)求啦。
Kong暴露了一個(gè)RESTful管理Api在8001端口上,Kong的配置,包括添加Service和Route,都是通過(guò)這個(gè)Api發(fā)送請(qǐng)求.
- 使用管理Api添加你的Service
執(zhí)行以下cURL請(qǐng)求,添加你的第一個(gè)Service(指向Mockbin API):
--url http://localhost:8001/services/
--data 'name=example-service'
--data 'url=http://mockbin.org'
為服務(wù)添加一個(gè)路由
--url http://localhost:8001/services/example-service/routes
--data 'hosts[]=example.com'
通過(guò)Kong轉(zhuǎn)發(fā)你的請(qǐng)求
執(zhí)行下面的cURL請(qǐng)求,驗(yàn)證Kong是否正確轉(zhuǎn)發(fā)到你的Service. 注意,默認(rèn)情況下,Kong在8000端口處理代理請(qǐng)求.
--url http://localhost:8000/
--header 'Host: example.com'
成功響應(yīng)意味著現(xiàn)在Kong已經(jīng)將http://localhost:8000轉(zhuǎn)發(fā)到我們?cè)诘谝徊街信涞膗rl上,并且將響應(yīng)轉(zhuǎn)發(fā)給我們。Kong之所以知道這么干,是通過(guò)在cURL請(qǐng)求里定義的Header:
啟動(dòng)插件
下面的步驟中,你會(huì)配置key-auth插件,為你的Service添加認(rèn)證功能。在添加這個(gè)插件之前,你的Service所有的請(qǐng)求都會(huì)代理到上游。一旦你添加配置了這個(gè)插件,只有帶正確的API key的請(qǐng)求會(huì)被代理,其他的請(qǐng)求會(huì)被Kong拒絕,從而保護(hù)你的上游服務(wù)免于未授權(quán)調(diào)用。
- 配置key-auth插件
為你在Kong中配置的服務(wù)配置key-auth插件,執(zhí)行以下cURL請(qǐng)求 執(zhí)行以下cURL請(qǐng)求,添加你的第一個(gè)Service(指向Mockbin API):
--url http://localhost:8001/services/example-service/plugins/
--data 'name=key-auth'
注意:這個(gè)插件同時(shí)接受config.key_names參數(shù),默認(rèn)值是[‘a(chǎn)piKey’]這是一個(gè)header參數(shù)名數(shù)組,用于在請(qǐng)求時(shí)發(fā)送apiKey,任意一個(gè)都支持.
- 驗(yàn)證插件是否正確配置 執(zhí)行以下的cURL請(qǐng)求,驗(yàn)證key-auth插件是否在Service上正確配置:
你會(huì)收到一個(gè)類(lèi)似下面的響應(yīng):
--url http://localhost:8000/
--header 'Host: example.com'
由于你沒(méi)有在header或參數(shù)里添加指定需要的apiKey,響應(yīng)應(yīng)該是401 Unauthorized
...
{
"message": "No API key found in request"
}
添加信任用戶(hù)Consumer
通過(guò)RESTful API創(chuàng)建一個(gè)Consumer
執(zhí)行下面的命令,創(chuàng)建一個(gè)叫Jason的用戶(hù)
--url http://localhost:8001/consumers/
--data "username=Jason"
響應(yīng)大致如下:
Content-Type: application/json
Connection: keep-alive
{
"username": "Jason",
"created_at": 1428555626000,
"id": "bbdf1c48-19dc-4ab7-cae0-ff4f59d87dc9"
}
恭喜,你剛添加了第一個(gè)Consumer
提示 Kong同時(shí)接受custom_id參數(shù),關(guān)聯(lián)到庫(kù)中已存在的Consumer
為Consumer發(fā)放憑證
給剛創(chuàng)建的用戶(hù)Jason創(chuàng)建 一個(gè)key
--url http://localhost:8001/consumers/Jason/key-auth/
--data 'key=ENTER_KEY_HERE'
驗(yàn)證你的Consumer憑證有效
現(xiàn)在,我們可以執(zhí)行下面的命令,驗(yàn)證剛剛給Jason發(fā)放的憑證是否有效.
--url http://localhost:8000
--header "Host: example.com"
--header "apikey: ENTER_KEY_HERE"
-
服務(wù)器
+關(guān)注
關(guān)注
12文章
8700瀏覽量
84528 -
API
+關(guān)注
關(guān)注
2文章
1461瀏覽量
61488 -
教程
+關(guān)注
關(guān)注
25文章
265瀏覽量
54077 -
日志
+關(guān)注
關(guān)注
0文章
129瀏覽量
10593
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論