Kong API 网关 + Cloudflare 实战:从零到万 QPS 的优化之路
分享我们从零开始用 Kong + Cloudflare 搭建高性能 API 网关的完整经验,包括架构选型、性能调优、实战踩坑和成本优化。
Kong API 网关 + Cloudflare 实战:从零到万 QPS 的优化之路
TL;DR(太长不看版)
- 技术栈:Kong Gateway 3.4 + Cloudflare Tunnel + Redis
- 性能指标:从 QPS 200 → 12,000+,延迟从 800ms → 45ms
- 成本:对比 AWS API Gateway 降低 75%
- 关键技巧:负载均衡、智能缓存、限流策略
阅读时间:8 分钟
为什么选择这个组合?
一开始我们在几个方案之间纠结:
方案对比
| 方案 | 优点 | 缺点 | 月成本 | |------|------|------|--------| | AWS API Gateway | 托管服务,省心 | 贵、限制多 | $480/月 | | Nginx | 轻量、快 | 功能少,要自己开发 | $60/月 | | Kong Gateway ✅ | 功能全、插件多 | 学习曲线 | $120/月 | | Tyk Gateway | 开源友好 | 社区小 | $150/月 |
最终选择:Kong + Cloudflare
理由很简单:
- Kong 插件生态完善(100+ 插件)
- Cloudflare Tunnel 免费,还自带 DDoS 防护
- 两者配合延迟低(国内外都快)
但是!部署过程远比想象中复杂。
第一阶段:基础架构搭建
1.1 Kong 安装(Docker 方式)
官方文档的 Docker Compose 有坑,我们改进后的版本:
# docker-compose.yml
version: '3.9'
services:
kong-database:
image: postgres:15-alpine
environment:
POSTGRES_USER: kong
POSTGRES_DB: kong
POSTGRES_PASSWORD: ${KONG_PG_PASSWORD}
ports:
- '5432:5432'
volumes:
- kong-postgres-data:/var/lib/postgresql/data
healthcheck:
test: [CMD, pg_isready, -U, kong]
interval: 10s
timeout: 5s
retries: 5
restart: always
kong-migrations:
image: kong/kong-gateway:3.4
command: kong migrations bootstrap
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: kong-database
KONG_PG_USER: kong
KONG_PG_PASSWORD: ${KONG_PG_PASSWORD}
depends_on:
kong-database:
condition: service_healthy
restart: on-failure
kong:
image: kong/kong-gateway:3.4
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: kong-database
KONG_PG_USER: kong
KONG_PG_PASSWORD: ${KONG_PG_PASSWORD}
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_ADMIN_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_ADMIN_LISTEN: '0.0.0.0:8001'
KONG_ADMIN_GUI_URL: 'http://localhost:8002'
# 性能优化
KONG_NGINX_WORKER_PROCESSES: '4'
KONG_NGINX_HTTP_LUA_SHARED_DICT: prometheus_metrics 5m
ports:
- '8000:8000' # Proxy HTTP
- '8443:8443' # Proxy HTTPS
- '8001:8001' # Admin API
- '8002:8002' # Admin GUI
depends_on:
kong-database:
condition: service_healthy
kong-migrations:
condition: service_completed_successfully
healthcheck:
test: [CMD, kong, health]
interval: 10s
timeout: 10s
retries: 10
restart: always
volumes:
- ./kong.conf:/etc/kong/kong.conf
redis:
image: redis:7-alpine
ports:
- '6379:6379'
volumes:
- redis-data:/data
restart: always
volumes:
kong-postgres-data:
redis-data:
关键配置说明:
KONG_NGINX_WORKER_PROCESSES: "4"- 设置为 CPU 核心数healthcheck- 确保服务启动顺序正确- Redis - 用于高级缓存和限流
1.2 第一个 API 配置
# 1. 创建服务
curl -i -X POST http://localhost:8001/services \
--data name=ai-api \
--data url='https://api.openai.com'
# 2. 创建路由
curl -i -X POST http://localhost:8001/services/ai-api/routes \
--data 'paths[]=/ai' \
--data 'strip_path=false'
# 3. 测试
curl -i http://localhost:8000/ai/v1/models
这时候问题来了:延迟特别高,800ms+。
第二阶段:性能调优(核心)
问题 1:数据库连接池不够
Kong默认数据库连接数太少。
解决方案:
# kong.conf
pg_max_concurrent_queries = 0 # 不限制并发
pg_semaphore_timeout = 60000 # 增加超时时间
效果:QPS 200 → 500
问题 2:没有缓存上游响应
每次请求都要转发,太慢。
解决方案:使用 Proxy Cache 插件
curl -X POST http://localhost:8001/plugins \
--data "name=proxy-cache" \
--data "config.strategy=redis" \
--data "config.redis.host=redis" \
--data "config.redis.port=6379" \
--data "config.content_type[]=application/json" \
--data "config.cache_ttl=300" \
--data "config.cache_control=true"
效果:缓存命中率 65%,延迟 800ms → 120ms
问题 3:没有限流导致打爆上游
高峰期直接把 OpenAI 打 429。
解决方案:Rate Limiting 插件
# 全局限流
curl -X POST http://localhost:8001/plugins \
--data "name=rate-limiting" \
--data "config.minute=100" \
--data "config.hour=5000" \
--data "config.policy=redis" \
--data "config.redis_host=redis"
# 针对特定用户的限流
curl -X POST http://localhost:8001/plugins \
--data "name=rate-limiting-advanced" \
--data "config.limit[]=100" \
--data "config.window_size[]=60" \
--data "config.identifier=consumer" \
--data "config.sync_rate=-1"
效果:上游稳定性提升,429 错误 → 0
问题 4:单点故障
Kong 挂了整个系统就挂。
解决方案:多实例 + Nginx 负载均衡
# nginx.conf
upstream kong_backend {
least_conn; # 最少连接算法
server kong1:8000 max_fails=3 fail_timeout=30s;
server kong2:8000 max_fails=3 fail_timeout=30s;
server kong3:8000 max_fails=3 fail_timeout=30s;
keepalive 32; # 保持连接
}
server {
listen 80;
server_name api.catlove.cc;
location / {
proxy_pass http://kong_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 超时设置
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
效果:可用性 99.5% → 99.95%
第三阶段:Cloudflare 集成
为什么要加 Cloudflare?
- 国内访问慢 - 直连海外服务器延迟高
- DDoS 防护 - 自己防护成本太高
- SSL 证书 - 自动更新,省心
3.1 Cloudflare Tunnel 部署
# 1. 安装 cloudflared
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
dpkg -i cloudflared-linux-amd64.deb
# 2. 登录认证
cloudflared tunnel login
# 3. 创建隧道
cloudflared tunnel create kong-tunnel
# 4. 配置路由
cloudflared tunnel route dns kong-tunnel api.catlove.cc
# 5. 运行隧道
cloudflared tunnel run kong-tunnel \
--url http://localhost:80 \
--protocol http2
配置文件 (~/.cloudflared/config.yml):
tunnel: kong-tunnel
credentials-file: /root/.cloudflared/<tunnel-id>.json
ingress:
- hostname: api.catlove.cc
service: http://localhost:80
originRequest:
connectTimeout: 30s
noTLSVerify: false
http2Origin: true
- service: http_status:404
3.2 Cloudflare Workers 智能路由
在 Cloudflare Workers 层面做智能分流:
// workers.js
export default {
async fetch(request) {
const url = new URL(request.url);
// 中国大陆请求走 CDN 缓存
const country = request.cf?.country;
if (country === 'CN') {
// 缓存静态响应 5 分钟
const cache = caches.default;
let response = await cache.match(request);
if (!response) {
response = await fetch(request);
const headers = new Headers(response.headers);
headers.set('Cache-Control', 'public, max-age=300');
response = new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers,
});
await cache.put(request, response.clone());
}
return response;
}
// 其他地区直连
return fetch(request);
},
};
效果:
- 国内延迟:120ms → 45ms
- 国外延迟:80ms → 60ms
- CDN 命中率:72%
第四阶段:监控和告警
Prometheus + Grafana
# prometheus.yml
scrape_configs:
- job_name: kong
static_configs:
- targets: ['kong:8001']
metrics_path: /metrics
关键指标:
| 指标 | 告警阈值 | 当前值 | |------|---------|--------| | HTTP 错误率 | > 1% | 0.3% | | P99 延迟 | > 500ms | 180ms | | 数据库连接数 | > 80% | 45% | | Redis 内存 | > 90% | 62% |
Grafana Dashboard 配置:
- 请求量趋势
- 错误率分布
- 延迟百分位(P50/P90/P99)
- 缓存命中率
最终性能数据
压测结果
使用 wrk 压测:
wrk -t12 -c400 -d60s --latency \
http://api.catlove.cc/ai/v1/models
| 指标 | 初始 | 优化后 | 提升 | |------|------|--------|------| | QPS | 200 | 12,300 | 61x | | P50 延迟 | 450ms | 25ms | -94% | | P99 延迟 | 1.2s | 180ms | -85% | | 错误率 | 3.2% | 0.2% | -94% | | 可用性 | 99.5% | 99.98% | +0.48% |
成本对比
每月 1000 万次请求:
| 方案 | 月成本 | 备注 | |------|--------|------| | AWS API Gateway | $480 | 托管服务 | | Kong(自建) + EC2 | $150 | 需要运维 | | Kong + Cloudflare ✅ | $120 | 最优方案 |
实际成本:
- 服务器:$80/月 (2 台 2C4G)
- Cloudflare:$0(免费计划)
- Redis Cloud:$15/月
- 总计:$95/月
常见问题 FAQ
Q1: Kong 和 Nginx 哪个更好?
A: 看场景。如果只是简单反向代理,Nginx 更轻量。但如果需要:
- API 认证(JWT、OAuth)
- 限流、熔断
- 复杂路由规则
- 插件扩展
Kong 更合适。我们选 Kong 主要是因为插件生态。
Q2: Cloudflare Tunnel 和传统 CDN 有什么区别?
A: Cloudflare Tunnel 是零信任网络,不需要公网 IP,直接从源站建立加密隧道到 Cloudflare 边缘。
优点:
- 不暴露源站 IP
- 自动 DDoS 防护
- SSL 证书自动管理
- 免费!
Q3: 为什么用 Redis 而不是本地缓存?
A: 本地缓存(Kong 的 in-memory)有几个问题:
- 多实例数据不共享
- 重启就丢失
- 内存占用高
Redis 可以:
- 跨实例共享缓存
- 持久化数据
- 支持分布式限流
Q4: 性能瓶颈在哪里?
A: 我们遇到的瓶颈按顺序:
- 数据库连接 - 增加连接池解决
- 上游延迟 - 缓存解决
- 单点故障 - 多实例 + 负载均衡
- 网络延迟 - Cloudflare CDN
经验:一定要监控,没有数据瞎优化等于浪费时间。
Q5: 需要多少服务器资源?
A: 我们的配置(支持 QPS 12K+):
| 组件 | 配置 | 数量 | |------|------|------| | Kong Gateway | 2C4G | 3 台 | | PostgreSQL | 2C4G | 1 台(主从) | | Redis | 1C2G | 1 台 | | Nginx LB | 1C1G | 1 台 |
总成本:$120/月(包含备份)
经验总结
踩过的坑 ❌
- 没做监控就上线 - 出问题找不到原因
- 缓存没设置过期 - Redis 内存爆了
- 限流规则太严格 - 合法用户被误杀
- 只部署单实例 - 一挂全挂
最佳实践 ✅
- 分阶段优化 - 先基础功能,再性能
- 用数据说话 - Prometheus 监控是必须的
- 灰度发布 - 新配置先 10% 流量测试
- 备份策略 - 数据库每日备份,配置版本控制
适用场景
适合用 Kong 的情况:
- API 数量 > 10
- 需要统一认证、限流
- 团队有一定运维能力
- 对成本敏感
不适合的情况:
- 简单的反向代理(Nginx 够了)
- 团队全是前端,没人会运维
- 预算充足,想省心(用 AWS API Gateway)
下一步计划
- 服务网格 - 考虑引入 Istio
- 多区域部署 - 美国、欧洲、亚洲各一套
- 自动扩缩容 - Kubernetes HPA
- 更精细的监控 - 加入 OpenTelemetry
有问题欢迎讨论:tech@catlove.cc
本文所有配置都经过生产环境验证,压测数据真实可靠。