资讯动态

Apache APISIX全流量网关:etcd动态配置与O(k)路由深度实践

发布时间:2026/9/19 10:35:55 来源:尧图企业网站定制
简介面向云原生架构师、平台工程师与微服务团队这份基于Apache APISIX的全流量API网关PDF资料系统阐释了云原生时代API网关的定位与选型维度并从数据面/控制面分离架构、全动态路由、插件机制、L4/L7流量处理等角度拆解了Apache APISIX替代Nginx/Envoy、承担K8s Ingress与IoT/零信任网关等落地场景。包体为1个6.58MB的PDF文档内容来自2023云原生社区研讨会保留演讲完整图文可供团队内部分享与个人精读。资料同时对比了APISIX与Kong在路由复杂度、配置生效时间、高可用架构上的差异并给出公有云、航天、金融、在线教育等行业案例能帮助读者快速判断网关技术路线、规避选型陷阱。目前已有321人学习适合作为技术调研与二次开发的基础参考。1. 云原生入口的第一站Apache APISIX 全流量 API 网关云原生入口的第一站绕不开 API 网关从 2023 年的视角回看Apache APISIX 几乎每次技术讨论都会被拿来当全流量 API 网关的参照系。它既不是简单的 Nginx 二开也不是给管理后台加了层壳而是把数据面、控制面拆开之后让路由、SSL 证书、上游节点、插件全部动态化的一套接入层方案。这篇文章不是官方文档复述我会从“关掉 reload”这个瞬间讲起把 etcd 配置下发、O(k) 路由匹配、南北向与东西向流量统一收口、压测验证这些关键点逐一拆开。做微服务网关选型的读者尤其是已经踩过配置要 reload、流量要分两套 proxy 的团队会从这篇文章里看到一套可复现的落地方案。2. 控制面与数据面分离etcd Watch 让 reload 成为历史2.1 为什么配置中心不用 MySQL/PostgreSQL早期 API 网关大多把路由、上游、证书放在数据库里服务启动时加载一次改配置要靠管理端写库再发信号让每个节点重新加载。这个模型有两个硬伤一是数据库本身成了单点网关集群的可用性被一个主库绑死二是节点定期轮询数据库配置变更到最终生效要等一个轮询周期通常 5 秒左右对线上灰度、快速降级来说太慢。APISIX 选择 etcd 作为唯一配置源看中的是分布式一致性、watch 推送和 Lease 机制。控制面对外暴露 Admin API写入的任何配置都落到 etcd数据面节点通过 watch 监听相关 key配置变更事件在毫秒级到达所有节点。nginx.conf 里不再需要动态生成的 upstream 块因为路由匹配时不直接依赖 nginx 静态配置文件而是由 lua-resty-radixtree 在请求阶段从内存里的共享字典读取。2.2 创建第一条动态路由Admin API 实操在不 reload 的情况下上线一条路由只需要两步准备一个 APISIX 节点确认 9180控制面 Admin API和 9080数据面 HTTP两个端口处于监听状态。然后调用 Admin API 写入路由。# 写入/更新一条路由URI 为 /hello后端两个节点轮询附带限流插件 curl -i -X PUT http://127.0.0.1:9180/apisix/admin/routes/hello \ -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 \ -d { uri: /hello, upstream: { type: roundrobin, nodes: { 192.168.1.10:8080: 1, 192.168.1.11:8080: 1 } }, plugins: { limit-count: { count: 100, time_window: 60, rejected_code: 503 } } } # 验证不重载 nginx直接请求数据面端口 curl -i http://127.0.0.1:9080/hello这条命令里PUT是幂等操作同一个id反复提交就是更新id取hello语义清晰。X-API-KEY是 Admin API 的访问凭证默认值来自config.yaml生产必须改掉。uri是精确匹配路径upstream.nodes后面跟着键值对键是ip:port值是权重limit-count插件做固定窗口计数time_window为 60 秒count为 100。修改任意字段后再执行一次PUT请求下一发就会走新配置process 不需要重启也不需要nginx -s reload。2.3 全动态的粒度路由、上游、SSL 证书、插件从上面的配置就能看到动态更新不只是一条路由还包括上游节点列表和插件参数。SSL 证书同样走/apisix/admin/ssls接口管理证书轮换时写 etcd各节点通过 Admin API 的 watch 感知旧证书到新证书切换不需要 reload。插件开启、关闭、调整参数也是同样的路径甚至可以在不中断服务的情况下升级单个插件的 Lua 代码。这一点在微服务治理里价值很大临时把某个接口的流量复制到影子环境、给线上接口加一道参数校验、紧急熔断某个上游都能通过一次 API 调用完成把过去“改配置、reload、观察”的流程压缩到几秒钟。2.4 APISIX 与 Kong 的架构对比很多人选型时会把 APISIX 和 Kong 放一起比较核心差异基本都集中在架构上。对比项Apache APISIXKong底层依赖Nginx etcdNginx PostgreSQL/Cassandra高可用无单点数据面存活即可用依赖数据库数据库故障会影响配置下发配置下发etcd watch事件驱动实测局域网内小于 1 毫秒定期轮询数据库默认约 5 秒生效路由匹配基于 radix tree复杂度 O(k) 与 uri 长度相关默认遍历路由数越多时延越高IP 匹配自研 ipmatcherO(1)新版本已改用 APISIX 的 IP 匹配库本地技术支持商业化公司1 小时响应远程支持为主Kong 的架构在云原生场景里并不算错但数据库轮询这个路径决定了配置生效延迟很难降下来。APISIX 把 etcd 放到核心链路本质上是用一个分布式一致性的基础设施换掉了“管理库 轮询”这套旧组合。控制面挂掉不影响数据面当前已有的路由转发数据面节点通过本地缓存继续服务这一点对网关这种关键链路尤其重要。3. 路由匹配与负载均衡O(k) 背后是 radix tree不只是广告3.1 radix tree 为什么能做到 O(k)很多网关宣传性能时只说 QPSAPISIX 的路由复杂度是 O(k)k 是 uri 长度与路由数量无关。这个结论的前提是路由使用 radix tree压缩前缀树组织匹配时把请求路径的字符逐个和树的分支比较走到叶子就命中了。同样一万条路由遍历匹配平均要比较几千次而 radix tree 只需要比较路径长度的量级。Kong 默认用正则/遍历匹配所以官方性能对比里随着路由数量增长APISIX 的优势会越来越明显。生产环境如果路由表有几千条这个差异不只是数字游戏请求时延的尾延迟会稳定得多。APISIX 的 IP 匹配也单独做了优化IP/网段的判断通过 ipmatcher 库编译成高效的查找结构匹配复杂度是 O(1)。大量来源 IP 的黑白名单场景下CPU 不会因为 IP 数量线性增长被打满。这里有个容易被忽略的细节如果路由里带了vars条件或者正则表达式匹配路径会退回到 Nginx 的location后执行正则性能模型就从 radix tree 变成正则匹配了。所以路由设计要遵循“精确前缀为主正则兜底”的原则。3.2 用 Nginx 变量做条件路由APISIX 的路由条件支持 Nginx 的全部内置变量包括$http_user_agent、$remote_addr、$host、$arg_xxx等。构造路由时vars字段通过一个二维数组表达条件每个三元组是[变量, 操作符, 值]。{ uri: /apisix/status, vars: [ [http_user_agent, ~~, curl/*], [remote_addr, in, [10.0.0.0/8, 192.168.0.0/16]] ], upstream: { type: roundrobin, nodes: { 10.10.1.1:1980: 1 } } }~~操作符是大小写不敏感的正则匹配in是网段/集合判断操作符还支持、~、、等。这里用两个条件做了一个典型场景只允许来自内网网段、使用 curl 的请求访问状态接口其他请求直接 404。实际使用时可以把remote_addr换成arg_key在边缘网关做带密钥的调试入口。3.3 自定义负载均衡挂载点多数网关支持 roundrobin、chash、least_conn但如果你想按业务排队长度、按机房成本或者按自定义错误率选择上游传统方案只能写死在代码里或者等厂商支持。APISIX 把balancer阶段暴露给插件允许在 Lua 层面完全接管节点选择逻辑。-- 自定义负载均衡插件片段在 balancer 阶段设置最终节点 local function pick(ctx, nodes) -- 这里可以实现任意策略按 queue depth、按成本权重、按亲和性 for _, node in ipairs(nodes) do if node.weight 0 then return node end end end function _M.balancer(ctx) local node pick(ctx, ctx.upstream.nodes) ctx.balancer function() -- ngx.balancer.set_more_tries(1) 允许失败后重试其他节点 ngx.balancer.set_more_tries(1) ngx.balancer.set_current_peer(node.host, node.port) end end这段代码展示了挂载点的用法_M.balancer会在每次请求进入 upstream 阶段前被回调pick函数可以返回自定义选中的节点ctx.balancer被赋值后APISIX 会在 Nginx 的balancer_by_lua阶段执行真正的连接设置。set_more_tries决定失败重试次数set_current_peer指定实际连接的地址。需要造轮子的人不用改 APISIX 源码写一个插件挂到路由上即可。4. 全流量接入南北向、东西向与 L4/L7 协议扩展4.1 Nginx 在云原生下面的三个短板传统南北向接入基本是 Nginx Lua 的组合到了云原生阶段问题逐渐暴露配置热加载做不到社区活跃度下降非 HTTP 流量Dubbo、MQTT、gRPC、TCP/UDP接入需要额外组件。更关键的是Service Mesh 把微服务之间的东西向流量也纳入治理范围Nginx 在代理性能和治理能力上很难和 Envoy、APISIX 竞争。APISIX 的思路是底层网络库沿用 Nginx但把路由匹配、配置管理和 C 模块全部替换成动态化方案再通过插件体系补齐可观测性、认证、限流、协议转换。这样既能蹭到 Nginx 的稳定性又能获得云原生所需的动态能力。4.2 用 APISIX Ingress Controller 接入 KubernetesKubernetes 里的 Ingress 流量要么交给云厂商的 LB要么交给 ingress controller。APISIX 的 ingress controller 做的事情是把 Ingress 资源翻译成 APISIX 的 Route、Upstream、SSL 配置写入 etcd由 APISIX 数据面执行转发。下面这个 Ingress 在集群里声明了一条从域名到服务的路由apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: order-ingress annotations: kubernetes.io/ingress.class: apisix spec: rules: - host: demo.example.com http: paths: - path: /order pathType: Prefix backend: service: name: order-svc port: number: 8080kubernetes.io/ingress.class: apisix告诉集群使用 APISIX 的 controller/order前缀匹配会把请求转发到order-svc的 8080 端口。controller 感知到 Ingress 变化后自动在 APISIX 里创建对应的路由。这里有个细节值得注意prefix匹配在 APISIX 里会映射为uri的前缀匹配而不是 Nginx 的location匹配所以 path 的边界行为要以 APISIX 为准。生产环境更推荐用 CRD如ApisixRoute来管理它可以表达权重、重写、插件等 Ingress 注解表达不了的能力。4.3 L4/L7 与多协议TCP、UDP、MQTT、gRPC全流量网关的另一个维度是协议。APISIX 通过stream_proxy处理 L4 流量通过插件支持 MQTT 代理、Dubbo 代理、gRPC 代理和 REST 与 gRPC 的协议转换。下面是可以直接放进config.yaml的 L4 监听配置apisix: proxy_mode: httpstream stream_proxy: tcp: - addr: 9100 tls: true udp: - addr: 9200配置里proxy_mode声明同时启用 HTTP 和 stream 两种模式stream_proxy.tcp监听 9100 端口并开启 TLSstream_proxy.udp监听 9200。L4 流量的路由通过/apisix/admin/stream_routes管理可以按server_addr、server_port、remote_addr做匹配。对于 IoT 场景启用 MQTT 插件后APISIX 可以直接作为 MQTT 接入网关把设备连接和鉴权统一收口到网关层。全流量场景覆盖流量方向典型协议APISIX 扮演的角色南北向接入HTTP/HTTPS反向代理、限流、认证、灰度发布东西向微服务HTTP/gRPC/Dubbo服务间路由、负载均衡、故障注入边缘接入MQTT/TCP/UDPIoT 网关、L4 代理服务网格HTTP/gRPC mTLSsidecar/数据面替代这种统一接入的价值在于团队不需要同时维护 Nginx、HAProxy、MQTT Broker、gRPC Gateway 多套接入组件控制面只有一套监控指标也能统一打到 Prometheus。4.4 身份认证与零信任网关APISIX 的身份认证插件支持 Basic Auth、JWT、Key Auth、OpenID Connect还可以对接 Auth0、Okta 等身份提供商。零信任网关场景下每个请求都必须经过身份校验和权限校验APISIX 通过openid-connect插件充当 Relying Party配合 mTLS 双向认证把终端身份和设备证书验证全部放在网关入口。和传统反代只做转发不同这套体系让网关不再是透明通道而是真正参与业务安全决策协议转换、身份断言、动态令牌校验都在请求进入业务服务之前完成。安全团队也少了一份“服务自己还要处理认证”的心智负担。5. 验证与压测像验收生产网关一样做端到端检查5.1 验证配置下发是否真的“不需要 reload”用etcdctl直接观察配置变更事件是最直接的验证方式。先开启一个终端监听 etcd 的 key 变化再调用 Admin API 改配置能看到PUT事件在毫秒级出现。etcdctl watch --prefixtrue /apisix/routes另一个更贴近用户的验证方法是打开 APISIX 的 error.log修改一条路由后观察日志中是否有reload相关动作。正常情况下一秒内新规则生效日志里只有请求访问记录没有任何 reload 或 worker 重启痕迹。5.2 健康检查参数被动检查压低配置成本全流量网关都建议开启被动健康检查只有请求失败达到阈值才摘除节点主动健康检查会定期探测配置不当反而可能打爆后端。典型的被动检查配置在 upstream 的healthcheck字段里passive.unhealthy.http_failures表示连续几次 HTTP 错误判定节点不健康healthy.successes表示恢复需要连续成功次数。参数设置上http_failures建议 3 到 5 次时间窗口 5 到 10 秒避免单次抖动直接摘除。5.3 压测与性能预期压测建议用 wrk 直接打数据面端口关闭日志输出避免磁盘 IO 成为瓶颈。wrk -t4 -c100 -d30s --latency http://127.0.0.1:9080/hello-t4是 4 个线程-c100是 100 个并发连接--latency输出延迟分布。APISIX 官方给出的单核心 QPS 1.5 万、延迟低于 0.7ms 是在开启两个限流插件和 Prometheus 插件的情况下测出来的所以压测时最好至少挂上limit-count和prometheus否则得出的性能基线会偏高。需要注意压测机本身不能跑在同一台机器上否则 CPU 竞争会让延迟数据失真。验证通过后再往生产推之前还要检查worker_processes是否等于 CPU 核数、etcd 集群是否独立部署、Admin API 的 key 是否轮换过。网关的优化空间通常不在 APISIX 本身而在 TLS 会话复用、连接池大小和上游 keepalive 的配合上。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价