API 网关产品对比与选型
目录
主流网关对比
全景对比
┌──────────────────────────────────────────────────────────────────────┐
│ API 网关产品全景对比 │
├───────────┬─────────┬─────────┬─────────┬─────────┬─────────────────┤
│ 特性 │ Kong │ APISIX │ Tyk │ Traefik │ AWS Gateway │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────────────┤
│ 开源 │ ✓ │ ✓ │ ✓ │ ✓ │ ✗ │
│ 核心语言 │ Lua │ Lua │ Go │ Go │ 托管服务 │
│ 性能(QPS) │ 20K │ 50K+ │ 25K │ 30K │ 自动扩展 │
│ 协议 │HTTP/gRPC│HTTP/gRPC│HTTP/gRPC│HTTP/TCP │ HTTP/REST │
│ 配置存储 │PostgreSQL│ etcd │ Redis │ 内存 │ DynamoDB │
│ Dashboard │ Konga │ 官方 │ 官方 │ 官方 │ Console │
│ 插件语言 │ Lua │Lua/多语言│ Go │ Go │ 无需开发 │
│ K8s集成 │ ✓ │ ✓✓ │ ✓ │ ✓✓ │ ✗ │
│ 社区活跃 │ ⭐⭐⭐ │ ⭐⭐⭐⭐ │ ⭐⭐ │ ⭐⭐⭐ │ N/A │
│ 学习曲线 │ 中等 │ 较陡 │ 简单 │ 简单 │ 简单 │
│ 商业支持 │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
│ 适用场景 │中大型企业│大规模高性能│中小企业│云原生 │ AWS 生态 │
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────────────┘性能基准测试
性能对比 (单核 QPS)
┌──────────────────────────────────┐
│ │
│ APISIX ████████████ 12000 │
│ │
│ Kong ████████ 8000 │
│ │
│ Tyk ██████████ 10000 │
│ │
│ Traefik ███████████ 11000 │
│ │
│ Nginx ██████████████ 14000 │
│ (纯转发) │
└──────────────────────────────────┘
延迟对比 (P99)
┌──────────────────────────────────┐
│ │
│ APISIX ██ 2ms │
│ │
│ Kong ████ 4ms │
│ │
│ Tyk ███ 3ms │
│ │
│ Traefik ███ 3ms │
│ │
│ Nginx █ 1ms │
└──────────────────────────────────┘
测试环境:
- CPU: 4 Core
- Memory: 8GB
- 并发: 1000
- 请求体: 1KBKong 深度分析
Kong 架构优劣势
┌─────────────────────────────────────────┐
│ Kong 优势 │
├─────────────────────────────────────────┤
│ │
│ ✓ 成熟稳定 (2015年开源) │
│ ✓ 生态丰富 (200+ 插件) │
│ ✓ 企业版功能强大 │
│ ✓ 文档完善 │
│ ✓ 社区活跃 │
│ ✓ 支持 PostgreSQL/Cassandra │
│ ✓ Kong Mesh (服务网格) │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ Kong 劣势 │
├─────────────────────────────────────────┤
│ │
│ ✗ 性能相对较低 │
│ ✗ 配置同步延迟 (数据库) │
│ ✗ Dashboard 需第三方 (Konga) │
│ ✗ 插件开发仅限 Lua │
│ ✗ 内存占用较高 │
└─────────────────────────────────────────┘Kong 适用场景
yaml
# Kong 最佳实践场景
scenarios:
# 1. 传统企业 API 管理
traditional_enterprise:
description: "需要稳定可靠的 API 网关"
reasons:
- 成熟度高,生产验证充分
- 企业版提供专业支持
- 丰富的插件生态
example: "金融、保险、电信行业"
# 2. 混合云架构
hybrid_cloud:
description: "跨云、跨数据中心部署"
reasons:
- 支持混合部署模式
- Kong Mesh 服务网格
- 统一控制平面
example: "跨国企业、大型互联网公司"
# 3. API 货币化
api_monetization:
description: "API 付费、计量计费"
reasons:
- 企业版提供计费功能
- 完善的速率限制
- 开发者门户
example: "SaaS 平台、API 提供商"
# 4. 微服务网关
microservices:
description: "中等规模微服务架构"
reasons:
- 服务发现集成
- 健康检查
- 负载均衡
example: "100-500 个微服务"APISIX 深度分析
APISIX 架构优势
┌─────────────────────────────────────────┐
│ APISIX 优势 │
├─────────────────────────────────────────┤
│ │
│ ✓ 性能极高 (50K+ QPS) │
│ ✓ 配置实时生效 (etcd Watch) │
│ ✓ 官方 Dashboard │
│ ✓ 多语言插件 (Lua/Java/Python/Go) │
│ ✓ 云原生设计 │
│ ✓ 完整的可观测性 │
│ ✓ 灵活的路由匹配 │
│ ✓ 低延迟 (P99 < 2ms) │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ APISIX 劣势 │
├─────────────────────────────────────────┤
│ │
│ ✗ 相对较新 (2019年开源) │
│ ✗ 文档有待完善 │
│ ✗ 插件生态不如 Kong │
│ ✗ 学习曲线较陡 │
│ ✗ 企业版功能相对少 │
└─────────────────────────────────────────┘APISIX 适用场景
yaml
# APISIX 最佳实践场景
scenarios:
# 1. 高性能场景
high_performance:
description: "对性能和延迟要求极高"
reasons:
- 单核 12K+ QPS
- P99 延迟 < 2ms
- 内存占用低
example: "电商大促、秒杀活动、游戏平台"
# 2. 云原生架构
cloud_native:
description: "Kubernetes 原生部署"
reasons:
- etcd 配置中心
- 毫秒级配置同步
- Ingress Controller
example: "容器化微服务、K8s 集群"
# 3. 大规模微服务
large_scale:
description: "数千个微服务、海量请求"
reasons:
- 支持数万路由规则
- 动态路由
- 服务发现集成
example: "超大型互联网公司"
# 4. 多协议网关
multi_protocol:
description: "需要支持多种协议"
reasons:
- HTTP/HTTPS/HTTP2/gRPC
- TCP/UDP/MQTT
- WebSocket
example: "IoT 平台、实时通信"APISIX 性能优化配置
yaml
# apisix-performance.yaml - 高性能配置
nginx_config:
error_log_level: error # 减少日志
worker_processes: auto # 自动匹配 CPU 核数
worker_rlimit_nofile: 65535 # 增加文件描述符限制
event:
worker_connections: 10620 # 每个 worker 连接数
http:
# 启用 sendfile
sendfile: on
tcp_nopush: on
tcp_nodelay: on
# Keepalive 优化
keepalive_timeout: 65s
keepalive_requests: 1000
# 上游 Keepalive 连接池
upstream:
keepalive: 320 # 连接池大小
keepalive_requests: 1000
keepalive_timeout: 60s
# 缓冲区优化
client_body_buffer_size: 128k
client_max_body_size: 50m
client_header_buffer_size: 4k
plugins:
# 只启用必要插件,减少性能开销
- prometheus # 监控
- limit-req # 限流
- jwt-auth # 认证
- proxy-rewrite # 路径重写
etcd:
# etcd 超时优化
timeout: 10
startup_retry: 2
# 使用本地 etcd 减少网络延迟
host:
- "http://127.0.0.1:2379"Nginx 与 OpenResty
Nginx 作为 API 网关
nginx
# nginx-gateway.conf - Nginx API 网关配置
http {
# 上游服务器组
upstream user_service {
least_conn; # 最少连接负载均衡
server user-service-1:8080 weight=3 max_fails=3 fail_timeout=30s;
server user-service-2:8080 weight=3;
server user-service-3:8080 backup; # 备用服务器
keepalive 32; # 连接池
}
# 限流配置
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
# 缓存配置
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=60m;
server {
listen 80;
server_name api.example.com;
# 访问日志
access_log /var/log/nginx/api_access.log json;
# 全局限流
limit_req zone=api_limit burst=50 nodelay;
limit_conn addr 10;
# JWT 验证 (需要 lua 模块)
set $jwt_payload "";
access_by_lua_block {
local jwt = require "resty.jwt"
local auth_header = ngx.var.http_authorization
if not auth_header or not string.find(auth_header, "Bearer ") then
ngx.status = 401
ngx.say('{"error":"Missing token"}')
return ngx.exit(401)
end
local token = string.sub(auth_header, 8)
local jwt_obj = jwt:verify("your-secret-key", token)
if not jwt_obj.verified then
ngx.status = 401
ngx.say('{"error":"Invalid token"}')
return ngx.exit(401)
end
ngx.var.jwt_payload = jwt_obj.payload
}
# 用户 API
location /api/v1/users {
# 跨域配置
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;
# 缓存配置
proxy_cache api_cache;
proxy_cache_valid 200 5m;
proxy_cache_key "$request_uri|$http_authorization";
add_header X-Cache-Status $upstream_cache_status;
# 代理设置
proxy_pass http://user_service;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Request-ID $request_id;
# 超时设置
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 30s;
# 健康检查
proxy_next_upstream error timeout http_500 http_502 http_503;
proxy_next_upstream_tries 2;
}
# 健康检查端点
location /health {
access_log off;
return 200 "OK\n";
}
# Prometheus 指标
location /metrics {
content_by_lua_block {
local prometheus = require("nginx.prometheus").init("prometheus_metrics")
prometheus:collect()
}
}
}
}OpenResty 自定义网关
lua
-- gateway.lua - OpenResty 自定义网关逻辑
local jwt = require "resty.jwt"
local redis = require "resty.redis"
local cjson = require "cjson"
local _M = {}
-- JWT 验证
function _M.verify_jwt()
local auth_header = ngx.var.http_authorization
if not auth_header or not auth_header:find("Bearer ") then
return nil, "Missing token"
end
local token = auth_header:sub(8)
local jwt_obj = jwt:verify(ngx.var.jwt_secret, token)
if not jwt_obj.verified then
return nil, "Invalid token"
end
return jwt_obj.payload, nil
end
-- 限流 (令牌桶)
function _M.rate_limit(key, rate, burst)
local red = redis:new()
red:set_timeouts(1000, 1000, 1000)
local ok, err = red:connect("redis", 6379)
if not ok then
ngx.log(ngx.ERR, "Failed to connect to redis: ", err)
return true -- Fail open
end
local bucket_key = "rate_limit:" .. key
local now = ngx.now()
-- 获取桶状态
local tokens, err = red:get(bucket_key .. ":tokens")
if tokens == ngx.null then
tokens = burst
else
tokens = tonumber(tokens)
end
local last_time, err = red:get(bucket_key .. ":time")
if last_time == ngx.null then
last_time = now
else
last_time = tonumber(last_time)
end
-- 补充令牌
local time_passed = now - last_time
tokens = math.min(burst, tokens + time_passed * rate)
if tokens < 1 then
-- 触发限流
ngx.header["X-RateLimit-Limit"] = rate
ngx.header["X-RateLimit-Remaining"] = 0
ngx.header["Retry-After"] = math.ceil(1 / rate)
red:set_keepalive(10000, 100)
return false
end
-- 消耗令牌
tokens = tokens - 1
-- 更新状态
red:set(bucket_key .. ":tokens", tokens)
red:set(bucket_key .. ":time", now)
red:expire(bucket_key .. ":tokens", 3600)
red:expire(bucket_key .. ":time", 3600)
ngx.header["X-RateLimit-Limit"] = rate
ngx.header["X-RateLimit-Remaining"] = math.floor(tokens)
red:set_keepalive(10000, 100)
return true
end
-- 服务发现 (Consul)
function _M.discover_service(service_name)
local http = require "resty.http"
local httpc = http.new()
local res, err = httpc:request_uri("http://consul:8500/v1/health/service/" .. service_name, {
method = "GET",
query = {passing = "true"}
})
if not res then
ngx.log(ngx.ERR, "Failed to discover service: ", err)
return nil
end
local services = cjson.decode(res.body)
if #services == 0 then
return nil
end
-- 随机选择
local idx = math.random(1, #services)
local service = services[idx]
return service.Service.Address .. ":" .. service.Service.Port
end
return _M选型决策
决策树
API 网关选型决策
┌────────────────────────────────────┐
│ 预算充足,需要商业支持? │
└─────────┬──────────────────────────┘
│
┌─────┴─────┐
是 否
│ │
│ ▼
│ ┌─────────────────────┐
│ │ 对性能要求极高? │
│ └─────┬───────────────┘
│ │
│ ┌────┴────┐
│ 是 否
│ │ │
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│ Kong │ │ APISIX │ │ Kong │
│ 企业版 │ │ │ │ 开源版 │
└────────┘ └────────┘ └────────┘
│
│
▼
需要 Kubernetes 深度集成?
│
┌──┴──┐
是 否
│ │
▼ ▼
APISIX Kong选型矩阵
┌──────────────────────────────────────────────┐
│ 选型决策矩阵 │
├───────────────┬───────┬─────────┬───────────┤
│ 需求 │ Kong │ APISIX │ Nginx │
├───────────────┼───────┼─────────┼───────────┤
│ 性能 > 30K QPS│ ✗ │ ✓ │ ✓ │
│ 延迟 < 5ms │ △ │ ✓ │ ✓ │
│ 插件生态 │ ✓ │ △ │ ✗ │
│ K8s 集成 │ △ │ ✓ │ △ │
│ 配置实时生效 │ ✗ │ ✓ │ ✗ │
│ Dashboard │ △ │ ✓ │ ✗ │
│ 学习成本低 │ ✓ │ ✗ │ △ │
│ 商业支持 │ ✓ │ △ │ ✓ │
│ 多语言插件 │ ✗ │ ✓ │ △ │
│ 社区活跃 │ ✓ │ ✓ │ ✓ │
└───────────────┴───────┴─────────┴───────────┘
✓ = 优秀 △ = 一般 ✗ = 不足实际案例参考
yaml
# 真实企业选型案例
cases:
# 案例 1: 电商平台
ecommerce_platform:
company_size: "中型 (500人)"
traffic: "日均 1000万 PV"
choice: "APISIX"
reasons:
- "大促期间 QPS 峰值 50000+"
- "需要灵活的灰度发布"
- "Kubernetes 原生部署"
- "成本敏感,选择开源版"
# 案例 2: 金融公司
financial_company:
company_size: "大型 (5000人)"
traffic: "日均 500万 PV"
choice: "Kong Enterprise"
reasons:
- "稳定性第一"
- "需要专业技术支持"
- "合规审计要求"
- "预算充足"
# 案例 3: 初创公司
startup:
company_size: "小型 (50人)"
traffic: "日均 10万 PV"
choice: "Kong OSS"
reasons:
- "快速上线"
- "文档完善,学习成本低"
- "插件生态丰富"
- "社区支持良好"
# 案例 4: 物联网平台
iot_platform:
company_size: "中型 (300人)"
traffic: "百万设备连接"
choice: "APISIX"
reasons:
- "支持 MQTT 协议"
- "低延迟要求"
- "动态路由"
- "云原生架构"迁移指南
Kong 迁移到 APISIX
python
# kong_to_apisix_migration.py - 配置迁移工具
import requests
import json
class MigrationTool:
def __init__(self, kong_admin, apisix_admin, apisix_key):
self.kong_admin = kong_admin
self.apisix_admin = apisix_admin
self.apisix_key = apisix_key
def export_kong_config(self):
"""导出 Kong 配置"""
config = {
"services": [],
"routes": [],
"upstreams": [],
"plugins": [],
"consumers": []
}
# 导出服务
resp = requests.get(f"{self.kong_admin}/services")
config["services"] = resp.json()["data"]
# 导出路由
resp = requests.get(f"{self.kong_admin}/routes")
config["routes"] = resp.json()["data"]
# 导出上游
resp = requests.get(f"{self.kong_admin}/upstreams")
config["upstreams"] = resp.json()["data"]
return config
def convert_service(self, kong_service):
"""转换服务配置"""
return {
"name": kong_service["name"],
"desc": kong_service.get("tags", [""])[0],
"upstream": {
"type": "roundrobin",
"scheme": kong_service["protocol"],
"nodes": {
f"{kong_service['host']}:{kong_service['port']}": 1
},
"timeout": {
"connect": kong_service.get("connect_timeout", 60000) / 1000,
"send": kong_service.get("write_timeout", 60000) / 1000,
"read": kong_service.get("read_timeout", 60000) / 1000
}
}
}
def convert_route(self, kong_route, kong_service_id_map):
"""转换路由配置"""
apisix_route = {
"name": kong_route.get("name", kong_route["id"]),
"methods": kong_route.get("methods", ["GET"]),
"uris": kong_route.get("paths", ["/"]),
"service_id": kong_service_id_map.get(kong_route["service"]["id"])
}
# 转换插件
if kong_route.get("plugins"):
apisix_route["plugins"] = self.convert_plugins(kong_route["plugins"])
return apisix_route
def convert_plugins(self, kong_plugins):
"""转换插件配置"""
apisix_plugins = {}
for plugin in kong_plugins:
name = plugin["name"]
# JWT 插件转换
if name == "jwt":
apisix_plugins["jwt-auth"] = {
"header": "Authorization",
"query": "jwt",
"cookie": "jwt"
}
# 限流插件转换
elif name == "rate-limiting":
config = plugin["config"]
apisix_plugins["limit-req"] = {
"rate": config.get("minute", 100) / 60,
"burst": config.get("minute", 100) / 60 * 0.5,
"key": "remote_addr"
}
# CORS 插件转换
elif name == "cors":
config = plugin["config"]
apisix_plugins["cors"] = {
"allow_origins": config.get("origins", "*"),
"allow_methods": ",".join(config.get("methods", ["*"])),
"allow_headers": ",".join(config.get("headers", ["*"]))
}
return apisix_plugins
def import_to_apisix(self, apisix_config):
"""导入到 APISIX"""
headers = {"X-API-KEY": self.apisix_key}
# 创建服务
for service in apisix_config["services"]:
resp = requests.put(
f"{self.apisix_admin}/apisix/admin/services/{service['name']}",
headers=headers,
json=service
)
print(f"Created service: {service['name']}, Status: {resp.status_code}")
# 创建路由
for route in apisix_config["routes"]:
resp = requests.put(
f"{self.apisix_admin}/apisix/admin/routes/{route['name']}",
headers=headers,
json=route
)
print(f"Created route: {route['name']}, Status: {resp.status_code}")
def migrate(self):
"""执行迁移"""
print("Step 1: Exporting Kong configuration...")
kong_config = self.export_kong_config()
print("Step 2: Converting configuration...")
apisix_config = {
"services": [],
"routes": []
}
service_id_map = {}
for kong_svc in kong_config["services"]:
apisix_svc = self.convert_service(kong_svc)
apisix_config["services"].append(apisix_svc)
service_id_map[kong_svc["id"]] = apisix_svc["name"]
for kong_route in kong_config["routes"]:
apisix_route = self.convert_route(kong_route, service_id_map)
apisix_config["routes"].append(apisix_route)
print("Step 3: Importing to APISIX...")
self.import_to_apisix(apisix_config)
print("Migration completed!")
if __name__ == "__main__":
tool = MigrationTool(
kong_admin="http://kong:8001",
apisix_admin="http://apisix:9180",
apisix_key="your-api-key"
)
tool.migrate()总结
快速选型建议
┌─────────────────────────────────────────┐
│ 一句话选型建议 │
├─────────────────────────────────────────┤
│ │
│ Kong: 求稳定、要支持、插件多 │
│ │
│ APISIX: 求性能、要灵活、云原生 │
│ │
│ Nginx: 求简单、要轻量、可定制 │
│ │
│ Traefik: 求云原生、要自动化 │
│ │
│ Tyk: 求易用、要快速、功能全 │
└─────────────────────────────────────────┘关键要点
- 性能优先: APISIX > Traefik > Kong
- 生态成熟: Kong > APISIX > Traefik
- 云原生: APISIX ≈ Traefik > Kong
- 学习成本: Kong < Traefik < APISIX
- 商业支持: Kong > APISIX > Traefik
推荐组合
- 初创公司: Kong OSS + Konga
- 中型公司: APISIX + Dashboard + Prometheus
- 大型企业: Kong Enterprise + Kong Mesh
- 云原生: APISIX + K8s Ingress
- 高性能: APISIX + Redis + etcd 集群
💬 讨论
使用 GitHub 账号登录后即可参与讨论