Skip to content

APISIX 生产落地实战:从 Spring Cloud Gateway 到 API 网关统一治理

作者:yanshaodong | 发布时间:2026-08-18 | 分类:中间件 / API 网关


前言

网关是微服务架构里绕不开的一环。它扛着所有流量的入口,一旦出问题,影响面就是整个系统。

我们团队的业务从单体拆成微服务后,最初用的是 Spring Cloud Gateway(下文简称 SCG)。它和 Spring 技术栈天然契合,起步够快,但运行一段时间后,几个问题逐渐暴露出来:配置要改就得重新发布、插件生态不够用、高并发下性能吃紧、多协议(gRPC/TCP)支持乏力。

最终我们把网关整体迁移到了 Apache APISIX。这篇文章不打算写成「APISIX 是什么」的入门科普,而是复盘一次真实的网关迁移全流程:为什么换、怎么部署、怎么迁移、怎么运维,以及我们踩过的坑。

如果你正在纠结网关选型,或者计划把 APISIX 跑上生产,这篇应该能帮到你。


一、为什么要动网关

先说说把我们「逼」到换网关的几个真实痛点。

1. 灰度发布与流量治理能力弱

业务迭代时最理想的上线方式是灰度发布:先放一小部分流量到新版本,观察稳定后再逐步放量。SCG 要支持灰度、金丝雀、按比例切流,原生能力有限,通常得结合 Nacos 权重、自定义负载均衡策略或额外 Filter 来实现,开发和维护成本都不低;限流、熔断等流量治理策略的精细化控制同样需要自研。

2. 插件生态不够用

SCG 的扩展靠 Filter,能力本身够用,但社区里现成的、可复用的插件相对有限。很多通用能力——比如细粒度的限流、请求改写、可观测性增强——都得自己写,维护成本高。

3. 性能有天花板

SCG 基于 WebFlux 非阻塞模型,单机性能其实不差,但在高并发场景下,JVM 的 GC 抖动、内存占用,以及和业务服务争夺资源的问题,让我们在做容量规划时越来越被动。

4. 多协议支持乏力

业务里逐渐出现了 gRPC 内部调用、TCP 长连接等诉求,SCG 主要面向 HTTP,这些场景要另起炉灶。

这些问题叠加起来,让我们下定决心换一个「流量治理能力强、插件丰富、性能更强、多协议」的网关。


二、网关选型:为什么是 APISIX

我们把市面上主流的几款网关放到一起对比:

维度Nginx / OpenRestyKongSpring Cloud GatewayAPISIX
动态配置需 reload 或自研支持(PostgreSQL)需刷新(配合配置中心)支持(etcd,实时生效)
灰度/流量治理自研有限自研traffic-split 等插件开箱即用
插件体系自研 Lua/模块插件丰富Filter 机制80+ 内置插件
多协议HTTP/TCPHTTP/TCP主要 HTTPHTTP/gRPC/TCP/UDP/MQTT
性能高(基准)较高中(JVM 开销)高(OpenResty)
配置存储文件PostgreSQL配置中心/Nacosetcd
社区与生态成熟成熟Spring 生态Apache 顶级项目,活跃
运维成本

选型结论

APISIX 在几个关键维度上恰好命中我们的诉求:

  1. 流量治理与动态配置:灰度发布、金丝雀、按比例切流通过 traffic-split 等插件开箱即用,配置写入 etcd 后秒级生效、无需重启——这是打动我们的第一点。
  2. 插件生态:80+ 内置插件覆盖认证、限流、熔断、灰度、可观测性等,大部分需求开箱即用。
  3. 性能:基于 OpenResty(Nginx + LuaJIT),单核即可扛住很高的 QPS,且不依赖 JVM,资源占用可控。
  4. 技术栈契合:我们已有 Docker Swarm 编排 + etcd + Nacos 的基础设施,APISIX 的依赖正好落在现有体系内,不需要额外引入新组件。

补充一句:APISIX 由支流科技(API7.ai)开源,2019 年进入 Apache 孵化器,2020 年毕业成为 Apache 顶级项目,社区活跃度是选型时的加分项。


三、APISIX 架构与核心概念速览

理解 APISIX 的架构,是后面部署和运维的基础。它由三层组成:

控制面 Control PlaneAdmin API(RESTful)/ Dashboard管理路由、上游、插件、消费者等配置读写配置配置存储(etcd)以 key-value 存储全部配置通过 watch 机制实时推送变更watch 推送数据面 Data PlaneAPISIX 核心(Nginx + OpenResty + LuaJIT)接收流量,按路由规则转发、执行插件

核心概念

概念说明
Route(路由)匹配规则 + 目标,是 APISIX 的核心。包含匹配条件(uri、host、method 等)和绑定的插件
Upstream(上游)一组上游服务节点 + 负载均衡算法(轮询、一致性哈希等)
Service(服务)上游的抽象,路由可以指向 Service,Service 再指向 Upstream,便于批量管理
Consumer(消费者)API 的调用方,用于认证、限流等场景,通常配合 key-auth、jwt-auth 等插件
Plugin(插件)功能扩展单元,可作用于全局 / 路由 / 服务 / 消费者

etcd 数据模型

APISIX 的所有配置(路由、上游、插件、消费者等)都以 key-value 形式存储在 etcd 中。例如一条路由对应 /apisix/routes/{id} 这样的 key。APISIX 通过 etcd 的 watch 机制监听配置变更,一旦有更新,数据面会实时加载新配置,全程无需 reload。这正是「动态配置」的底层原理。

这也意味着:etcd 的可用性直接决定了 APISIX 的可用性,所以生产部署时 etcd 必须做高可用。


四、生产部署:Docker Swarm 下的高可用

我们的生产环境用 Docker Swarm 做容器编排,APISIX 和 etcd 都以 Swarm Service 的形式部署。

部署拓扑

用户流量Swarm 负载均衡gateway-101APISIXetcd-1gateway-102APISIXetcd-2gateway-103APISIXetcd-3etcd 集群(3 节点)Nacos业务服务

关键点:APISIX 无状态,随流量水平扩展;etcd 有状态,必须集群化并保证数据不丢。我们的三台节点 gateway-101/102/103 上,各部署一个 APISIX 实例和一个 etcd 节点,组成 3 节点 etcd 集群。同机部署简化了拓扑,同时 etcd 的 3 个奇数节点正好满足 Raft 选举的多数派要求。

docker-compose.swarm.yml 关键配置

yaml
version: "3.8"

services:
  apisix:
    image: apache/apisix:3.10.0-debian
    deploy:
      replicas: 3
      restart_policy:
        condition: any
      update_config:
        parallelism: 1
        delay: 10s
    ports:
      - "9080:9080"   # HTTP
      - "9443:9443"   # HTTPS
    environment:
      - TZ=Asia/Shanghai
    volumes:
      # 挂载主配置(etcd 地址、admin key 等)
      - ./apisix/config.yaml:/usr/local/apisix/conf/config.yaml:ro
      # 日志目录持久化
      - apisix-logs:/usr/local/apisix/logs
    networks:
      - apisix-net
    healthcheck:
      test: ["CMD", "curl", "-f", "http://127.0.0.1:9080/healthcheck"]
      interval: 10s
      timeout: 5s
      retries: 3

  etcd:
    image: bitnami/etcd:3.5
    deploy:
      replicas: 3
      placement:
        # 固定 etcd 到指定节点,保证数据目录稳定
        constraints: [node.labels.etcd == true]
    environment:
      - ETCD_NAME=etcd-{{.Task.Slot}}
      - ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379
      - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
      - ETCD_INITIAL_CLUSTER_TOKEN=apisix-etcd-cluster
      - ETCD_INITIAL_CLUSTER=etcd-1=http://etcd-1:2380,etcd-2=http://etcd-2:2380,etcd-3=http://etcd-3:2380
      - ETCD_INITIAL_CLUSTER_STATE=new
      - ETCD_DATA_DIR=/bitnami/etcd/data
    volumes:
      - etcd-data:/bitnami/etcd/data
    networks:
      - apisix-net

volumes:
  apisix-logs:
  etcd-data:

networks:
  apisix-net:
    driver: overlay

说明:etcd 集群在 Swarm 里做高可用需要配合 placement.constraints 固定节点、持久化数据卷,并正确配置 ETCD_INITIAL_CLUSTER。这是部署里最需要细心的一环,后面「踩坑复盘」会展开讲。生产环境的完整编排还包含 Nacos、证书和多环境隔离,这里只给出核心骨架。

APISIX 主配置 config.yaml 关键项

yaml
apisix:
  node_listen: 9080              # HTTP 监听端口
  enable_ipv6: false
  enable_control: true

deployment:
  role: traditional              # 使用 etcd 存储配置
  role_traditional:
    config_provider: etcd
  etcd:
    host:                         # etcd 集群地址
      - "http://etcd:2379"
    prefix: "/apisix"            # 配置 key 前缀
    timeout: 30

# 插件加载配置(按需启用,控制资源占用)
plugins:
  - real-ip
  - prometheus
  - limit-req
  - limit-count
  - skywalking
  - traffic-split
  - jwt-auth
  - key-auth

运维细节

  • 健康检查探针:APISIX 的 /healthcheck 接口默认不经过认证,适合做容器探针。我们用它做 Swarm 的 healthcheck,异常时自动重建实例。
  • 日志双路输出:APISIX 默认写文件,容器化场景下还要同时输出到 stdout,方便日志采集。通过 error_logaccess_log 配置 /dev/stdout 与文件双写(具体见下文踩坑第 3 条)。
  • 无状态水平扩展:只要 etcd 地址配置正确,新增 APISIX 实例无需任何额外动作,Swarm 扩容后自动加入集群。

五、网关迁移实战

迁移的核心思路是灰度切流 + 可快速回滚,绝不一次性全量切换。

1. 路由迁移:SCG → APISIX

SCG 的路由是 YAML/Java 配置,迁移到 APISIX 后变成 etcd 中的动态配置,通过 Admin API 或声明式 YAML 管理。

SCG 原始配置:

yaml
spring:
  cloud:
    gateway:
      routes:
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/order/**

迁移后的 APISIX 路由(Admin API 方式):

bash
curl http://127.0.0.1:9180/apisix/admin/routes/order-service \
  -H "X-API-KEY: ${ADMIN_KEY}" \
  -X PUT -d '
{
  "uri": "/api/order/*",
  "upstream": {
    "type": "roundrobin",
    "nodes": {
      "order-service:8080": 1
    }
  }
}'

迁移时建议先用脚本批量把 SCG 路由导出,再转成 APISIX 的路由配置,避免手抄出错。

2. 认证鉴权迁移

SCG 里的鉴权 Filter,迁移到 APISIX 对应插件:

SCG 能力APISIX 插件
JWT 校验jwt-auth
API Key / AppKeykey-auth
Basic Authbasic-auth
MD5 签名校验自定义插件(或结合 body-transformer)
IP 白名单ip-restriction

我们内部用 MD5 签名鉴权(AppKey + 时间戳 + 签名),APISIX 没有现成插件,就基于 Lua 写了一个自定义插件。自定义插件开发会在下文高级能力章节提一下。

3. 灰度切流与回滚

切流策略:先在 APISIX 建好全部路由 → 用 Swarm 的负载均衡/或 DNS 层把少量流量切到 APISIX → 观察监控指标 → 逐步放量 → 稳定后下线 SCG

bash
# 灰度期间可随时回滚:把流量切回 SCG 即可,APISIX 侧无需改动
# APISIX 侧用 traffic-split 插件按比例切流到不同上游
curl http://127.0.0.1:9180/apisix/admin/routes/order-service \
  -H "X-API-KEY: ${ADMIN_KEY}" -X PATCH -d '
{
  "plugins": {
    "traffic-split": {
      "rules": [
        { "weighted_upstreams": [ { "upstream_id": 1, "weight": 10 } ] }
      ]
    }
  }
}'

回滚的底气在于:APISIX 配置在 etcd 里,改配置秒级生效,且可以用 Admin API 快速还原。这是动态配置带来的最大红利。


六、可观测性建设

网关是可观测性的关键节点,我们搭了「Prometheus + SkyWalking + Grafana」组合。

1. Prometheus 指标采集

APISIX 通过 prometheus 插件暴露 /apisix/prometheus/metrics 指标,Prometheus 抓取即可。

关键点——Swarm 服务发现:Swarm 里服务是动态调度的,IP 不固定,我们用 Prometheus 的 dns_sd_configs 做服务发现,靠 Swarm 内置 DNS 把服务名解析成实例 IP。

yaml
# prometheus.yml
scrape_configs:
  - job_name: 'apisix'
    dns_sd_configs:
      - names:
          - 'tasks.apisix'        # Swarm 服务名,解析到所有副本
        type: 'A'
        port: 9091
        refresh_interval: 15s
    metrics_path: /apisix/prometheus/metrics
    relabel_configs:
      # 用 job label 标识服务,便于 Grafana 聚合筛选
      - source_labels: [__meta_dns_name]
        target_label: service

dns_sd_configs 是我们在 Swarm 环境里的关键技巧:不用手工维护 IP 列表,服务扩缩容后 Prometheus 自动发现新实例。

2. SkyWalking 链路追踪

APISIX 的 skywalking 插件把网关作为链路的起点,将 trace 信息透传给下游服务,形成完整链路。只需在 config.yamlplugins 里启用,并配置 SkyWalking OAP 地址。

yaml
plugins:
  - skywalking

plugin_attr:
  skywalking:
    service_name: apisix
    service_instance_name: apisix-instance-{{.Task.Slot}}
    endpoint_addr: http://skywalking-oap:12800

3. Grafana 监控大盘

Grafana 接入 Prometheus 数据源后,导入 APISIX 官方 Dashboard(或自建面板),重点监控:QPS、平均/分位延迟、错误率、上游健康状态、etcd 延迟


七、高级能力(简要)

生产上用到的几个进阶能力,这里点到为止,后续可单独展开。

  • 限流熔断limit-req(请求数限流)、limit-count(计数限流)、limit-conn(并发限流)、api-breaker(熔断)。
  • 灰度发布traffic-split 插件按权重切流,配合 canary 实现金丝雀发布。
  • 多协议:gRPC、TCP/UDP 代理,APISIX 天然支持。
  • 自定义插件:基于 Lua 编写,我们用它实现了 MD5 签名鉴权,开发成本远低于 SCG 写 Java Filter。

八、踩坑复盘

这是本文最想分享的部分。迁移过程中踩过的坑,整理成表:

#现象根因解决
1etcd 数据丢失重启后路由全部丢失,网关 404etcd 数据卷未持久化到稳定存储etcd 挂持久化卷 + 定期备份 etcd 快照
2配置热更新失效改了路由不生效,必须重启etcd watch 连接断开后未重连检查 etcd 集群稳定性,APISIX 与 etcd 网络链路
3容器日志丢失容器重建后日志没了日志只写文件,未输出 stdoutaccess_log/error_log 同时写文件 + /dev/stdout
4worker 数不合理高并发下 CPU 打不满worker_processes 未按核数配置设为 auto,按容器核数自动分配
5探针被打认证拦截healthcheck 一直失败触发重启探针路径未排除认证使用 /healthcheck 或配置探针路径跳过认证

九、总结与展望

迁移收益

  • 流量治理开箱即用:灰度发布、金丝雀、按比例切流通过插件即可实现,不再需要自研。
  • 性能提升:网关层资源占用下降,容量规划更从容。
  • 能力补齐:限流、灰度、多协议、可观测性开箱即用,少写了很多自研代码。
  • 运维简化:无状态水平扩展 + 动态配置,日常变更风险大幅降低。

后续规划

  • 深化多协议(gRPC/TCP)网关能力。
  • 自研更多业务插件,沉淀团队网关中台。
  • 探索 APISIX 与服务网格(Istio)的结合。