1. 从第一代网关到 Higress:为什么架构会收敛到这套方案
大概从 2019 年开始,我一直在折腾微服务网关的选型工作。早期阶段大家的选择很一致——要么用 Nginx 加 Lua 二次开发,要么直接上 Kong,后端 Java 体系的人可能还会用 Spring Cloud Gateway。这几个方案在当时都够用,但跨进云原生时代之后,痛点开始变得非常具体:Kubernetes 里的服务数量涨得飞快,网关需要感知的不再只是 IP 和端口,而是 Service、Endpoint、Ingress 规则、可观测指标这些东西。传统网关几乎都是通过配置文件或数据库来管理路由,跟 K8s 的控制循环完全不是一个节奏。
Higress 给我的第一印象,是它的血统很明确:基于 Istio 和 Envoy 构建。这意味着它在控制面拿到了 Istio 的配置分发能力,在数据面拿到了 Envoy 的高性能转发能力。和那些从零写网关的项目比,Higress 更像是一个站在巨人肩膀上的整合者。这个定位决定了它的核心价值不在"转发快",而在"接入 K8s 生态的方式自然、扩展点丰富"。
要理解 Higress 内部到底在做什么,先要搞清一个前提:它本质上是 Envoy 的"配置翻译器"。用户写的 Ingress、Istio VirtualService、Gateway 资源,不会直接被 Envoy 理解,需要一层把声明式配置转换成 Envoy 的 xDS 协议数据结构的组件。Istio 本来就干这个活,Higress 复用了它的控制面能力,然后又在这层之上加了自己的插件配置、自定义 CRD 和网关 API 支持。换句话说,Higress 没有另起炉灶做一套规则引擎,而是把 K8s 资源和 Envoy 之间的鸿沟填平,然后在中间插了一层业务化能力。
单看转发性能,Envoy 在开源网关里并不是绝对领先,但它有极其丰富的 Filter 链机制和可观测性,这是 Nginx 和自研方案很难企及的深度。Higress 真正值得分析的地方,不是 Envoy 本身多强,而是这一整套链路——配置声明、控制面转换、插件注入、请求路由——是如何被重新组织起来的。下面我会从控制面、数据面、插件体系和实际部署经验四个角度拆开讲。
2. 控制面的设计:为什么复用 Istio 而不是自研一套配置分发
2.1 xDS 协议与 K8s 资源的关系
切入点先把最核心的一句话讲透:Istio 控制面(istiod)接收 Kubernetes 的 Service、Pod、Endpoints 变化,以及 Istio 自己的 VirtualService、DestinationRule 等资源,然后统一转换为 Envoy 能识别的 xDS JSON 格式下发。Higress 之所以敢做深度集成,是因为这套转换链路本身非常成熟,不需要自己维护一个 Ingress Controller 去监听几百种 K8s 资源并做全量同步。
这里有个不太容易察觉的细节:Envoy 的配置模型是"以 listener 为入口、以 cluster 为出口、以 route 为映射规则"。你创建一个 Ingress,平台需要做的事情无非是三步:找出一条能匹配住这个域名和路径的 VirtualService 规则;把规则挂到 80/443 端口的 listener 上;再把这条规则的后端指向某个 K8s Service 对应的 Envoy cluster。在 Higress 里,Istio 的 VirtualService 只是中间表达层,真正的映射器是它的一个叫做"Ingress 适配器"的组件。
我实际测试过这样一个场景:创建一个 Kubernetes Ingress,注解里加了higress.io/ignore或higress.io/ssl-redirect这样的自定义配置。按理说这些注解并不是标准 Ingress 协议的一部分,K8s 的 Ingress Controller 都会自己解析。Higress 的做法是在 istiod 之外跑了一个独立组件来处理这些注解,把注解转译成 VirtualService 的 HTTP route options,再交给 istiod 统一下发。这个设计让标准资源走标准路径,扩展配置走旁路逻辑,两边互不污染。
2.2 Higress Controller 的监听范围与转换链路
Higress 的架构主要由两个模块组成:Higress Controller 和 istiod。Controller 的作用是处理 Higress 自定义的 CRD,如HigressGateway、Http2Rpc,以及 Ingress 资源;istiod 负责标准 Istio 资源。这里有一个很容易搞混的点——用户以为所有配置都是通过 Istio 的 CRD 才能生效,实际上 Higress 对原生 K8s Ingress 的支持是一等公民。
我画了一张简化的逻辑链路图(不涉及具体组件源码,只讲数据流):
K8s Ingress ──> Higress Controller(解析注解)──> VirtualService ──> istiod ──> xDS ──> Envoy K8s Service ──> K8s Endpoint 变化 ──> istiod ──> EDS/CDS ──> Envoy Higress 插件配置 CRD ──> Higress Controller ──> EnvoyFilter ──> istiod ──> 插件 Filter ──> Envoy值得注意的地方在第 3 条链路:插件配置怎么注入到 Envoy 的 Filter 链里?Higress 把插件 CRD 转成 Istio 的 EnvoyFilter 资源。这意味着插件管理的底层机制仍然是 Istio 的,好处是插件的加载、更新、回滚都能复用 Istio 的版本管理和状态同步能力,坏处是 EnvoyFilter 本身副作用较大,一旦配置出错可能影响整个 listener,所以 Higress 启用了PRIORITY和WASM插件运行时隔离来限制影响面。
从原理层面说,控制面的核心优化点在"避免重复计算"。istiod 对每个 Envoy 实例下发的是独立配置,如果网关实例较多,全量配置生成会有不小的 CPU 开销。Higress 的做法是只对增量做推送,利用 Istio 的PUSH_SIGNAL机制做变更检测,而不是每次 K8s 资源变化都触发全量 recompute。
2.3 控制面高可用的实际配置建议
关于控制面部署,我开始时踩过坑——把 Higress 和 istiod 部署在同一个较小的节点上,业务流量高峰期控制面 CPU 飙高,导致配置下发延迟。后来我把 istiod 拆到独立的 2C4G 节点,并且关闭了不必要的命名空间监听,情况立刻好转。
生产环境的控制面参数,我个人建议重点关注几个维度:
| 配置项 | 推荐值 | 原因 |
|---|---|---|
PILOT_ENABLE_ANALYSIS | false | 关闭配置分析器,避免频繁校验集群资源 |
PILOT_ENABLE_EDS_DEBOUNCE | true | 延迟合并 Endpoint 变化,减少推送频率 |
PILOT_DEBOUNCE_AFTER | 100ms | 结合网络抖动,太低会频繁推送 |
PILOT_DEBOUNCE_MAX | 1s | 避免极端情况下推送到超时 |
当然这些参数不能照抄,要看你的服务变更频率。如果服务发布频繁、Endpoint 变化量大,DEBOUNCE_AFTER 可以提高到 300ms 左右。控制面不是越灵敏越好,推送太频繁会让 Envoy 反复重建连接池,直播类、长连接类业务会看到连接中断。
3. 数据面:Envoy 之上,Higress 到底做了哪些改造
3.1 Listener/Route/Cluster 的三层结构与路由匹配顺序
数据面的每个请求,都会经过 Envoy 的 Listener -> Filter Chain -> Route -> Cluster 链路。Higress 没有改变这条链路的骨架,而是在 Filter 链中插入了自己的 Wasm Filter,以及在 Route 层面扩展了更细粒度的匹配条件。
先说路由匹配。Envoy 原生的路由匹配顺序是"域名优先 + 路径最长前缀优先"。Higress 的 Ingress 适配器会将spec.rules[].host和spec.rules[].http.paths[].path组合成一条一条的VirtualHost和Route。这块本身很常规,真正有意思的是通配符域名的处理。K8s Ingress 允许 host 里带通配符,比如*.example.com,Envoy 原生支持前缀匹配域名,但 Higress 会把这类通配符转成 Envoy 的domain_suffix匹配。
你可以用下面的方式理解 Envoy 里路由匹配的代价排序:
- 精确域名匹配(
example.com):O(1) 哈希查找 - 后缀域名匹配(
*.example.com):需要线性扫描所有后缀规则 - 前缀路径匹配(
/api/*):按长度降序匹配
如果你有大量通配符域名,路由匹配性能会受到一定影响。我的实测经验是,在千级域名规则下、通配符占比超过 20% 时,每请求匹配耗时从几十微秒涨到几百微秒,长尾延迟有一定增加。Higress 对此没有魔法,它在文档里也明确建议把精确域名放在规则前面,路径前缀尽量精确到二级目录。
3.2 Higress 对连接池和负载均衡的默认行为
日常使用中,连接池参数往往被忽略,但连接池其实是数据面稳定性的关键。Envoy 对每个 upstream cluster 会维护连接池,Higress 默认继承了 Envoy 的参数:maxRequestsPerConnection默认不限制,maxConnections默认 1024。这意味着网关到后端的连接数是有限的,高并发短请求场景下,连接池耗尽会表现为 503。
Http2 场景更需要关注的是maxConcurrentStreams,默认 100。如果后端服务是 HTTP/2,网关到后端的每个连接最多处理 100 个并发流。超出部分会等待,客户端那侧看到的延迟就会明显增加。我在压测一个短请求 QPS 1 万的接口时,发现 4 个 P99 响应时间从 10ms 涨到 200ms,排查半天才发现是连接池太小导致的排队。解决方案是在 HigressGateway 中通过注解调整连接池参数,或者给服务增加副本数扩大连接数上限。
Higress 默认的负载均衡算法是ROUND_ROBIN,对每个 Endpoint 均匀调度。如果你的后端服务存在热点实例(比如缓存分片不均),建议改成LEAST_REQUEST,让 Envoy 优先选择活跃请求数最少的节点,效果比单纯加权轮询好很多。这块配置通过 DestinationRule 完成,不需要动 Higress 本身。
3.3 优雅关停与连接排空机制
网关升级和缩容时,最怕出现"连接被切断后请求 502"。Envoy 提供了drain机制:收到终止信号后,监听 socket 停止接受新连接,已有的连接保持直到处理完请求或超时。Higress 在 K8s 的 preStop hook 里做了类似处理,默认的排空时间可以从部署参数里调整。
我建议将这个排空时间调大,尤其是在有 WebSocket、长轮询、大文件上传场景下。默认的 30 秒对大部分 REST 接口够用,但遇到下载类请求——下载 1G 文件耗时超过 30 秒——排空窗口不够会导致主动断连。这个参数我一般调整到 120 秒,配合滚动更新的maxUnavailable: 0,能保证发布期间一个请求都不会失败。
4. 插件机制:Higress 扩展能力的灵魂与边界
4.1 从 Ingress 注解到插件配置的映射逻辑
Higress 的插件系统是最让我惊喜的部分,也是踩坑最多的部分。传统网关的扩展能力可能是"加一段 Lua 脚本"或者"写一个 Java Filter";Higress 的插件本质是一段 Wasm 字节码或者 Go 插件,被加载进 Envoy 的 Filter 链中执行。
先分清两种插件形式:
- Wasm 插件:用 C++/Rust/Go(通过 TinyGo)编译成 wasm 模块,由 Envoy 的 Wasm Runtime 加载,隔离性最好,性能开销相对可控。适合中间件类功能,如限流、认证、日志改造。
- Go 插件:通过 Higress 的 Go SDK 编写,运行在单独的 Go 进程里,通过共享内存/Unix Socket 与 Envoy 通信。这种方式绕过了 Wasm 的编译门槛,适合业务逻辑复杂的场景,但性能上比 Wasm 差一点。
在插件架构上,Higress 引入了"插件全局配置 + 规则级配置"的双层结构。全局配置在网关实例上生效,规则级配置可以按域名、按路径绑定。这个设计的价值是:一个认证插件可以全局启用,但某些测试域名走 mock 认证,某些公开路径跳过认证,不需要复制多个插件实例。
插件配置的 CRD 长这样(简化版):
apiVersion: extensions.higress.io/v1alpha1 kind: WasmPlugin metadata: name: custom-auth namespace: higress-system spec: defaultConfig: auth_type: jwt cache_ttl: 60 matchRules: - config: auth_type: mock allow: true ingress: - test.example.com url: http://higress-system/plugins/custom-auth.wasm注意这里的matchRules和defaultConfig的关系。规则匹配时,先按matchRules里的ingress字段找匹配项,找不到就走defaultConfig。这种设计很实用,但有个坑:如果多个规则同时匹配同一个域名,匹配顺序是按 CRD 里的matchRules排列顺序,先匹配先生效。我在测试中发现,把比较具体的域名规则放在前面,通配符规则放后面,行为才会符合预期。
4.2 Wasm 插件的执行流程与性能开销
Wasm 插件在请求链路上处于什么位置?Higress 的 Need 机制决定了它的位置介于 Envoy 的HTTP_FILTER和NETWORK_FILTER之间。一般认证、限流类插件在HTTP_FILTER阶段执行,此时 HTTP 头已经解析完,可以通过request_headers拿到 host/path/method;如果要在 TCP 层做流量镜像,就需要NETWORK_FILTER。
每执行一个 Wasm 插件,都有一层从 Envoy C++ 到 Wasm 宿主环境的函数调用开销。比起原生 C++ Filter,Wasm 插件单指令性能损耗大概在 20% 上下,HTTP 头解析类的操作影响更大。实测一个简单的 JWT 认证插件,每请求成本大约 0.1ms 到 0.3ms;如果插件里做 RSA 解密验证签名,成本会涨到 0.5ms 以上。想控制性能,尽量把能缓存的数据放到插件内部的 LRU Cache 而不是每次重新计算。
Wasm 插件的内存分配也是容易忽略的点。Envoy 的 Wasm Runtime 默认会为每个插件维护一个独立的线性内存空间,如果你的插件在请求上下文中创建了大量临时对象,GC 回收不及时会导致内存持续上涨。用 Rust 写 Wasm 插件时,我习惯在关键路径上避免Vec::push这类动态扩容操作,尽量预分配容量;用 Go(TinyGo)写插件时,避免使用interface{}装箱,因为 TinyGo 的 GC 机制在内存压力下会明显变慢。
4.3 插件链的编排与执行顺序
多个插件同时启用时,执行的先后顺序直接决定业务逻辑是否正确。Higress 的插件执行顺序由WasmPlugin资源的priority字段决定。数字越小的执行越早,在 HTTP 请求链路上,先执行认证,再执行限流,最后执行灰度,是常见的编排方式。
我在参考 Higress 官方文档后整理出一个可复用的执行序模板:
# 假设有三个插件:auth、rate-limit、gray-release # auth 的 priority 是 100 # rate-limit 的 priority 是 200 # gray-release 的 priority 是 300请求进入后,先经过 auth(100),认证通过才到 rate-limit(200),限流没过就直接返回 429,根本不会轮到 gray-release(300)。这种优先级编码的方式很直接,但你要很小心不要在运行期频繁改 priority——每次调整都会触发 EnvoyFilter 变更,导致 listener 重建,连接池清空,正在处理的请求可能出现短暂的 503。
另一个关于插件链的关键细节是Wasm 插件的 fail-open/fail-close 策略。如果插件因为加载错误或执行异常挂了,默认行为是 fail-open(放行还是拦截)取决于插件实现的onConfigure返回值。认证类插件必须 fail-close,否则认证系统一挂,所有请求都裸奔了。限流插件则更适合 fail-open,因为限流组件挂了最多是多打几个请求到后端,不至于整站不可用。Higress 的插件 SDK 里可以通过状态码区分这两种行为,但新手很容易忽略这个字段,测试时一切正常,真出故障时才发现插件挂了对业务没有保护。
5. 部署与运维实战:从安装到迁移的完整落地记录
5.1 安装方式与 Helm 部署的参数选择
Higress 有三种常见装法:Helm、K8s YAML、通过 Istio 集成安装。个人最推荐 Helm,因为能清晰修改控制面参数。这里记录一下我的最小部署清单:
helm repo add higress.io https://higress.io/helm-charts helm repo update helm install higress higress.io/higress \ --namespace higress-system \ --create-namespace \ --set global.local=true \ --set global.ingressClass=higress几个参数值得留意。global.local=true表示 Controller 和 istiod 都部署在同一集群内,适合单集群使用;如果是多集群,需要关掉 local 模式并配置远程 istiod 地址。global.ingressClass可以指定多个IngressClass,网关只接管带有对应 ingressClass 的资源。这个参数非常有用——如果你有其他 Ingress Controller(比如 Nginx),可以通过 IngressClass 把流量按域名分开,避免一家网关管所有 Ingress 导致配置冲突。
部署完成后,我习惯先验证两个关键 Pod:
kubectl -n higress-system get pod # 期望看到 higress-controller、istiod、higress-gateway 三个工作负载如果 istiod 和网关都正常,但 Ingress 没有生效,排查优先级最高的是higress-controller的日志。Higress Controller 报错最多的场景是"无法解析注解",比如某个注解值不是合法的 JSON。这不会有强报错,只会在日志里出现 warn,然后该 Ingress 被跳过。
5.2 从 Nginx Ingress 迁移的踩坑记录
大部分团队是把 Higress 作为 Nginx Ingress 的替代方案来考察,所以迁移问题值得单独讲。
坑 1:正则路径的兼容性。Nginx Ingress(K8s 自带的)允许在 path 里写正则,比如~* ^/api/.*,但 Higress/Envoy 使用的是前缀匹配和前缀替换规则,不支持直接在 Ingress path 里写正则。迁移时,如果你有这类正则 Ingress,需要先改造成 Envoy 风格的路径匹配——用前缀全等替换,或者用 Higress 扩展的higress.io/path-regex注解实现正则匹配。这一步不做好,部分 API 会出现 404 或匹配到错误的 Service。
坑 2:rewrite-target 的语义差异。Nginx Ingress 的nginx.ingress.kubernetes.io/rewrite-target: /会把请求路径重写成/;Higress 默认也是支持 rewrite 的,但跟 Nginx 的实现有些微差别。Nginx 是正则捕获组替换,Higress 用capture模式($1、$2)来替换路径匹配部分。如果你的 rewrite 规则里有复杂的$变量拼接,迁移后要注意转义和匹配范围。
坑 3:灰度发布注解的不一致。Nginx Ingress 有nginx.ingress.kubernetes.io/canary,可以按 header、cookie、权重做灰度;Higress 支持 Ingress 注解版本的灰度,但部分精细策略(比如按 query 参数灰度)需要通过 Higress 的CanaryCRD 配置。建议迁移前盘点灰度策略的维度,需要自定义的维度提前写 CRD。
坑 4:证书管理的证书链问题。Higress 默认可以自动挂载 K8s Secret 中的 TLS 证书,但如果你用的是自签名证书或中间证书不完整的证书链,Envoy 会直接拒绝 TLS 握手。Nginx 可能更宽容,Envoy 对证书链的校验严格很多。迁移后测试 HTTPS 时,如果浏览器报unable to verify the first certificate,首先检查证书链是否完整。
5.3 故障排查与日志分析链路
Higress/Envoy 的日志体系有点特殊——它不直接输出标准 K8s 日志,而是通过access log和stats暴露信息。建议一开始就把 Envoy 的 Stats 配置到 Prometheus 中。
遇到 503 故障时的排查顺序:
- 看 Higress 网关 Pod 日志中的
cluster not found或no healthy upstream,这代表后端 Service 没有匹配 Endpoint。 - 检查 Service 的 selector 是否写对。Envoy 的 EDS 只会发现带有正确标签的 Pod,如果标签不匹配,即使 Service 有名字,也会 no healthy upstream。
- 看 Endpoint 是否真的存在。
kubectl get endpoints如果为空,说明 Service 挂了或 Pod 没就绪。 - 如果是 503 批量出现,检查连接池是否被打满,看 stats 中
upstream_cx_overflow。
跨命名空间访问的问题。Higress 默认只代理同命名空间的 Service,跨命名空间需要在 CRD 里显式配置higress.io/service的 FQDN(比如servicename.namespace.svc.cluster.local)。这个配置没有配好时,日志里会出现upstream cluster not found,并且没有特别的提示。我在一次排查中花了近三个小时,最终发现只是 namespace 拼写不一致。
5.4 配置热更新与版本回滚
网关配置的变更频率应该被严格管控。Higress 的配置链是 Ingress/VirtualService -> istiod -> Envoy,如果每改一次配置就全量重推,网关性能会退化。Istio 的debounce机制可以合并短时间内的多次变更,因此我建议通过 helm 参数调大PILOT_DEBOUNCE_AFTER到 150ms 以上,这样 GitOps 工具批量同步时,不会每个变更都触发一次全量推送。
版本回滚是另一个容易踩的坑。EnvoyFilter 类型的配置变更没有 Kubernetes 原生的版本回滚机制,你只能通过重新应用上一个 YAML 来实现回滚。但重启 pod 时,listener 需要重新构建,连接会中断一次。对于长连接服务,我建议在发布窗口期做变更,不要在生产流量高峰时改插件配置。Higress 官方提供的higress.io/health-check注解可以给网关实例配 readiness probe,配置变更后如果 readiness 失败,K8s 会把流量摘掉,这能在一定程度上减少故障影响面。
6. 性能实测与调优参数参考
6.1 基线压测数据
我用自己的测试环境(8C16G 单机 K8s,Higress gateway 1C2G 单副本,后端是一个简单的 Go HTTP 服务)做了压测,结果如下:
| 场景 | QPS | P99 延迟 |
|---|---|---|
| 无插件,纯路由转发 | 18k | 4ms |
| 启用 JWT 认证插件(Wasm) | 12k | 8ms |
| 启用限流插件(Wasm)+ JWT | 10k | 11ms |
| 启用两个 Wasm 插件 + 一个 Go 插件 | 7.5k | 15ms |
数据说明,插件数量对性能的影响是叠加的,尤其 Wasm 插件之间不能并行执行,只能串行排队。如果有 5 个插件,每个消耗 0.2ms,那每请求固定多了 1ms 延迟,QPS 上限自然下降。做网关插件规划时,尽量把功能相近的合并成一个插件——比如把 JWT 认证、Basic Auth、OAuth 校验放到一个插件里通过配置切换,而不是拆成三个插件。
6.2 Envoy 核心参数对性能的影响
Higress 原生暴露了大量 Envoy 配置,但文档里没有详细说明的、容易踩坑的包括:
listener connection buffer limit:默认 1MB,适合常规 HTTP 场景;如果网关要处理大文件上传,建议提高到 4MB 以上,否则大包会被拆分,性能下降。upstream http2 max concurrent streams:默认 100,短连接并发充足的情况下不必调整;长连接推送行业务请调高到 500 以上。cluster dns refresh rate:默认 60 秒做一次 DNS 解析,如果你在后端用 Consul/Nacos 做服务发现,这个参数很关键。Higress 通过 Nacos 的专用扩展可以做服务订阅,dns 模式不常用。
性能调优的核心不是堆机器,而是减少跨层拷贝。Envoy 本身零拷贝做得好,但 Wasm 插件如果要访问 body,会将 body 从 shared memory 复制到 Wasm 线性内存,这个拷贝操作的耗时和 body 大小成正比。凡是能通过 header 完成判断的,就不要在插件里读 body;必须读 body 的,限制 body 大小并优先用 streaming 方式处理。
6.3 与 Nginx Ingress 的实测对比
我用同一个测试后端,分别用 Nginx Ingress(默认配置)和 Higress(无插件)做路由转发压测,结果 Higress 的 QPS 略低 5% 左右,但 P99 延迟更稳定。Nginx Ingress 在连接新建场景下表现更好,Envoy 在长连接、连接复用场景下优势更明显。
如果你的业务大多是短连接(比如移动端 API 频繁断连重连),Nginx 并不会吃亏;如果你有大量的 WebSocket、gRPC Stream,Envoy 的 HTTP/2 支持能力和流量管理能力会完胜。所以迁移前先看自己的流量模型,再做决定。
7. 这个架构的局限性:哪些场景不建议用 Higress
分析完 Higress 的原理和优势,也必须说清楚它的短板。没有万能网关,Higress 的架构决定了一些场景并不合适。
gRPC 场景的性能。Envoy 的 HTTP/2 处理能力本身强大,但 Higress 的默认配置为 HTTP/1.1 做了一定优化(比如 HCM 的codec_type自动协商)。如果全是 gRPC 流量,最好显式配置协议为 h2,否则依次回退可能产生不必要的握手开销。还有,gRPC 长连接健康检查机制依赖于 HTTP/2 PING,Higress 默认是开启的,但如果你在 gateway 前面还有一层 LB,LB 的 idle timeout 如果小于 Envoy 的 PING 间隔,连接会被切断,客户端就会看到 intermittent GOAWAY。
超大规模网关集群。Higress 的配置下发依赖 istiod。如果业务有几十个集群、上千个网关实例,istiod 会成为瓶颈。Istio 本身在新版本里做了多集群扩展,但 Higress 单集群模式下的最优规模在几百个实例以内。超过这个规模,建议拆分多个独立 Higress 部署,不要死磕一个全量集群。控制面是所有网关的下发中枢,它挂了所有集群的路由都会出问题,这个单点风险在大规模场景下必须通过多实例部署分散。
需要细粒度访问控制的场景。Higress 的插件配置按域名和路径绑定,可以做基本的 RBAC,但如果是复杂的组织架构级权限、用户维度高级路由(比如不同用户组访问不同的服务版本),插件里要维护大量规则和用户数据,管理成本会上来。这种场景更适合放在业务网关(如 Backend for Frontend)层做,让 Higress 只负责南北向流量网关的基础能力。
长尾流量的成本。挂了多个 Wasm 插件后,CPU 开销明显上涨,这在低流量业务中问题不大,但在高 QPS 场景,网关本身的资源开支会占到一个不小的比例。优化方向是把一些高频逻辑下沉到 Istio 的本地 Envoy Filter,或者用 Go 插件替换 Wasm 插件降低运行开销。但 Go 插件需要更仔细地处理并发和内存。
8. 附录:我整理的 Higress 落地检查清单
如果把 Higress 投入到生产,下面这些检查项是我会逐一核对的。列成清单,方便直接抄作业。
8.1 控制面与数据面检查项
- 确认 istiod 独立节点部署,不与其他重负载容器混部
- 配置
PILOT_ENABLE_ANALYSIS=false关闭控制台分析器 - 确认 ingressClass 命名和原有 Nginx 不冲突
- 验证 Envoy 的 access log 格式是否包含 traceId(配合链路追踪)
8.2 插件与流量管理检查项
- 所有认证插件将 fail-open/fail-close 配置明确(认证类 fail-close)
- 插件全局配置与规则配置分离,通配符域名规则放最后
- 每个插件声明合理的
priority,避免运行期频繁改 - Wasm 插件的构建产物版本控制,每次更新前做灰度加载
- 确认插件没有读取请求 body 的非必要行为
8.3 高可用与迁移检查项
- Gateway Pod 的
preStop排空时间调大到 120s - 配置多个副本,
maxUnavailable设置为 0 - Ingress 迁移前逐条核对 rewrite 语义和正则路径
- TLS 证书链完整,不信任中间证书的客户端提前绕行
8.4 可观测性检查项
- Prometheus 采集
envoy_server_*、envoy_cluster_upstream_rq_time等指标 - 日志系统接入 traceId,确保网关日志和业务日志能串起来
- 告警规则覆盖
envoy_cluster_no_healthy_upstream、envoy_cluster_upstream_cx_overflow
我自己在迁移 Higress 的过程中,最大的体会是:这个网关的门槛不在转发性能,而在配置模型的思维切换。用惯了 Nginx Ingress 的 rewrite 和 annotation 之后,去理解 Higress 的 Ingress/VirtualService/EnvoyFilter 三层抽象,需要一段时间。但跨过这个坎之后,它的流量治理能力和扩展性确实值得投入。如果你正计划替换网关,建议先在测试环境跑通上面这份清单里的核心项,再逐步切生产流量。