前陣子公司微服務集羣擴張到三十多個服務,客户端調用變得一團糟:每個服務都有獨立域名,認證邏輯重複開發,還經常因為某個服務突發流量拖垮整個集羣。後來引入Kong網關作為統一入口,不僅解決了域名混亂問題,還通過流量控制和認證攔截減輕了業務服務的負擔,運維效率提升了不少。
在微服務架構中,API網關扮演着"交通樞紐"的角色,負責請求路由、流量控制、認證授權等橫切關注點。Kong作為基於Nginx的高性能網關,以輕量、可擴展著稱,尤其適合高併發場景。本文結合實際業務場景,講解Kong的核心功能、路由配置技巧以及流量控制策略,幫你快速上手這個強大的網關工具。
一、Kong基礎:核心概念與部署
Kong的核心概念很簡單,理解這幾個術語就能快速入門:
- Service:代表後端的一個微服務(如用户服務、訂單服務),定義了服務的訪問地址。
- Route:路由規則,決定哪些請求轉發到哪個Service(如將
/api/user/*轉發到用户服務)。 - Plugin:插件機制,用於實現認證、限流、日誌等功能,可綁定到Service或Route。
快速部署Kong
用Docker Compose快速部署Kong(含PostgreSQL存儲配置):
# docker-compose.yml
version: '3'
services:
postgres:
image: postgres:13
environment:
POSTGRES_USER: kong
POSTGRES_DB: kong
POSTGRES_PASSWORD: kong
volumes:
- pgdata:/var/lib/postgresql/data
kong:
image: kong:3.2
depends_on:
- postgres
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: postgres
KONG_PG_USER: kong
KONG_PG_PASSWORD: kong
KONG_PROXY_LISTEN: 0.0.0.0:8000
KONG_ADMIN_LISTEN: 0.0.0.0:8001
ports:
- "8000:8000" # 代理端口(接收客户端請求)
- "8001:8001" # 管理端口(配置Kong)
restart: always
volumes:
pgdata:
啓動服務:
docker-compose up -d
驗證部署成功:
curl http://localhost:8001/status # 返回Kong狀態信息
二、路由配置:精準轉發請求
路由是Kong的核心功能,通過定義Route規則,可將不同路徑、方法的請求轉發到對應的微服務。
1. 創建Service(後端服務)
先定義一個指向用户服務的Service:
# 創建用户服務Service
curl -X POST http://localhost:8001/services \
-d "name=user-service" \
-d "url=http://user-service:8080" # 後端服務實際地址
再創建訂單服務:
curl -X POST http://localhost:8001/services \
-d "name=order-service" \
-d "url=http://order-service:8080"
2. 配置Route(路由規則)
為用户服務添加路由,匹配/api/user開頭的路徑:
# 用户服務路由:匹配路徑/api/user/*
curl -X POST http://localhost:8001/services/user-service/routes \
-d "paths[]=/api/user" \
-d "methods[]=GET" \
-d "methods[]=POST" \
-d "name=user-route"
為訂單服務添加路由,同時匹配路徑和主機名:
# 訂單服務路由:匹配主機名order.example.com和路徑/api/order/*
curl -X POST http://localhost:8001/services/order-service/routes \
-d "paths[]=/api/order" \
-d "hosts[]=order.example.com" \
-d "name=order-route"
此時,Kong會按以下規則轉發:
GET http://localhost:8000/api/user/1→ 轉發到user-service:8080/api/user/1POST http://order.example.com:8000/api/order→ 轉發到order-service:8080/api/order
3. 路由高級配置:路徑重寫
有時需要修改請求路徑,例如將/api/v1/user重寫為/user後轉發到後端:
# 創建帶路徑重寫的路由
curl -X POST http://localhost:8001/services/user-service/routes \
-d "paths[]=/api/v1/user" \
-d "name=user-v1-route" \
-d "strip_path=false" # 不自動去除匹配的路徑前綴
-d "regex_priority=2" # 路由優先級(數字越大越優先)
-d "plugins[0].name=request-transformer" \
-d "plugins[0].config.replace.uri[]=/user" # 將URI重寫為/user
配置後,/api/v1/user/1會被重寫為/user/1轉發到後端服務。
三、流量控制:限流與熔斷
Kong通過插件實現流量控制,防止後端服務被突發流量壓垮,常用的有rate-limiting(限流)和request-size-limiting(請求大小限制)。
1. 接口限流
為用户服務添加限流插件,限制每個IP每分鐘最多100次請求:
# 為user-service添加限流插件
curl -X POST http://localhost:8001/services/user-service/plugins \
-d "name=rate-limiting" \
-d "config.minute=100" \ # 每分鐘100次
-d "config.policy=local" \ # 本地限流(集羣需用redis)
-d "config.limit_by=ip" # 按IP限流
超過限制時,Kong會返回429狀態碼:
{
"message": "API rate limit exceeded"
}
也可針對特定路由限流(如更嚴格限制登錄接口):
# 為登錄路由添加更嚴格的限流
curl -X POST http://localhost:8001/routes/login-route/plugins \
-d "name=rate-limiting" \
-d "config.minute=10" # 每分鐘僅10次
2. 請求大小限制
防止大請求消耗過多資源,限制請求體最大1MB:
curl -X POST http://localhost:8001/services/order-service/plugins \
-d "name=request-size-limiting" \
-d "config.allowed_payload_size=1" \ # 1MB
-d "config.size_unit=megabytes"
超過限制時返回413狀態碼。
3. 熔斷機制
當後端服務頻繁出錯時,自動熔斷避免無效請求:
# 配置熔斷插件:50%失敗率且至少10個請求時觸發
curl -X POST http://localhost:8001/services/payment-service/plugins \
-d "name=circuit-breaker" \
-d "config.failure_threshold=50" \ # 失敗率閾值
-d "config.minimum_calls=10" \ # 最小調用次數
-d "config.window_size=60" \ # 統計窗口(秒)
-d "config.fallback=http_status=503" # 熔斷時返回503
四、認證與安全:統一攔截
Kong可集中處理認證邏輯,避免每個服務重複開發。以JWT認證為例:
1. 啓用JWT插件
為所有服務啓用JWT認證:
# 全局啓用JWT插件(作用於所有服務)
curl -X POST http://localhost:8001/plugins \
-d "name=jwt" \
-d "config.uri_param_names[]=token" \ # 支持URL參數傳遞token
-d "config.cookie_names[]=jwt_token" # 支持Cookie傳遞token
也可只為特定服務啓用:
# 只為支付服務啓用JWT
curl -X POST http://localhost:8001/services/payment-service/plugins \
-d "name=jwt"
2. 創建消費者與憑證
添加一個消費者(客户端)並生成JWT憑證:
# 創建消費者
curl -X POST http://localhost:8001/consumers \
-d "username=mobile-app"
# 為消費者生成JWT憑證
curl -X POST http://localhost:8001/consumers/mobile-app/jwt \
-d "algorithm=HS256"
返回結果包含token,客户端請求時需在Header中攜帶:
curl http://localhost:8000/api/user \
-H "Authorization: Bearer <生成的token>"
未攜帶有效token的請求會被攔截,返回401狀態碼。
五、最佳實踐與避坑指南
- 路由設計規範:按業務域劃分路由(如
/api/user、/api/order),避免過細或過粗。路徑中可包含版本(如/api/v1/user),便於平滑升級。 - 插件粒度控制:全局插件(如基礎認證)作用於所有服務,服務級插件(如訂單服務限流)針對特定服務,路由級插件(如登錄接口限流)用於更精細的控制。
- 集羣部署注意:單節點Kong的限流插件用
local策略,集羣環境需改用redis策略,確保限流計數在節點間同步。 - 監控與日誌:啓用
prometheus插件暴露監控指標,結合file-log插件記錄請求日誌:
# 啓用Prometheus監控
curl -X POST http://localhost:8001/plugins \
-d "name=prometheus"
# 啓用日誌插件
curl -X POST http://localhost:8001/plugins \
-d "name=file-log" \
-d "config.path=/var/log/kong/access.log"
- 避免性能瓶頸:Kong本身性能優異,但過多插件會增加開銷。建議只保留必要插件,複雜邏輯通過自定義插件異步處理。
總結
Kong網關通過Service、Route和Plugin的組合,輕鬆實現了微服務的路由轉發、流量控制和認證安全。它的優勢在於輕量高性能(基於Nginx)和靈活的插件機制,能適應從簡單到複雜的各種場景。
實際使用中,重點在於合理設計路由規則和插件策略:路由要清晰易維護,插件要按需啓用避免性能損耗。無論是中小團隊的快速部署,還是大型集羣的高可用需求,Kong都能提供可靠的網關解決方案,讓業務服務專注於核心邏輯,無需重複處理橫切關注點。