API 网关选型三个月对比:Kong / APISIX / SCG / Envoy / Higress

API 网关选型 3 个月,5 个候选(Kong / APISIX / Spring Cloud Gateway / Envoy / Higress)真实压测对比 + 配置示例 + 插件生态 + 限流灰度方案。最终选 APISIX 的 5 个理由 + 10 条避坑清单。日 5 亿请求峰值 20w QPS 实战。

2023 年底我们做 API 网关选型,在 Kong / APISIX / Spring Cloud Gateway / Envoy / Higress 五个候选里折腾了三个月,最终选 APISIX。本文把当时的对比、压测数据、踩坑过程整理出来,给在做类似选型的团队参考。结论先说:没有银弹,选型看团队栈和需求边界,不要看 GitHub star。

需求清单

业务要求:
- 日均 5 亿请求,峰值 20w QPS
- 路由数 500+(50 个微服务,每个 10 条左右路由)
- 多协议:HTTP/HTTPS、gRPC、WebSocket
- 鉴权:OAuth2 / JWT / API Key 三种
- 限流:基于 IP / 用户 / 接口三个维度
- 灰度发布:按 header / 流量比例 / 灰度名单
- 可观测:Prometheus + Skywalking trace
- 配置热更新(改路由不能重启)
- 团队栈:Java 为主,运维有 Python 经验
- 不希望搞 Lua(运维不会)

五个候选简评

候选            内核            配置       插件生态  性能 (QPS)  上手难度
=============================================================================
Kong            OpenResty(Lua)  declarative 强       30k         中
APISIX          OpenResty(Lua)  etcd        强       40k+        中
SCG (Spring)    Netty(Java)     YAML        中       15k         低(Java)
Envoy           C++             xDS protobuf 中      50k+        高
Higress (基于 Envoy) C++         CRD         强       50k+        中

压测对比

压测环境:4C8G × 3 节点,wrk -t 8 -c 200,空插件

延迟 p99(ms):
              空载       JWT 鉴权    JWT+限流+trace
Kong          18         42          75
APISIX        12         28          55
SCG           28         85          150
Envoy         8          22          48
Higress       9          23          50

QPS:
              空载       JWT 鉴权    JWT+限流+trace
Kong          32000      18000       9500
APISIX        42000      24000       13000
SCG           15500      8500        4200
Envoy         51000      27000       14500
Higress       49000      26000       14000

资源占用(满负载):
              CPU        内存
Kong          75%        220MB
APISIX        65%        180MB
SCG           90%        650MB(JVM)
Envoy         55%        130MB
Higress       58%        145MB

路由配置对比

# Kong 声明式(declarative)
_format_version: "3.0"
services:
  - name: order-service
    url: http://order-service.default.svc:8080
    routes:
      - name: order-route
        paths: ["/api/order"]
        plugins:
          - name: jwt
          - name: rate-limiting
            config:
              minute: 100
              policy: redis

# APISIX(etcd 存储,可 yaml/json 导入)
routes:
  -
    uri: /api/order/*
    upstream:
      type: roundrobin
      nodes:
        "order-service.default.svc:8080": 1
    plugins:
      jwt-auth:
        key: order-key
      limit-count:
        count: 100
        time_window: 60
        policy: redis-cluster
        redis_cluster_nodes:
          - "redis-0:7000"
          - "redis-1:7000"

# Spring Cloud Gateway
spring:
  cloud:
    gateway:
      routes:
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/order/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 100
                redis-rate-limiter.burstCapacity: 200

# Envoy(xDS)— 略复杂,通常用控制面如 Istio / Higress 生成

# Higress CRD(K8s)
apiVersion: networking.higress.io/v1
kind: McpBridge
metadata:
  name: order-route
spec:
  routeName: order
  match:
    uri:
      prefix: /api/order
  destination:
    host: order-service.default.svc
  filters:
    - name: jwt
    - name: rate-limit
      config:
        rules: [{ limit: 100, window: 60s, key: header.x-user-id }]

插件 / 扩展能力

Kong:
  - 官方 100+ 插件,生态成熟
  - 自定义插件用 Lua
  - 企业版有 GUI(开源版无)

APISIX:
  - 80+ 内置插件
  - 自定义可用 Lua,但更支持 Wasm
  - 提供 Java/Go/Python 的 Plugin Runner(JVM 进程外通信)
  - GUI(APISIX Dashboard)开源免费

SCG:
  - 跟 Spring 生态深度结合
  - 自定义 GatewayFilter 用 Java(团队友好)
  - 但生态不如 Kong/APISIX 丰富

Envoy:
  - 插件用 C++ 或 Wasm
  - 配置全用 protobuf 写,门槛高
  - 通常配合控制面(Istio / Higress)用

Higress:
  - 基于 Envoy + Istio,沉淀阿里多年实战
  - 自定义插件 Go/Wasm
  - K8s 原生,CRD 配置
  - 比 Istio 轻,网关场景专用

为什么最终选 APISIX

1. 性能强:同等硬件 QPS 比 Kong 高 30%,延迟低 30%
2. 配置存 etcd,改路由秒级生效(Kong 也行,SCG 要刷新)
3. APISIX Dashboard 开源免费,Kong GUI 要钱
4. Plugin Runner 支持 Java(团队栈友好)
5. 中国社区活跃,问题响应快
6. 文档中文版本完整
7. 基于 etcd 不需要数据库(Kong 要 Postgres 或 Cassandra)

但有一些坑:
- Lua 调试不友好,内置插件出问题排查难
- etcd 一旦挂,网关不能更新配置(运行不影响)
- Dashboard 历史版本 bug 多,现在稳定了
- 文档质量参差,有些插件示例缺失

APISIX 部署

# K8s 部署(Helm)
$ helm repo add apisix https://charts.apiseven.com
$ helm repo update

$ helm install apisix apisix/apisix \
    --namespace apisix --create-namespace \
    --set gateway.type=LoadBalancer \
    --set ingress-controller.enabled=true \
    --set etcd.enabled=true \
    --set etcd.replicaCount=3 \
    --set dashboard.enabled=true

# 验证
$ kubectl -n apisix get pods
NAME                                  READY   STATUS    RESTARTS
apisix-7d4f8b6cdf-x2k4t              1/1     Running   0
apisix-7d4f8b6cdf-9pj2m              1/1     Running   0
apisix-7d4f8b6cdf-z8nv3              1/1     Running   0
apisix-dashboard-6c7b9c8b-q3pwl     1/1     Running   0
apisix-etcd-0                        1/1     Running   0
apisix-etcd-1                        1/1     Running   0
apisix-etcd-2                        1/1     Running   0

# Admin API 添加路由
$ curl http://apisix-admin:9180/apisix/admin/routes/1 \
    -H "X-API-KEY: xxx" -X PUT -d '
{
  "uri": "/api/order/*",
  "name": "order",
  "upstream": {
    "type": "roundrobin",
    "nodes": {"order-service.default.svc:8080": 1}
  },
  "plugins": {
    "jwt-auth": {},
    "limit-count": {
      "count": 1000,
      "time_window": 60,
      "key": "remote_addr",
      "policy": "redis-cluster"
    },
    "prometheus": {},
    "skywalking": {"sample_ratio": 0.1}
  }
}'

自定义插件(Java Plugin Runner)

// 团队不熟 Lua,自定义插件用 Java + apisix-java-plugin-runner
@Component
public class UserContextEnrichPlugin implements PluginFilter {

    @Override
    public String name() {
        return "user-context-enrich";
    }

    @Override
    public void filter(PluginRequest request, PluginResponse response, PluginFilterChain chain) {
        // 从 JWT 解析用户信息,写入下游 header
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            try {
                Claims claims = JwtUtil.parse(token.substring(7));
                request.setHeader("X-User-Id", claims.getSubject());
                request.setHeader("X-User-Tenant", claims.get("tenant", String.class));
                request.setHeader("X-User-Roles", String.join(",", claims.get("roles", List.class)));
            } catch (Exception e) {
                response.setStatusCode(401);
                response.setBody("{\"error\":\"invalid token\"}");
                return;
            }
        }
        chain.filter(request, response);
    }
}

// 启动:
// java -jar apisix-java-plugin-runner.jar
// APISIX 通过 unix socket 调用 java runner

限流配置(三维度)

# IP 维度限流(防爬虫)
plugins:
  limit-conn:
    conn: 100
    burst: 50
    default_conn_delay: 0.1
    key_type: var
    key: remote_addr
    rejected_code: 429

# 用户维度限流(VIP / 普通)
plugins:
  limit-count:
    count: 1000
    time_window: 60
    key_type: var
    key: http_x_user_id
    policy: redis-cluster
    redis_cluster_nodes:
      - "redis-cluster:6379"

# 接口维度(秒杀防刷)
plugins:
  limit-req:
    rate: 100      # 每秒 100 个
    burst: 50      # 允许突发 50
    key_type: var
    key: uri

灰度发布

# traffic-split 插件
plugins:
  traffic-split:
    rules:
      - match:
          - vars:
              - ["http_x_canary", "==", "true"]   # header 灰度
        weighted_upstreams:
          - upstream_id: "order-canary"
            weight: 1
      - weighted_upstreams:
          - upstream_id: "order-stable"
            weight: 95
          - upstream_id: "order-canary"
            weight: 5                              # 5% 流量灰度

监控与可观测

# Prometheus 插件
plugins:
  prometheus:
    prefer_name: true

# Skywalking trace
plugins:
  skywalking:
    sample_ratio: 0.1   # 10% 采样
    endpoint_addr: http://skywalking-oap:12800

# 访问日志(异步写 Kafka)
plugins:
  kafka-logger:
    broker_list:
      - "kafka-1:9092"
      - "kafka-2:9092"
    kafka_topic: "apisix-access-log"
    timeout: 3
    batch_max_size: 100
    inactive_timeout: 5

选型决策树

团队是 Java 栈,简单需求 → SCG
团队是 Java 栈,需要高性能 + 复杂插件 → APISIX + Java Plugin Runner
有 OpenResty / Lua 经验 → Kong 或 APISIX
全员云原生 + K8s 重度用户 → Higress 或 Envoy
追求极致性能 → Envoy
要图形化管理 + 多租户 → Kong Enterprise(付费)或 APISIX Dashboard
不想自己运维 → 云厂商 API 网关(腾讯 API 网关 / 阿里 EDAS / AWS API Gateway)

避坑清单

  1. 不要直接看 GitHub star,要看实际场景的性能压测
  2. 团队熟悉的栈最重要,Java 团队选 Lua 网关有学习成本
  3. 插件可用性 ≠ 插件好用,要看文档完整度和社区活跃度
  4. 限流别只用网关,业务侧也要兜底
  5. JWT 验证放网关,签发放业务,撤销机制要想清楚
  6. etcd / Redis 一定要 HA,否则网关瘫
  7. Dashboard 不要暴露公网,加双因素
  8. 升级前在测试环境跑全量 case,Lua 插件兼容性偶尔会断
  9. 路由数量上千的话压测路由匹配性能,前缀树 vs hash 差别大
  10. 不要在网关写业务逻辑,网关是路由 + 横切关注点

三个月对比的反思

选型这事最忌讳"看大家用什么"。Kong 在国外强,APISIX 在国内强,SCG 在 Java 团队香,Envoy 在云原生圈热,各有自己的护城河。最终我们选 APISIX 是因为性能 + 配置存 etcd + Java Plugin Runner + 中文社区 + 免费 Dashboard 五点叠加,不是单一指标决定。如果你的团队是纯 Spring 生态,SCG 反而更顺手。建议每个候选拿真实业务流量压测一周再决定,纸面参数和实际跑起来差别大。

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

PostgreSQL bloat 治理实战:1.2 亿行表从 380GB 压到 152GB

2026-5-19 11:58:41

技术教程

Spring Boot 3 升级两个月实录:javax→jakarta + 30 万行代码 + 40 个微服务

2026-5-19 12:02:40

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索