
在使用 Kong 免費版的過程中,發現一些限制像Service 跟 Route 必須綁定 Service、不提供Consumer Group 功能受限等等,後來了解到 APISIX 這個開源方案,決定實際測試看看,經過實測後發現 APISIX 確實表現不錯,它是 Apache 基金會維護的項目,社群相當活躍,功能也很彈性,支援 Route Only 模式、Consumer Group、熱更新、多語言套件等等,是很值得考慮使用的 API Gateway 。
在架設的過程中,由於官方文件不夠詳細,版本相容性也有些問題,花了一些時間才成功建置環境。相關的設定檔已整理並放在 GitHub 上,有需要的朋友可以參考:
來看看這兩個到底差在哪裡:
| 項目 | APISIX | Kong (OSS) |
|---|---|---|
| 開源授權 | Apache 2.0 | Apache 2.0 |
| 核心技術 | NGINX + LuaJIT(OpenResty 底) | NGINX + LuaJIT(OpenResty 底) |
| 設定檔放哪 | etcd | PostgreSQL / DB-less 模式 |
| 怎麼設定 | REST API / etcd / YAML / Dashboard | REST API / YAML / Kong Manager(要錢) |
| 套件系統 | 熱更新,支援 Lua/Go/Java | Lua 套件、也能熱更新 |
| 效能表現 | 性能優秀,動態路由表現良好 | 穩定但比較保守 |
| 熱更新 | ✅ 支援不重啟服務即可加載套件 | ✅ 也支援熱更新,但沒這麼彈性(kong reload),APISIX 在自動化程度上稍微勝出一些。 |
| 管理介面 | ✅ 開源版本即提供不錯的 Dashboard | 🔶 第三方有 Konga 可以用 |
| K8s 支援 | ✅ 原生 Ingress Controller | ✅ Kong Ingress Controller |
| 多語言套件 | ✅ Lua / Go / Java / Wasm 都行 | ❌ 只能用 Lua |
| Consumer Group | ✅ 內建支援,使用方便 | ❌ 免費版不支援 |
| 套件數量 | 60+ 個,持續增加中 | 50+ 個 |
| 限流機制 | 相當彈性,支援分散式架構 | 基本功能完整,也支援 Redis分散式架構 |
| 安全性套件 | ✅ JWT、key-auth、IP 限制、WAF 等功能完整 | ✅ JWT、ACL 等等 |
| API 文檔自動生成 | ✅ 內建功能 | ❌ 需自行實作 |
| gRPC / WebSocket | ✅ 原生支援,無需額外設定 | 🔶 需安裝 plugin |
| 社群活躍度 | 相當活躍,中國地區更新頻繁 | 穩定,全球用戶多 |
| 商業支持 | API7.ai | Kong Inc |
| 維護複雜度 | 稍微高一點(要顧 etcd) | 比較簡單(用 PostgreSQL) |
假設你想要把 /wms/api/item/1 轉到 http://172.62.1.1:1080/api/item/1,來看看兩個怎麼做:
POST http://localhost:8001/services
Content-Type: application/json
{
"name": "wms",
"url": "http://localhost:1081/"
}
POST http://localhost:8001/routes
Content-Type: application/json
{
"name": "wms-api-item-1",
"paths": ["~/wms/(?<path>api/item/1)$"],
"strip_path": true,
"path_handling": "v1",
"service": {
"name": "wms"
},
"tags": ["wms"]
}
POST http://localhost:8001/plugins
Content-Type: application/json
{
"name": "request-transformer",
"service": {
"name": "wms"
},
"tags": ["wms"],
"config": {
"replace": {
"uri": "/api/item/1"
}
}
}
Kong 需要 3 次 API 呼叫,而且改路徑還需要額外安裝套件,設定流程較為複雜。
APISIX 支援 Route Only 模式,一次 API Call 即可完成設定:
PUT http://127.0.0.1:9180/apisix/admin/routes/api-0001
X-API-KEY: <your-api-key>
Content-Type: application/json
{
"uri": "/wms/api/item/1",
"name": "/wms/api/item/1",
"priority": 10,
"methods": ["GET", "POST", "PUT", "DELETE"],
"plugins": {
"proxy-rewrite": {
"regex_uri": ["^/wms/(.*)", "/$1"]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"172.62.1.1:1080": 1
}
}
}
APISIX 僅需 1 次 API Call,內建的 proxy-rewrite 功能可直接處理路徑重寫,設定流程相當簡潔。
| 項目 | Kong | APISIX |
|---|---|---|
| 要先建 Service嗎 | ✅ 一定要 | ❌ 不用,直接建 Route |
| 要建 Route | ✅ | ✅ |
| API Call 次數 | 3 次(較為繁瑣) | 1 次(相對簡單) |
| 設定複雜度 | 較為複雜 | 相對簡單 |
APISIX 的優勢之一是支援多種條件來決定路由,不僅是 URI,還可以根據 HTTP Method、Header、Query 參數、Host 等等,實現動態條件分流
PUT http://127.0.0.1:9180/apisix/admin/routes/dynamic-header
X-API-KEY: <your-api-key>
Content-Type: application/json
{
"uri": "/api/v1/resource",
"methods": ["GET"],
"name": "dynamic-header-route",
"priority": 20,
"vars": [
["http_x-user-type", "==", "admin"]
],
"upstream": {
"type": "roundrobin",
"nodes": {
"10.0.0.1:8080": 1
}
}
}
這樣設定的話,只有帶著
X-User-Type: adminheader 的請求,才會被導到指定的 upstream。
PUT http://127.0.0.1:9180/apisix/admin/routes/dynamic-query
X-API-KEY: <your-api-key>
Content-Type: application/json
{
"uri": "/api/v1/resource",
"methods": ["GET"],
"name": "dynamic-query-route",
"priority": 10,
"vars": [
["arg_version", "==", "beta"]
],
"upstream": {
"type": "roundrobin",
"nodes": {
"10.0.0.2:8080": 1
}
}
}
這個設定會把帶有
?version=beta的請求,導到不同的 upstream。
P.S. APISIX 的路由條件設計相當彈性,可以根據各種請求屬性來做動態分流
實際使用後,推薦以下幾個實用功能:
還是用剛剛 /wms/api/item/1 轉址的例子:
PUT http://127.0.0.1:9180/apisix/admin/routes/api-0001
X-API-KEY: <your-api-key>
Content-Type: application/json
{
"uri": "/wms/api/item/1",
"name": "/wms/api/item/1",
"priority": 10,
"methods": ["GET", "POST", "PUT", "DELETE"],
"plugins": {
"proxy-rewrite": {
"regex_uri": ["^/wms/(.*)", "/$1"]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"172.62.1.1:1080": 1
}
}
}
APISIX 的 Consumer Group 功能相當實用,雖然沒有 UI 介面,但透過 API 操作也很方便,可以搭配 Plugin Config 來實現分群限流:
PUT http://localhost:9180/apisix/admin/consumer_groups/free
X-API-KEY: <your-api-key>
Content-Type: application/json
{
"plugins": {}
}
建立限流的 Plugin Config:
PUT http://localhost:9180/apisix/admin/plugin_configs/free_ratelimit
X-API-KEY: <your-api-key>
Content-Type: application/json
{
"plugins": {
"key-auth": {},
"limit-count": {
"count": 100,
"time_window": 1,
"rejected_code": 429,
"key": "consumer_name",
"policy": "local",
"group": "daily"
}
}
}
建立 Consumer 並套用群組:
PUT http://localhost:9180/apisix/admin/consumers/mark
X-API-KEY: <your-api-key>
Content-Type: application/json
{
"username": "mark",
"plugins": {
"key-auth": {
"key": "mark-api-key"
}
},
"consumer_group": "standard"
}
注意喔!一個 consumer 只能加入一個 consumer group
APISIX 在限流方面表現優秀,支援類似 Kong 付費版才有的「動態模板 key」功能。可以在 key 欄位中使用多個變數(如 IP、consumer、header 等)組合,實現精細的分群限流。
舉例來說:
PUT /apisix/admin/plugin_configs/pc_free
{
"plugins": {
"limit-count": {
"time_window": 60,
"count": 100,
"rejected_code": 429,
"key_type": "var_combination",
"key": "standard-1-47|$consumer_name",
"policy": "redis",
"redis_host": "192.168.0.15",
"redis_port": 6379,
"redis_timeout": 1000000,
"redis_database": 0
}
}
}
P.S. 這個實測有問題,應該是有bug
這個設定會根據來源 IP、consumer 名稱、以及 header
X-User-Group的組合,動態計算每個分群的頻次,限流資料儲存在 Redis 中。這種彈性分群限流功能,Kong 需企業版才提供,APISIX 開源版即內建此功能。
APISIX 支援多個層級的套件綁定,讓你可以很彈性地管理:
| 層級 | 綁定方式 | 說明 |
|---|---|---|
| Global Rule | /apisix/admin/global_rules | 全域規則,優先權最高 |
| Consumer | /apisix/admin/consumers/{username} | 針對特定使用者 |
| Consumer Group | /apisix/admin/consumer_groups/{groupname} | 分群管理 Consumer |
| Route | /apisix/admin/routes/{id} | 針對特定 API 路由 |
| Service | /apisix/admin/services/{id} | 多個 Route 可以共用 |
Plugin Config 可以重複使用,讓 Route/Service 直接引用 plugin_config_id,維運效率大大提升!
APISIX 支援 labels 功能,可以為 Route、Consumer、Service 加上 group 標籤,便於查詢和管理:
{
"uri": "/wms/api/item/1",
"labels": {
"group": "wms"
},
"name": "get-wms-item-1"
}
想查詢 group 是 wms 的 route,直接這樣打:
GET /apisix/admin/routes?label=group==wms
可以用 Global Rule 來套用全域套件,像是 request-id、prometheus、udp-logger 等等:
PUT http://127.0.0.1:9180/apisix/admin/global_rules/1
X-API-KEY: <your-api-key>
Content-Type: application/json
{
"plugins": {
"key-auth": {"_meta": {"disable": false}},
"request-id": {"_meta": {"disable": false}},
"prometheus": {"_meta": {"disable": false}},
"udp-logger": {
"host": "192.168.0.1",
"port": 5000,
"custom_fields": {"client_ip": "$remote_addr"}
}
}
}
注意:APISIX 支援多筆 Global rules(有特殊用途),但 Dashboard 只能管理一筆。一般情況下,維持一筆 global_rule(如 /global_rules/1)即可滿足需求,將所有 plugin 配置在同一筆記錄中。
啟用 Prometheus 監控:
PUT http://localhost:9180/apisix/admin/plugins/prometheus
X-API-KEY: <your-api-key>
Content-Type: application/json
{
"enabled": true
}
雖然 APISIX 很強,但還是有一些限制要注意。不管是用 KONG 還是 APISIX,都各有各的限制,如果需要更複雜的流量分組,可能都需要自己寫 plugin,或是大幅度客製化:
使用 APISIX 一段時間後,認為這個開源方案確實很不錯。其高彈性、熱更新、多語言套件等優勢,使其成為現代 API Gateway 的優質選擇,雖然有些功能需要透過 API 操作,維運複雜度稍微高一些,但對於需要高彈性、分群限流、動態路由的場景來說,APISIX 提供了完善的解決方案,了解這些限制之後,就能更清楚該提供什麼樣的解決方案。但在特定領域的 API Gateway 需求如果過於複雜,即使使用付費版本,除非需求可以調整,否則最終還是可能需要客製化開發。