CatLove Cloud 技术团队24 分钟阅读

Kong API 网关 + Cloudflare 实战:从零到万 QPS 的优化之路

分享我们从零开始用 Kong + Cloudflare 搭建高性能 API 网关的完整经验,包括架构选型、性能调优、实战踩坑和成本优化。

#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

理由很简单:

  1. Kong 插件生态完善(100+ 插件)
  2. Cloudflare Tunnel 免费,还自带 DDoS 防护
  3. 两者配合延迟低(国内外都快)

但是!部署过程远比想象中复杂。


第一阶段:基础架构搭建

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?

  1. 国内访问慢 - 直连海外服务器延迟高
  2. DDoS 防护 - 自己防护成本太高
  3. 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)有几个问题:

  1. 多实例数据不共享
  2. 重启就丢失
  3. 内存占用高

Redis 可以:

  • 跨实例共享缓存
  • 持久化数据
  • 支持分布式限流

Q4: 性能瓶颈在哪里?

A: 我们遇到的瓶颈按顺序:

  1. 数据库连接 - 增加连接池解决
  2. 上游延迟 - 缓存解决
  3. 单点故障 - 多实例 + 负载均衡
  4. 网络延迟 - Cloudflare CDN

经验:一定要监控,没有数据瞎优化等于浪费时间。

Q5: 需要多少服务器资源?

A: 我们的配置(支持 QPS 12K+):

| 组件 | 配置 | 数量 | |------|------|------| | Kong Gateway | 2C4G | 3 台 | | PostgreSQL | 2C4G | 1 台(主从) | | Redis | 1C2G | 1 台 | | Nginx LB | 1C1G | 1 台 |

总成本:$120/月(包含备份)


经验总结

踩过的坑 ❌

  1. 没做监控就上线 - 出问题找不到原因
  2. 缓存没设置过期 - Redis 内存爆了
  3. 限流规则太严格 - 合法用户被误杀
  4. 只部署单实例 - 一挂全挂

最佳实践 ✅

  1. 分阶段优化 - 先基础功能,再性能
  2. 用数据说话 - Prometheus 监控是必须的
  3. 灰度发布 - 新配置先 10% 流量测试
  4. 备份策略 - 数据库每日备份,配置版本控制

适用场景

适合用 Kong 的情况

  • API 数量 > 10
  • 需要统一认证、限流
  • 团队有一定运维能力
  • 对成本敏感

不适合的情况

  • 简单的反向代理(Nginx 够了)
  • 团队全是前端,没人会运维
  • 预算充足,想省心(用 AWS API Gateway)

下一步计划

  1. 服务网格 - 考虑引入 Istio
  2. 多区域部署 - 美国、欧洲、亚洲各一套
  3. 自动扩缩容 - Kubernetes HPA
  4. 更精细的监控 - 加入 OpenTelemetry

有问题欢迎讨论:tech@catlove.cc


本文所有配置都经过生产环境验证,压测数据真实可靠。

C
CatLove Cloud 技术团队
CatLove Cloud 技术团队