前言
API 网关是技术中台的"前门",所有外部请求都经过它。选对网关、配好网关,是中台建设的第一步。本篇对比 Kong 和 APISIX 两大主流网关,给出完整的落地实践。
一、API 网关核心职责
客户端请求
│
▼
┌─────────────────────────────────┐
│ API 网关 │
│ │
│ 1. 路由:/api/users → 用户中心 │
│ 2. 鉴权:JWT/OAuth2 校验 │
│ 3. 限流:100 QPS/IP │
│ 4. 熔断:后端故障快速失败 │
│ 5. 日志:请求审计 │
│ 6. 协议转换:HTTP→gRPC │
│ 7. 灰度:10%流量到 v2 │
│ 8. 缓存:热点数据缓存 │
│ 9. 请求/响应改写 │
│ 10. SSL/TLS 终止 │
└─────────────────────────────────┘
│ │ │
▼ ▼ ▼
用户中心 订单中心 支付中心
二、Kong vs APISIX 对比
| 维度 | Kong | APISIX |
|---|---|---|
| 语言 | Lua + Nginx | Lua + Nginx |
| 性能 | 高(~10K RPS) | 极高(~20K RPS) |
| 配置 | Admin API + 数据库 | Admin API + etcd |
| 动态配置 | 需重启或重载 | 热更新、毫秒生效 |
| 插件 | 丰富(200+) | 丰富(80+) |
| 协议 | HTTP/HTTPS/TCP/UDP | HTTP/HTTPS/TCP/UDP/gRPC |
| 多租户 | Workspaces | Route 级别隔离 |
| 服务发现 | DNS/Consul | DNS/Consul/Nacos/Eureka |
| 云原生 | K8s Ingress Controller | K8s Ingress Controller |
| 社区 | 成熟、企业版 | Apache 项目、活跃 |
| 学习曲线 | 中等 | 中等 |
选型建议
yaml
# 选 APISIX 如果你:
- 追求极致性能
- 需要动态配置热更新
- 深度使用 K8s
- 需要丰富协议支持(gRPC)
# 选 Kong 如果你:
- 已有 Kong 基础设施
- 需要 200+ 成熟插件
- 需要企业版支持
- 团队熟悉 Lua
三、APISIX 实战
安装
bash
# Docker Compose
version: '3'
services:
apisix:
image: apache/apisix:3.8.0
restart: always
ports:
- "9080:9080" # HTTP
- "9443:9443" # HTTPS
- "9180:9180" # Admin API
volumes:
- ./apisix.yaml:/usr/local/apisix/conf/apisix.yaml
depends_on:
- etcd
etcd:
image: bitnami/etcd:3.5
restart: always
environment:
- ALLOW_NONE_AUTH=yes
- ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379
ports:
- "2379:2379"
基本配置
yaml
# apisix.yaml
apisix:
node_listen: 9080
ssl:
enabled: true
listen_port: 9443
deployment:
role: traditional
role_traditional:
config_provider: etcd
etcd:
host:
- "http://etcd:2379"
prefix: "/apisix"
plugins:
- router-rewrite
- cors
- ip-restriction
- jwt-auth
- consumer-restriction
- limit-req
- limit-count
- limit-conn
- key-auth
- basic-auth
- prometheus
- request-id
- proxy-cache
- fault-injection
- serverless-pre-function
路由配置
bash
# 创建路由:/api/users/* → 用户中心
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f0-5bd7-4a20-9c9f-9f1d2c3b4a5e' \
-X PUT -d '
{
"uri": "/api/users/*",
"name": "user-service",
"methods": ["GET", "POST", "PUT", "DELETE"],
"upstream": {
"type": roundrobin,
"nodes": {
"user-service:8080": 1
}
},
"plugins": {
"prometheus": {},
"limit-req": {
"rate": 100,
"burst": 50,
"key_type": "var",
"key": "remote_addr",
"rejected_code": 429
},
"jwt-auth": {}
}
}'
鉴权插件
bash
# JWT 认证
# 1. 创建 Consumer
curl http://127.0.0.1:9180/apisix/admin/consumers \
-H 'X-API-KEY: xxx' \
-X PUT -d '
{
"username": "app-client",
"plugins": {
"jwt-auth": {
"key": "my-secret-key",
"algorithm": "HS256"
}
}
}'
# 2. 生成 Token
curl http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=my-secret-key
# {"token": "eyJhbG..."}
# 3. 请求带 Token
curl http://127.0.0.1:9080/api/users/1 \
-H "Authorization: eyJhbG..."
限流插件
bash
# 按 IP 限流
"limit-req": {
"rate": 100, # 每秒 100 个请求
"burst": 50, # 允许突发 50 个
"key_type": "var",
"key": "remote_addr",
"rejected_code": 429
}
# 按 Consumer 限流
"limit-count": {
"count": 1000, # 每分钟 1000 次
"time_window": 60,
"key_type": "var",
"key": "consumer_name",
"policy": "local", # 或 redis-cluster
"rejected_code": 429
}
熔断插件
bash
"api-breaker": {
"break_response_code": 502,
"unhealthy": {
"http_statuses": [500, 503],
"failures": 3 # 连续 3 次失败触发熔断
},
"healthy": {
"http_statuses": [200],
"successes": 2 # 连续 2 次成功恢复
}
}
灰度发布
bash
# 10% 流量到 v2
curl http://127.0.0.1:9180/apisix/admin/routes/2 \
-H 'X-API-KEY: xxx' \
-X PUT -d '
{
"uri": "/api/orders/*",
"upstream": {
"type": roundrobin,
"nodes": {
"order-v1:8080": 9,
"order-v2:8080": 1
}
}
}'
监控集成
bash
# 启用 Prometheus 插件
"plugins": {
"prometheus": {
"prefer_name": true
}
}
# 暴露 metrics
curl http://127.0.0.1:9080/apisix/prometheus/metrics
yaml
# Prometheus 采集
scrape_configs:
- job_name: 'apisix'
static_configs:
- targets: ['apisix:9080']
metrics_path: /apisix/prometheus/metrics
四、Kong 实战
安装
bash
# Docker
docker run -d --name kong \
--link kong-database:kong-database \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
-e "KONG_PROXY_LISTEN=0.0.0.0:8000" \
-p 8000:8000 \
-p 8001:8001 \
kong:3.6
路由配置
bash
# 创建 Service
curl -X POST http://localhost:8001/services \
-d "name=user-service" \
-d "url=http://user-service:8080"
# 创建 Route
curl -X POST http://localhost:8001/services/user-service/routes \
-d "paths[]=/api/users" \
-d "methods[]=GET" \
-d "methods[]=POST"
# 启用插件
curl -X POST http://localhost:8001/services/user-service/plugins \
-d "name=rate-limiting" \
-d "config.minute=100" \
-d "config.hour=10000"
鉴权插件
bash
# JWT 认证
curl -X POST http://localhost:8001/services/user-service/plugins \
-d "name=jwt"
# 创建 Consumer
curl -X POST http://localhost:8001/consumers \
-d "username=app-client"
# 给 Consumer 配置 JWT
curl -X POST http://localhost:8001/consumers/app-client/jwt \
-d "algorithm=HS256" \
-d "secret=my-secret"
五、K8s Ingress Controller
APISIX Ingress
yaml
# 安装 APISIX Ingress Controller
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: user-service-route
spec:
http:
- name: user-route
match:
hosts:
- api.example.com
paths:
- /api/users/*
backend:
serviceName: user-service
servicePort: 8080
plugins:
- name: limit-req
enable: true
config:
rate: 100
burst: 50
- name: jwt-auth
enable: true
- name: prometheus
enable: true
Kong Ingress
yaml
apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
name: user-service-kong
route:
methods:
- GET
- POST
strip_path: true
preserve_host: true
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: user-ingress
annotations:
konghq.com/strip-path: "true"
konghq.com/plugins: rate-limiting,jwt-auth
spec:
rules:
- host: api.example.com
http:
paths:
- path: /api/users
pathType: Prefix
backend:
service:
name: user-service
port:
number: 8080
六、生产部署
高可用
yaml
# APISIX K8s 部署
apiVersion: apps/v1
kind: Deployment
metadata:
name: apisix
spec:
replicas: 3 # HA
template:
spec:
containers:
- name: apisix
image: apache/apisix:3.8.0
resources:
requests:
cpu: 1
memory: 1Gi
limits:
cpu: 2
memory: 2Gi
livenessProbe:
httpGet:
path: /apisix/status
port: 9080
readinessProbe:
httpGet:
path: /apisix/status
port: 9080
---
apiVersion: v1
kind: Service
metadata:
name: apisix
spec:
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 9080
- name: https
port: 443
targetPort: 9443
selector:
app: apisix
监控告警
yaml
# 关键告警
groups:
- name: gateway-alerts
rules:
- alert: GatewayDown
expr: up{job="apisix"} == 0
for: 1m
labels:
severity: critical
- alert: GatewayHighLatency
expr: histogram_quantile(0.99, rate(apisix_request_duration_seconds_bucket[5m])) > 1
for: 5m
labels:
severity: warning
- alert: GatewayHighErrorRate
expr: |
sum(rate(apisix_request_total{status=~"5.."}[5m]))
/ sum(rate(apisix_request_total[5m])) * 100 > 5
for: 2m
labels:
severity: critical
⚠️ 踩坑提示 :
APISIX 配置变更通过 etcd 传播,etcd 必须高可用
Kong 依赖数据库,数据库也要高可用
SSL 证书管理用 cert-manager 自动更新
生产环境务必开启限流和熔断
要点回顾
| 特性 | APISIX | Kong |
|---|---|---|
| 性能 | 更高 | 高 |
| 动态配置 | etcd 热更新 | 需 reload |
| 插件 | 80+ | 200+ |
| K8s | Ingress CRD | Ingress Annotation |
| 推荐 | 云原生新项目 | 传统企业 |
- API 网关是中台统一入口
- APISIX 适合云原生、追求性能的场景
- Kong 适合传统企业、需要丰富插件
- 核心插件:路由、鉴权、限流、熔断、监控
- K8s 环境用 Ingress Controller 部署
下一篇预告
下一篇 【中台·技术篇】消息队列中台:Kafka/RocketMQ 统一管理与多租户隔离 将讲解消息队列的中台化。