日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
開(kāi)源API網(wǎng)關(guān),到底哪個(gè)強(qiáng)?

我今天就在和大家探討一下 API Gateway。在微服務(wù)的架構(gòu)下,API 網(wǎng)關(guān)是一個(gè)常見(jiàn)的架構(gòu)設(shè)計(jì)模式。

目前創(chuàng)新互聯(lián)已為近1000家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機(jī)、網(wǎng)站托管運(yùn)營(yíng)、企業(yè)網(wǎng)站設(shè)計(jì)、關(guān)嶺網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶(hù)導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶(hù)和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。

以下是微服務(wù)中常見(jiàn)的問(wèn)題,需要引入 API 網(wǎng)關(guān)來(lái)協(xié)助解決:

  • 微服務(wù)提供的 API 的粒度通常與客戶(hù)端所需的粒度不同。微服務(wù)通常提供細(xì)粒度的 API,這意味著客戶(hù)端需要與多個(gè)服務(wù)進(jìn)行交互。例如,如上所述,需要產(chǎn)品詳細(xì)信息的客戶(hù)需要從眾多服務(wù)中獲取數(shù)據(jù)。
  • 不同的客戶(hù)端需要不同的數(shù)據(jù)。例如,產(chǎn)品詳細(xì)信息頁(yè)面桌面的桌面瀏覽器版本通常比移動(dòng)版本更為詳盡。
  • 對(duì)于不同類(lèi)型的客戶(hù)端,網(wǎng)絡(luò)性能是不同的。例如,與非移動(dòng)網(wǎng)絡(luò)相比,移動(dòng)網(wǎng)絡(luò)通常要慢得多并且具有更高的延遲。而且,當(dāng)然,任何 WAN 都比 LAN 慢得多。
  • 這意味著本機(jī)移動(dòng)客戶(hù)端使用的網(wǎng)絡(luò)性能與服務(wù)器端 Web 應(yīng)用程序使用的 LAN 的性能差異很大。服務(wù)器端 Web 應(yīng)用程序可以向后端服務(wù)發(fā)出多個(gè)請(qǐng)求,而不會(huì)影響用戶(hù)體驗(yàn),而移動(dòng)客戶(hù)端只能提供幾個(gè)請(qǐng)求。
  • 微服務(wù)實(shí)例數(shù)量及其位置(主機(jī)+端口)動(dòng)態(tài)變化。
  • 服務(wù)劃分會(huì)隨著時(shí)間的推移而變化,應(yīng)該對(duì)客戶(hù)端隱藏。
  • 服務(wù)可能會(huì)使用多種協(xié)議,其中一些協(xié)議可能對(duì)網(wǎng)絡(luò)不友好。

常見(jiàn)的API網(wǎng)關(guān)主要提供以下的功能:

  • 反向代理和路由:大多數(shù)項(xiàng)目采用網(wǎng)關(guān)的解決方案的最主要的原因。給出了訪問(wèn)后端 API 的所有客戶(hù)端的單一入口,并隱藏內(nèi)部服務(wù)部署的細(xì)節(jié)。
  • 負(fù)載均衡:網(wǎng)關(guān)可以將單個(gè)傳入的請(qǐng)求路由到多個(gè)后端目的地。
  • 身份驗(yàn)證和授權(quán):網(wǎng)關(guān)應(yīng)該能夠成功進(jìn)行身份驗(yàn)證并僅允許可信客戶(hù)端訪問(wèn) API,并且還能夠使用類(lèi)似 RBAC 等方式來(lái)授權(quán)。
  • IP 列表白名單/黑名單:允許或阻止某些 IP 地址通過(guò)。
  • 性能分析:提供一種記錄與 API 調(diào)用相關(guān)的使用和其他有用度量的方法。
  • 限速和流控:控制 API 調(diào)用的能力。
  • 請(qǐng)求變形:在進(jìn)一步轉(zhuǎn)發(fā)之前,能夠在轉(zhuǎn)發(fā)之前轉(zhuǎn)換請(qǐng)求和響應(yīng)(包括 Header 和 Body)。
  • 版本控制:同時(shí)使用不同版本的 API 選項(xiàng)或可能以金絲雀發(fā)布或藍(lán)/綠部署的形式提供慢速推出 API。
  • 斷路器:微服務(wù)架構(gòu)模式有用,以避免使用中斷。
  • 多協(xié)議支持:WebSocket/GRPC。
  • 緩存:減少網(wǎng)絡(luò)帶寬和往返時(shí)間消耗,如果可以緩存頻繁要求的數(shù)據(jù),則可以提高性能和響應(yīng)時(shí)間
  • API 文檔:如果計(jì)劃將 API 暴露給組織以外的開(kāi)發(fā)人員,那么必須考慮使用 API 文檔,例如 Swagger 或 OpenAPI。

有很多的開(kāi)源軟件可以提供 API 網(wǎng)關(guān)的支持,下面我們就看看他們各自的架構(gòu)和功能。

為了對(duì)這些開(kāi)源網(wǎng)關(guān)進(jìn)行基本功能的驗(yàn)證,我創(chuàng)建了一些代碼,使用 OpenAPI 生成了四個(gè)基本的 API 服務(wù),包含 Golang,Nodejs,Python Flask 和 Java Spring。

API 使用了常見(jiàn)的寵物商店的樣例,聲明如下:

 
 
 
 
  1. openapi: "3.0.0"
  2. info:
  3.   version: 1.0.0
  4.   title: Swagger Petstore
  5.   license:
  6.     name: MIT
  7. servers:
  8.   - url: http://petstore.swagger.io/v1
  9. paths:
  10.   /pets:
  11.     get:
  12.       summary: List all pets
  13.       operationId: listPets
  14.       tags:
  15.         - pets
  16.       parameters:
  17.         - name: limit
  18.           in: query
  19.           description: How many items to return at one time (max 100)
  20.           required: false
  21.           schema:
  22.             type: integer
  23.             format: int32
  24.       responses:
  25.         '200':
  26.           description: A paged array of pets
  27.           headers:
  28.             x-next:
  29.               description: A link to the next page of responses
  30.               schema:
  31.                 type: string
  32.           content:
  33.             application/json:    
  34.               schema:
  35.                 $ref: "#/components/schemas/Pets"
  36.         default:
  37.           description: unexpected error
  38.           content:
  39.             application/json:
  40.               schema:
  41.                 $ref: "#/components/schemas/Error"
  42.     post:
  43.       summary: Create a pet
  44.       operationId: createPets
  45.       tags:
  46.         - pets
  47.       responses:
  48.         '201':
  49.           description: Null response
  50.         default:
  51.           description: unexpected error
  52.           content:
  53.             application/json:
  54.               schema:
  55.                 $ref: "#/components/schemas/Error"
  56.   /pets/{petId}:
  57.     get:
  58.       summary: Info for a specific pet
  59.       operationId: showPetById
  60.       tags:
  61.         - pets
  62.       parameters:
  63.         - name: petId
  64.           in: path
  65.           required: true
  66.           description: The id of the pet to retrieve
  67.           schema:
  68.             type: string
  69.       responses:
  70.         '200':
  71.           description: Expected response to a valid request
  72.           content:
  73.             application/json:
  74.               schema:
  75.                 $ref: "#/components/schemas/Pet"
  76.         default:
  77.           description: unexpected error
  78.           content:
  79.             application/json:
  80.               schema:
  81.                 $ref: "#/components/schemas/Error"
  82. components:
  83.   schemas:
  84.     Pet:
  85.       type: object
  86.       required:
  87.         - id
  88.         - name
  89.       properties:
  90.         id:
  91.           type: integer
  92.           format: int64
  93.         name:
  94.           type: string
  95.         tag:
  96.           type: string
  97.     Pets:
  98.       type: array
  99.       items:
  100.         $ref: "#/components/schemas/Pet"
  101.     Error:
  102.       type: object
  103.       required:
  104.         - code
  105.         - message
  106.       properties:
  107.         code:
  108.           type: integer
  109.           format: int32
  110.         message:
  111.           type: string

構(gòu)建好的 Web 服務(wù)通過(guò) Docker Compose 來(lái)進(jìn)行容器化的部署。

 
 
 
 
  1. version: "3.7"
  2. services:
  3.   goapi:
  4.     container_name: goapi
  5.     image: naughtytao/goapi:0.1
  6.     ports:
  7.       - "18000:8080"
  8.     deploy:
  9.       resources:
  10.         limits:
  11.           cpus: '1'
  12.           memory: 256M
  13.         reservations:
  14.           memory: 256M
  15.   nodeapi:
  16.     container_name: nodeapi
  17.     image: naughtytao/nodeapi:0.1
  18.     ports:
  19.       - "18001:8080"
  20.     deploy:
  21.       resources:
  22.         limits:
  23.           cpus: '1'
  24.           memory: 256M
  25.         reservations:
  26.           memory: 256M
  27.   flaskapi:
  28.     container_name: flaskapi
  29.     image: naughtytao/flaskapi:0.1
  30.     ports:
  31.       - "18002:8080"
  32.     deploy:
  33.       resources:
  34.         limits:
  35.           cpus: '1'
  36.           memory: 256M
  37.         reservations:
  38.           memory: 256M
  39.   springapi:
  40.     container_name: springapi
  41.     image: naughtytao/springapi:0.1
  42.     ports:
  43.       - "18003:8080"
  44.     deploy:
  45.       resources:
  46.         limits:
  47.           cpus: '1'
  48.           memory: 256M
  49.         reservations:
  50.           memory: 256M

我們?cè)趯W(xué)習(xí)這些開(kāi)源網(wǎng)關(guān)架構(gòu)的同時(shí),也會(huì)對(duì)其最基本的路由轉(zhuǎn)發(fā)功能作出驗(yàn)證。

這里用戶(hù)發(fā)送的請(qǐng)求 server/service_name/v1/ 會(huì)發(fā)送給 API 網(wǎng)關(guān),網(wǎng)關(guān)通過(guò) service name 來(lái)路由到不同的后端服務(wù)。

我們使用 K6 用 100 個(gè)并發(fā)跑 1000 次測(cè)試的結(jié)果如上圖,我們看到直連的綜合響應(yīng),每秒可以處理的請(qǐng)求數(shù)量大概是 1100+。

Nginx

Nginx 是異步框架的網(wǎng)頁(yè)服務(wù)器,也可以用作反向代理、負(fù)載平衡器和 HTTP 緩存。

該軟件由伊戈?duì)枴べ愃饕騽?chuàng)建并于 2004 年首次公開(kāi)發(fā)布。2011 年成立同名公司以提供支持。2019 年 3 月 11 日,Nginx 公司被 F5 Networks 以 6.7 億美元收購(gòu)。

Nginx 有以下的特點(diǎn):

  • 由 C 編寫(xiě),占用的資源和內(nèi)存低,性能高。
  • 單進(jìn)程多線程,當(dāng)啟動(dòng) Nginx 服務(wù)器,會(huì)生成一個(gè) master 進(jìn)程,master 進(jìn)程會(huì) fork 出多個(gè) worker 進(jìn)程,由 worker 線程處理客戶(hù)端的請(qǐng)求。
  • 支持反向代理,支持 7 層負(fù)載均衡(拓展負(fù)載均衡的好處)。
  • 高并發(fā),Nginx 是異步非阻塞型處理請(qǐng)求,采用的 epollandqueue 模式。
  • 處理靜態(tài)文件速度快。
  • 高度模塊化,配置簡(jiǎn)單。社區(qū)活躍,各種高性能模塊出品迅速。

如上圖所示,Nginx 主要由 Master,Worker 和 Proxy Cache 三個(gè)部分組成。

Master 主控:NGINX 遵循主從架構(gòu)。它將根據(jù)客戶(hù)的要求為 Worker 分配工作。

將工作分配給 Worker 后,Master 將尋找客戶(hù)的下一個(gè)請(qǐng)求,因?yàn)樗粫?huì)等待 Worker 的響應(yīng)。一旦響應(yīng)來(lái)自 Worker,Master 就會(huì)將響應(yīng)發(fā)送給客戶(hù)端。

Worker 工作單元:Worker 是 NGINX 架構(gòu)中的 Slave。每個(gè)工作單元可以單線程方式一次處理 1000 個(gè)以上的請(qǐng)求。

一旦處理完成,響應(yīng)將被發(fā)送到主服務(wù)器。單線程將通過(guò)在相同的內(nèi)存空間而不是不同的內(nèi)存空間上工作來(lái)節(jié)省 RAM 和 ROM 的大小。多線程將在不同的內(nèi)存空間上工作。

Cache 緩存:Nginx 緩存用于通過(guò)從緩存而不是從服務(wù)器獲取來(lái)非??焖俚爻尸F(xiàn)頁(yè)面。在第一個(gè)頁(yè)面請(qǐng)求時(shí),頁(yè)面將被存儲(chǔ)在高速緩存中。

為了實(shí)現(xiàn) API 的路由轉(zhuǎn)發(fā),需要只需要對(duì) Nginx 作出如下的配置:

 
 
 
 
  1. server {
  2.     listen 80 default_server; 
  3.     location /goapi {
  4.         rewrite ^/goapi(.*) $1 break;
  5.         proxy_pass  http://goapi:8080;
  6.     }
  7.     location /nodeapi {
  8.         rewrite ^/nodeapi(.*) $1 break;
  9.         proxy_pass  http://nodeapi:8080;
  10.     }
  11.     location /flaskapi {
  12.         rewrite ^/flaskapi(.*) $1 break;
  13.         proxy_pass  http://flaskapi:8080;
  14.     }
  15.     location /springapi {
  16.         rewrite ^/springapi(.*) $1 break;
  17.         proxy_pass  http://springapi:8080;
  18.     }
  19. }

我們基于不同的服務(wù) goapi,nodeapi,flaskapi 和 springapi,分別配置一條路由,在轉(zhuǎn)發(fā)之前,需要利用 rewrite 來(lái)去掉服務(wù)名,并發(fā)送給對(duì)應(yīng)的服務(wù)。

使用容器把 Nginx 和后端的四個(gè)服務(wù)部署在同一個(gè)網(wǎng)絡(luò)下,通過(guò)網(wǎng)關(guān)連接路由轉(zhuǎn)發(fā)的。

Nginx 的部署如下:

 
 
 
 
  1. version: "3.7"
  2. services:
  3.   web:
  4.     container_name: nginx
  5.     image: nginx
  6.     volumes:
  7.       - ./templates:/etc/nginx/templates
  8.       - ./conf/default.conf:/etc/nginx/conf.d/default.conf
  9.     ports:
  10.       - "8080:80"
  11.     environment:
  12.       - NGINX_HOST=localhost
  13.       - NGINX_PORT=80
  14.     deploy:
  15.       resources:
  16.         limits:
  17.           cpus: '1'
  18.           memory: 256M
  19.         reservations:
  20.           memory: 256M

K6 通過(guò) Nginx 網(wǎng)關(guān)的測(cè)試結(jié)果如下:

每秒處理的請(qǐng)求數(shù)量是 1093,和不通過(guò)網(wǎng)關(guān)轉(zhuǎn)發(fā)相比非常接近。

從功能上看,Nginx 可以滿(mǎn)足用戶(hù)對(duì)于 API 網(wǎng)關(guān)的大部分需求,可以通過(guò)配置和插件的方式來(lái)支持不同的功能,性能非常優(yōu)秀。

缺點(diǎn)是沒(méi)有管理的 UI 和管理 API,大部分的工作都需要手工配置 config 文件的方式來(lái)進(jìn)行。商業(yè)版本的功能會(huì)更加完善。

Kong

Kong 是基于 NGINX 和 OpenResty 的開(kāi)源 API 網(wǎng)關(guān)。

Kong 的總體基礎(chǔ)結(jié)構(gòu)由三個(gè)主要部分組成:NGINX 提供協(xié)議實(shí)現(xiàn)和工作進(jìn)程管理,OpenResty 提供 Lua 集成并掛鉤到 NGINX 的請(qǐng)求處理階段。

而 Kong 本身利用這些掛鉤來(lái)路由和轉(zhuǎn)換請(qǐng)求。數(shù)據(jù)庫(kù)支持 Cassandra 或 Postgres 存儲(chǔ)所有配置。

Kong 附帶各種插件,提供訪問(wèn)控制,安全性,緩存和文檔等功能。它還允許使用 Lua 語(yǔ)言編寫(xiě)和使用自定義插件。

Kong 也可以部署為 Kubernetes Ingress 并支持 GRPC 和 WebSockets 代理。

NGINX 提供了強(qiáng)大的 HTTP 服務(wù)器基礎(chǔ)結(jié)構(gòu)。它處理 HTTP 請(qǐng)求處理,TLS 加密,請(qǐng)求日志記錄和操作系統(tǒng)資源分配(例如,偵聽(tīng)和管理客戶(hù)端連接以及產(chǎn)生新進(jìn)程)。

NGINX 具有一個(gè)聲明性配置文件,該文件位于其主機(jī)操作系統(tǒng)的文件系統(tǒng)中。

雖然僅通過(guò) NGINX 配置就可以實(shí)現(xiàn)某些 Kong 功能(例如,基于請(qǐng)求的 URL 確定上游請(qǐng)求路由),但修改該配置需要一定級(jí)別的操作系統(tǒng)訪問(wèn)權(quán)限,以編輯配置文件并要求 NGINX 重新加載它們。

而 Kong 允許用戶(hù)執(zhí)行以下操作:通過(guò) RESTful HTTP API 更新配置。Kong 的 NGINX 配置是相當(dāng)基本的:除了配置標(biāo)準(zhǔn)標(biāo)頭,偵聽(tīng)端口和日志路徑外,大多數(shù)配置都委托給 OpenResty。

在某些情況下,在 Kong 的旁邊添加自己的 NGINX 配置非常有用,例如在 API 網(wǎng)關(guān)旁邊提供靜態(tài)網(wǎng)站。在這種情況下,您可以修改 Kong 使用的配置模板。

NGINX 處理的請(qǐng)求經(jīng)過(guò)一系列階段。NGINX 的許多功能(例如,使用 C 語(yǔ)言編寫(xiě)的模塊)都提供了進(jìn)入這些階段的功能(例如,使用 gzip 壓縮的功能)。

雖然可以編寫(xiě)自己的模塊,但是每次添加或更新模塊時(shí)都必須重新編譯 NGINX。為了簡(jiǎn)化添加新功能的過(guò)程,Kong 使用了 OpenResty。

OpenResty 是一個(gè)軟件套件,捆綁了 NGINX,一組模塊,LuaJIT 和一組 Lua 庫(kù)。

其中最主要的是 ngx_http_lua_module一個(gè)NGINX 模塊,該模塊嵌入 Lua 并為大多數(shù) NGINX 請(qǐng)求階段提供 Lua 等效項(xiàng)。

這有效地允許在 Lua 中開(kāi)發(fā) NGINX 模塊,同時(shí)保持高性能(LuaJIT 相當(dāng)快),并且 Kong 用它來(lái)提供其核心配置管理和插件管理基礎(chǔ)結(jié)構(gòu)。

Kong 通過(guò)其插件體系結(jié)構(gòu)提供了一個(gè)框架,可以掛接到上述請(qǐng)求階段。從上面的示例開(kāi)始,Key Auth 和 ACL 插件都控制客戶(hù)端(也稱(chēng)為使用者)是否應(yīng)該能夠發(fā)出請(qǐng)求。

每個(gè)插件都在其處理程序中定義了自己的訪問(wèn)函數(shù),并且該函數(shù)針對(duì)通過(guò)給定路由或服務(wù)啟用的每個(gè)插件執(zhí)行 kong.access()。

執(zhí)行順序由優(yōu)先級(jí)值決定,如果 Key Auth 的優(yōu)先級(jí)為 1003,ACL 的優(yōu)先級(jí)為 950,則 Kong 將首先執(zhí)行 Key Auth 的訪問(wèn)功能,如果它不放棄請(qǐng)求,則將執(zhí)行 ACL,然后再通過(guò)將該 ACL 傳遞給上游 proxy_pass。

由于 Kong 的請(qǐng)求路由和處理配置是通過(guò)其 admin API 控制的,因此可以在不編輯底層 NGINX 配置的情況下即時(shí)添加和刪除插件配置。

因?yàn)?Kong 本質(zhì)上提供了一種在 API 中注入位置塊(通過(guò) API 定義)和配置的方法。它們通過(guò)將插件,證書(shū)等分配給這些 API。

我們使用以下的配置部署 Kong 到容器中(省略四個(gè)微服務(wù)的部署):

 
 
 
 
  1. version: '3.7'
  2. volumes:
  3.   kong_data: {}
  4. networks:
  5.   kong-net:
  6.     external: false
  7. services:
  8.   kong:
  9.     image: "${KONG_DOCKER_TAG:-kong:latest}"
  10.     user: "${KONG_USER:-kong}"
  11.     depends_on:
  12.       - db
  13.     environment:
  14.       KONG_ADMIN_ACCESS_LOG: /dev/stdout
  15.       KONG_ADMIN_ERROR_LOG: /dev/stderr
  16.       KONG_ADMIN_LISTEN: '0.0.0.0:8001'
  17.       KONG_CASSANDRA_CONTACT_POINTS: db
  18.       KONG_DATABASE: postgres
  19.       KONG_PG_DATABASE: ${KONG_PG_DATABASE:-kong}
  20.       KONG_PG_HOST: db
  21.       KONG_PG_USER: ${KONG_PG_USER:-kong}
  22.       KONG_PROXY_ACCESS_LOG: /dev/stdout
  23.       KONG_PROXY_ERROR_LOG: /dev/stderr
  24.       KONG_PG_PASSWORD_FILE: /run/secrets/kong_postgres_password
  25.     secrets:
  26.       - kong_postgres_password
  27.     networks:
  28.       - kong-net
  29.     ports:
  30.       - "8080:8000/tcp"
  31.       - "127.0.0.1:8001:8001/tcp"
  32.       - "8443:8443/tcp"
  33.       - "127.0.0.1:8444:8444/tcp"
  34.     healthcheck:
  35.       test: ["CMD", "kong", "health"]
  36.       interval: 10s
  37.       timeout: 10s
  38.       retries: 10
  39.     restart: on-failure
  40.     deploy:
  41.       restart_policy:
  42.         condition: on-failure
  43.   db:
  44.     image: postgres:9.5
  45.     environment:
  46.       POSTGRES_DB: ${KONG_PG_DATABASE:-kong}
  47.       POSTGRES_USER: ${KONG_PG_USER:-kong}
  48.       POSTGRES_PASSWORD_FILE: /run/secrets/kong_postgres_password
  49.     secrets:
  50.       - kong_postgres_password
  51.     healthcheck:
  52.       test: ["CMD", "pg_isready", "-U", "${KONG_PG_USER:-kong}"]
  53.       interval: 30s
  54.       timeout: 30s
  55.       retries: 3
  56.     restart: on-failure
  57.     deploy:
  58.       restart_policy:
  59.         condition: on-failure
  60.     stdin_open: true
  61.     tty: true
  62.     networks:
  63.       - kong-net
  64.     volumes:
  65.       - kong_data:/var/lib/postgresql/data
  66. secrets:
  67.   kong_postgres_password:
  68.     file: ./POSTGRES_PASSWORD

數(shù)據(jù)庫(kù)選擇了 PostgreSQL,開(kāi)源版本沒(méi)有 Dashboard,我們使用 RestAPI 創(chuàng)建所有的網(wǎng)關(guān)路由:

 
 
 
 
  1. curl -i -X POST http://localhost:8001/services \
  2.           --data name=goapi \
  3.           --data url='http://goapi:8080'
  4.     curl -i -X POST http://localhost:8001/services/goapi/routes \
  5.         --data 'paths[]=/goapi' \
  6.           --data name=goapi

需要先創(chuàng)建一個(gè) service,然后在該 service 下創(chuàng)建一條路由。

使用 K6 壓力測(cè)試的結(jié)果如下:

每秒請(qǐng)求數(shù) 705 要明顯弱于 Nginx,所以所有的功能都是有成本的。

APISIX

Apache APISIX 是一個(gè)動(dòng)態(tài)、實(shí)時(shí)、高性能的 API 網(wǎng)關(guān), 提供負(fù)載均衡、動(dòng)態(tài)上游、灰度發(fā)布、服務(wù)熔斷、身份認(rèn)證、可觀測(cè)性等豐富的流量管理功能。

APISIX 于 2019 年 4 月由中國(guó)的支流科技創(chuàng)建,于 6 月開(kāi)源,并于同年 10 月進(jìn)入 Apache 孵化器。

支流科技對(duì)應(yīng)的商業(yè)化產(chǎn)品的名字叫 API7 。APISIX 旨在處理大量請(qǐng)求,并具有較低的二次開(kāi)發(fā)門(mén)檻。

APISIX 的主要功能和特點(diǎn)有:

  • 云原生設(shè)計(jì),輕巧且易于容器化。
  • 集成了統(tǒng)計(jì)和監(jiān)視組件,例如 Prometheus,Apache Skywalking 和 Zipkin。
  • 支持 gRPC,Dubbo,WebSocket,MQTT 等代理協(xié)議,以及從 HTTP 到 gRPC 的協(xié)議轉(zhuǎn)碼,以適應(yīng)各種情況。
  • 擔(dān)當(dāng) OpenID 依賴(lài)方的角色,與 Auth0,Okta 和其他身份驗(yàn)證提供程序的服務(wù)連接。
  • 通過(guò)在運(yùn)行時(shí)動(dòng)態(tài)執(zhí)行用戶(hù)功能來(lái)支持無(wú)服務(wù)器,從而使網(wǎng)關(guān)的邊緣節(jié)點(diǎn)更加靈活。
  • 支持插件熱加載。
  • 不鎖定用戶(hù),支持混合云部署架構(gòu)。
  • 網(wǎng)關(guān)節(jié)點(diǎn)無(wú)狀態(tài),可以靈活擴(kuò)展。

從這個(gè)角度來(lái)看,API 網(wǎng)關(guān)可以替代 Nginx 來(lái)處理南北流量,也可以扮演 Istio 控制平面和 Envoy 數(shù)據(jù)平面的角色來(lái)處理東西向流量。

APISIX 的架構(gòu)如下圖所示:

APISIX 包含一個(gè)數(shù)據(jù)平面,用于動(dòng)態(tài)控制請(qǐng)求流量;一個(gè)用于存儲(chǔ)和同步網(wǎng)關(guān)數(shù)據(jù)配置的控制平面,一個(gè)用于協(xié)調(diào)插件的 AI 平面,以及對(duì)請(qǐng)求流量的實(shí)時(shí)分析和處理。

它構(gòu)建在 Nginx 反向代理服務(wù)器和鍵值存儲(chǔ) etcd 的之上,以提供輕量級(jí)的網(wǎng)關(guān)。

它主要用 Lua 編寫(xiě),Lua 是類(lèi)似于 Python 的編程語(yǔ)言。它使用 Radix 樹(shù)進(jìn)行路由,并使用前綴樹(shù)進(jìn)行 IP 匹配。

使用 etcd 而不是關(guān)系數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)配置可以使它更接近云原生,但是即使在任何服務(wù)器宕機(jī)的情況下,也可以確保整個(gè)網(wǎng)關(guān)系統(tǒng)的可用性。

所有組件都是作為插件編寫(xiě)的,因此其模塊化設(shè)計(jì)意味著功能開(kāi)發(fā)人員只需要關(guān)心自己的項(xiàng)目即可。

內(nèi)置的插件包括流控和速度限制,身份認(rèn)證,請(qǐng)求重寫(xiě),URI 重定向,開(kāi)放式跟蹤和無(wú)服務(wù)器。

APISIX 支持 OpenResty 和 Tengine 運(yùn)行環(huán)境,并且可以在 Kubernetes 的裸機(jī)上運(yùn)行。它同時(shí)支持 X86 和 ARM64。

我們同樣使用 Docker Compose 來(lái)部署 APISIX:

 
 
 
 
  1. version: "3.7"
  2. services:
  3.   apisix-dashboard:
  4.     image: apache/apisix-dashboard:2.4
  5.     restart: always
  6.     volumes:
  7.     - ./dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml
  8.     ports:
  9.     - "9000:9000"
  10.     networks:
  11.       apisix:
  12.         ipv4_address: 172.18.5.18
  13.   apisix:
  14.     image: apache/apisix:2.3-alpine
  15.     restart: always
  16.     volumes:
  17.       - ./apisix_log:/usr/local/apisix/logs
  18.       - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
  19.     depends_on:
  20.       - etcd
  21.     ##network_mode: host
  22.     ports:
  23.       - "8080:9080/tcp"
  24.       - "9443:9443/tcp"
  25.     networks:
  26.       apisix:
  27.         ipv4_address: 172.18.5.11
  28.     deploy:
  29.       resources:
  30.         limits:
  31.           cpus: '1'
  32.           memory: 256M
  33.         reservations:
  34.           memory: 256M
  35.   etcd:
  36.     image: bitnami/etcd:3.4.9
  37.     user: root
  38.     restart: always
  39.     volumes:
  40.       - ./etcd_data:/etcd_data
  41.     environment:
  42.       ETCD_DATA_DIR: /etcd_data
  43.       ETCD_ENABLE_V2: "true"
  44.       ALLOW_NONE_AUTHENTICATION: "yes"
  45.       ETCD_ADVERTISE_CLIENT_URLS: "http://0.0.0.0:2379"
  46.       ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
  47.     ports:
  48.       - "2379:2379/tcp"
  49.     networks:
  50.       apisix:
  51.         ipv4_address: 172.18.5.10
  52. networks:
  53.   apisix:
  54.     driver: bridge
  55.     ipam:
  56.       config:
  57.       - subnet: 172.18.0.0/16

開(kāi)源的 APISIX 支持 Dashboard 的方式來(lái)管理路由,而不是像 KONG 把儀表盤(pán)功能限制在商業(yè)版本中。

但是 APISIX 的儀表盤(pán)不支持對(duì)路由 URI 進(jìn)行改寫(xiě),所以我們只好使用 RestAPI 來(lái)創(chuàng)建路由。

創(chuàng)建一個(gè)服務(wù)的路由的命令如下:

 
 
 
 
  1. curl --location --request PUT 'http://127.0.0.1:8080/apisix/admin/routes/1' \
  2. --header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
  3. --header 'Content-Type: text/plain' \
  4. --data-raw '{
  5.     "uri": "/goapi/*",
  6.     "plugins": {
  7.         "proxy-rewrite": {
  8.             "regex_uri": ["^/goapi(.*)$","$1"]
  9.         }
  10.     },
  11.     "upstream": {
  12.         "type": "roundrobin",
  13.         "nodes": {
  14.             "goapi:8080": 1
  15.         }
  16.     }
  17. }'

使用 K6 壓力測(cè)試的結(jié)果如下:

APISix 取得了 1155 的好成績(jī),表現(xiàn)出接近不經(jīng)過(guò)網(wǎng)關(guān)的性能,可能緩存起到了很好的效果。

Tyk

Tyk 是一款基于 Golang 和 Redis 構(gòu)建的開(kāi)源 API 網(wǎng)關(guān)。它于 2014 年創(chuàng)建,比 AWS 的 API 網(wǎng)關(guān)即服務(wù)功能早。Tyk 用 Golang 編寫(xiě),并使用 Golang 自己的 HTTP 服務(wù)器。

Tyk 支持不同的運(yùn)行方式:云,混合(在自己的基礎(chǔ)架構(gòu)中為 GW)和本地。

Tyk 由 3 個(gè)組件組成:

  • 網(wǎng)關(guān):處理所有應(yīng)用流量的代理。
  • 儀表板:可以從中管理 Tyk,顯示指標(biāo)和組織 API 的界面。
  • Pump:負(fù)責(zé)持久保存指標(biāo)數(shù)據(jù),并將其導(dǎo)出到 MongoDB(內(nèi)置),ElasticSearch 或 InfluxDB 等。

我們同樣使用 Docker Compose 來(lái)創(chuàng)建 Tyk 網(wǎng)關(guān)來(lái)進(jìn)行功能驗(yàn)證。

 
 
 
 
  1. version: '3.7'
  2. services:
  3.   tyk-gateway:
  4.     image: tykio/tyk-gateway:v3.1.1
  5.     ports:
  6.       - 8080:8080
  7.     volumes:
  8.       - ./tyk.standalone.conf:/opt/tyk-gateway/tyk.conf
  9.       - ./apps:/opt/tyk-gateway/apps
  10.       - ./middleware:/opt/tyk-gateway/middleware
  11.       - ./certs:/opt/tyk-gateway/certs
  12.     environment:
  13.       - TYK_GW_SECRET=foo
  14.     depends_on:
  15.       - tyk-redis
  16.   tyk-redis:
  17.     image: redis:5.0-alpine
  18.     ports:
  19.       - 6379:6379

Tyk 的 Dashboard 也是屬于商業(yè)版本的范疇,所我們又一次需要借助 API 來(lái)創(chuàng)建路由,Tyk 是通過(guò) app 的概念來(lái)創(chuàng)建和管理路由的,你也可以直接寫(xiě) app 文件。

 
 
 
 
  1. curl --location --request POST 'http://localhost:8080/tyk/apis/' \
  2. --header 'x-tyk-authorization: foo' \
  3. --header 'Content-Type: application/json' \
  4. --data-raw '{
  5.     "name": "GO API",
  6.     "slug": "go-api",
  7.     "api_id": "goapi",
  8.     "org_id": "goapi",
  9.     "use_keyless": true,
  10.     "auth": {
  11.       "auth_header_name": "Authorization"
  12.     },
  13.     "definition": {
  14.       "location": "header",
  15.       "key": "x-api-version"
  16.     },
  17.     "version_data": {
  18.       "not_versioned": true,
  19.       "versions": {
  20.         "Default": {
  21.           "name": "Default",
  22.           "use_extended_paths": true
  23.         }
  24.       }
  25.     },
  26.     "proxy": {
  27.       "listen_path": "/goapi/",
  28.       "target_url": "http://host.docker.internal:18000/",
  29.       "strip_listen_path": true
  30.     },
  31.     "active": true
  32. }'

使用 K6 壓力測(cè)試的結(jié)果如下:

Tyk 的結(jié)果在 400-600 左右,性能上和 KONG 接近。

Zuul

Zuul 是 Netflix 開(kāi)源的基于 Java 的 API 網(wǎng)關(guān)組件。

Zuul 包含多個(gè)組件:

  • zuul-core:該庫(kù)包含編譯和執(zhí)行過(guò)濾器的核心功能。
  • zuul-simple-webapp:該 Webapp 展示了一個(gè)簡(jiǎn)單的示例,說(shuō)明如何使用 zuul-core 構(gòu)建應(yīng)用程序。
  • zuul-netflix:將其他 NetflixOSS 組件添加到 Zuul 的庫(kù),例如,使用 Ribbon 路由請(qǐng)求。
  • zuul-netflix-webapp:將 zuul-core 和 zuul-netflix 打包到一個(gè)易于使用的程序包中的 webapp。

Zuul 提供了靈活性和彈性,部分是通過(guò)利用其他 Netflix OSS 組件進(jìn)行的:

  • Hystrix 用于流控。包裝對(duì)始發(fā)地的呼叫,這使我們可以在發(fā)生問(wèn)題時(shí)丟棄流量并確定流量的優(yōu)先級(jí)。
  • Ribbon 是來(lái)自 Zuul 的所有出站請(qǐng)求的客戶(hù),它提供有關(guān)網(wǎng)絡(luò)性能和錯(cuò)誤的詳細(xì)信息,并處理軟件負(fù)載平衡以實(shí)現(xiàn)均勻的負(fù)載分配。
  • Turbine 實(shí)時(shí)匯總細(xì)粒度的指標(biāo),以便我們可以快速觀察問(wèn)題并做出反應(yīng)。
  • Archaius 處理配置并提供動(dòng)態(tài)更改屬性的能力。

Zuul 的核心是一系列過(guò)濾器,它們能夠在路由 HTTP 請(qǐng)求和響應(yīng)期間執(zhí)行一系列操作。

以下是 Zuul 過(guò)濾器的主要特征:

  • 類(lèi)型:通常定義路由流程中應(yīng)用過(guò)濾器的階段。(盡管它可以是任何自定義字符串)
  • 執(zhí)行順序:在類(lèi)型中應(yīng)用,定義跨多個(gè)過(guò)濾器的執(zhí)行順序。
  • 準(zhǔn)則:執(zhí)行過(guò)濾器所需的條件。
  • 動(dòng)作:如果符合條件,則要執(zhí)行的動(dòng)作。
 
 
 
 
  1. class DeviceDelayFilter extends ZuulFilter {
  2.     def static Random rand = new Random()
  3.     @Override
  4.     String filterType() {
  5.        return 'pre'
  6.     }
  7.     @Override
  8.     int filterOrder() {
  9.        return 5
  10.     }
  11.     @Override
  12.     boolean shouldFilter() {
  13.        return  RequestContext.getRequest().
  14.        getParameter("deviceType")?equals("BrokenDevice"):false
  15.     }
  16.     @Override
  17.     Object run() {
  18.        sleep(rand.nextInt(20000)) // Sleep for a random number of
  19.                                   // seconds between [0-20]
  20.     }
  21. }

Zuul 提供了一個(gè)框架來(lái)動(dòng)態(tài)讀取,編譯和運(yùn)行這些過(guò)濾器。過(guò)濾器不直接相互通信。

而是通過(guò)每個(gè)請(qǐng)求唯一的 RequestContext 共享狀態(tài)。過(guò)濾器使用 Groovy 編寫(xiě)。

有幾種與請(qǐng)求的典型生命周期相對(duì)應(yīng)的標(biāo)準(zhǔn)過(guò)濾器類(lèi)型:

  • Pre 過(guò)濾器在路由到原點(diǎn)之前執(zhí)行。示例包括請(qǐng)求身份驗(yàn)證,選擇原始服務(wù)器以及記錄調(diào)試信息。
  • Route 路由過(guò)濾器處理將請(qǐng)求路由到源。這是使用 Apache HttpClient 或 Netflix Ribbon 構(gòu)建和發(fā)送原始 HTTP 請(qǐng)求的地方。
  • 在將請(qǐng)求路由到源之后,將執(zhí)行 Post 過(guò)濾器。示例包括將標(biāo)準(zhǔn) HTTP 標(biāo)頭添加到響應(yīng),收集統(tǒng)計(jì)信息和指標(biāo)以及將響應(yīng)從源流傳輸?shù)娇蛻?hù)端。
  • 在其他階段之一發(fā)生錯(cuò)誤時(shí),將執(zhí)行 Error 過(guò)濾器。

Spring Cloud 創(chuàng)建了一個(gè)嵌入式 Zuul 代理,以簡(jiǎn)化一個(gè)非常常見(jiàn)的用例的開(kāi)發(fā),在該用例中,UI 應(yīng)用程序希望代理對(duì)一個(gè)或多個(gè)后端服務(wù)的調(diào)用。

此功能對(duì)于用戶(hù)界面代理所需的后端服務(wù)很有用,從而避免了為所有后端獨(dú)立管理 CORS 和身份驗(yàn)證問(wèn)題的需求 。

要啟用它,請(qǐng)使用 @EnableZuulProxy 注解一個(gè) Spring Boot 主類(lèi),這會(huì)將本地調(diào)用轉(zhuǎn)發(fā)到適當(dāng)?shù)姆?wù)。

Zuul 是 Java 的一個(gè)庫(kù),他并不是一款開(kāi)箱即用的 API 網(wǎng)關(guān),所以需要用 Zuul 開(kāi)發(fā)一個(gè)應(yīng)用來(lái)對(duì)其功能進(jìn)行測(cè)試。

對(duì)應(yīng)的 Java 的 POM 如下:

 
 
 
 
  1.     xmlns="http://maven.apache.org/POM/4.0.0"
  2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4.     4.0.0
  5.     naughtytao.apigateway
  6.    &n
    新聞標(biāo)題:開(kāi)源API網(wǎng)關(guān),到底哪個(gè)強(qiáng)?
    當(dāng)前路徑:http://www.dlmjj.cn/article/cdpgdhi.html