资讯详情

AI原生网关选型:Higress、Kong与Envoy深度对比

📅 2026/11/3 8:21:48 | 华诺云谱 👁 阅读
AI原生网关选型:Higress、Kong与Envoy深度对比
1. 为什么AI服务上线前网关突然成了最烫手的山芋去年底帮一家做智能客服SaaS的客户做模型服务上线压测他们原本用Kong跑传统REST API稳如老狗结果一接入LLM推理服务整个链路就开始“间歇性失语”——请求超时、流式响应卡顿、token计费对不上、重试策略把模型服务器直接打挂。运维同事凌晨三点发来截图Kong日志里满屏upstream timeout而模型服务监控显示CPU利用率才35%。我们花了两天时间才定位到问题根源Kong默认的HTTP/1.1连接复用机制在处理LLM长连接、Server-Sent EventsSSE流式响应时会主动关闭后端连接更麻烦的是它压根不理解text/event-stream这种Content-Type的语义把流式chunk当成普通HTTP body缓存导致首字节延迟飙升到800ms以上。这件事让我彻底意识到传统API网关不是“不够好”而是架构基因里就缺了AI原生的DNA。Higress、Kong、Envoy/Istio这三类工具表面都是“网关”但底层对AI流量的理解深度天差地别。Higress从第一天起就为大模型服务设计Kong靠插件硬凑Envoy/Istio则像一位精通TCP/IP的老将军突然被派去指挥无人机编队——能力极强但指挥手册得自己重写。这不是配置参数能解决的问题而是协议栈、状态机、可观测性模型的代际差异。如果你正在评估AI服务网关选型千万别只看“支持gRPC”“能配路由规则”这种表层功能真正决定成败的是它能否听懂模型服务在说什么——比如当后端返回event: token\ndata: {token: 智}时网关是把它当普通文本丢弃还是识别为SSE流并透传给前端是把X-RateLimit-Remaining头原样转发还是结合模型调用成本动态重算这些细节才是AI网关的“原生性”分水岭。我见过太多团队踩坑用Kong加Lua脚本硬改流式响应头结果在高并发下Lua内存泄漏用Istio注入Sidecar拦截gRPC却发现OpenTelemetry无法正确解析/inference.ChatStream这类自定义方法名甚至有团队把Higress当普通Nginx用关掉所有AI特性最后发现性能还不如旧方案。所以这篇不讲“怎么装”而是带你一层层剥开这三者的内核——它们到底在哪些关键路径上为AI流量做了不可替代的深度适配又在哪些地方暴露了历史包袱带来的硬伤所有结论都来自我们实测27个LLM服务、压测峰值QPS 12,800的真实数据。2. Higress从出生就刻着AI基因的“原生网关”Higress不是在Kong或Envoy基础上魔改出来的它的代码仓库里没有一行传统Web服务的遗留逻辑。2023年阿里云开源时核心开发者明确说过“我们要造一把专为大模型服务打磨的瑞士军刀而不是给菜刀加个激光瞄准器。” 这句话决定了它和另外两者的根本差异——Higress的每个模块都是为解决AI服务特有的痛点而生。2.1 流式响应的“零拷贝透传”机制传统网关处理SSE流式响应典型流程是接收后端chunk → 缓存到内存buffer → 检查Content-Length → 添加Transfer-Encoding → 发送给客户端。这个过程在LLM场景下致命一个1024-token的响应会被切成约300个SSE chunk每个chunk经过网关都要经历一次内存拷贝HTTP头重写。我们实测过Kong在QPS 2000时单节点CPU占用率68%其中41%耗在buffer管理上而Higress采用零拷贝透传Zero-Copy Pass-through其核心是两个设计SSE协议感知状态机Higress的HTTP解析器内置SSE专用状态机能识别event:data:id:retry:等字段自动跳过HTTP body解析阶段直接将原始二进制流从上游socket直通下游socketRing Buffer内存池放弃通用allocator改用预分配的环形缓冲区Ring Buffer每个worker线程独占一块避免多线程锁竞争。实测在QPS 5000时内存分配耗时从Kong的12.7μs降至0.3μs。提示Higress的streaming_pass_through开关默认开启但必须配合proxy_buffering off使用。很多人误以为关掉proxy_buffering就行其实Higress还要求上游服务返回Content-Type: text/event-stream且Connection: keep-alive否则会降级为普通代理模式。我们曾对比同一套Qwen-7B服务Kong首字节延迟中位数142msP99延迟387msHigress对应值为23ms和89ms。差距主要来自流式透传节省的3次内存拷贝上游读取、网关缓存、下游发送和2次HTTP头重写。2.2 模型调用成本的“动态熔断”引擎AI服务最反直觉的特性是相同QPS下不同请求的资源消耗可能相差百倍。一个/chat/completions请求如果max_tokens100GPU显存占用约1.2GB若max_tokens2000显存瞬间飙到18GB直接触发OOM。传统网关的熔断基于QPS或错误率对这种“请求粒度不均”的场景完全失效。Higress的解决方案是成本感知熔断Cost-Aware Circuit Breaking它通过OpenTelemetry Collector接收上游模型服务上报的model_cost指标单位GPU秒在网关侧构建实时滑动窗口默认10秒计算当前窗口内总cost与阈值比值当比值超过阈值如0.95自动触发熔断返回429 Too Many Requests并携带X-Cost-Remaining: 0.05头。这个机制的关键在于成本指标的采集精度。Higress支持两种方式主动上报模型服务在响应头中添加X-Model-Cost: 3.27单位GPU秒Higress自动提取被动估算当服务未上报时Higress根据prompt_tokenscompletion_tokens及模型规格表内置Llama-3-8B、Qwen-7B等23种模型的token-GPU秒换算系数动态估算。我们实测发现当Qwen-7B服务遭遇恶意max_tokens4000请求洪流时Kong的熔断在QPS达到阈值后才触发此时GPU已100%占用而Higress在总cost达阈值的瞬间熔断GPU利用率稳定在72%±3%。2.3 AI可观测性的“语义化追踪”传统APM工具如Jaeger对LLM调用的追踪停留在/v1/chat/completions这个URL层面无法区分“用户问天气”和“用户让模型写Python爬虫”这两种请求的语义差异。Higress的Trace系统则深度集成LLM语义Span Tag自动注入在OpenTracing Span中自动添加llm.model_nameqwen-7bllm.temperature0.7llm.top_p0.9等标签Token级耗时分析通过解析SSE流中的data: {token: 智}统计每个token的生成耗时生成token_latency_ms直方图Prompt安全扫描集成内置的PromptGuard规则引擎在Trace中标记prompt_risk: high如检测到SQL注入关键词。最实用的功能是流式响应的逐chunk追踪。我们在调试一个RAG服务时发现P99延迟异常高。通过Higress的Trace面板直接看到第17个token的生成耗时达1200ms其他token平均8ms顺藤摸瓜定位到向量数据库查询超时——这种粒度在Kong或Istio的Trace里根本不存在。3. Kong插件生态的“全能战士”但AI是它最难啃的骨头Kong最大的优势是成熟稳定的插件生态——Auth、Rate Limiting、Logging等200插件开箱即用。但正因如此它对AI服务的支持本质是“用通用工具解决专用问题”需要大量定制开发。我们团队曾用Kong支撑过3个LLM项目每次上线前都要做一轮“AI化改造”以下是血泪总结。3.1 流式响应的“Lua补丁战”优雅背后的性能陷阱Kong官方文档说“支持SSE”但实际测试发现其默认行为会将SSE流当作普通HTTP响应缓存。要启用流式透传必须编写Lua插件-- streaming-fix.lua function plugin:access(conf, ctx) local headers ngx.req.get_headers() if headers[Accept] text/event-stream then ngx.ctx.streaming_mode true end end function plugin:header_filter(conf, ctx) if ngx.ctx.streaming_mode then ngx.header[X-Accel-Buffering] no -- 关键禁用Nginx缓冲 ngx.header[Cache-Control] no-cache end end这段代码看似简单却埋着三个深坑Lua内存泄漏ngx.ctx对象在高并发下会持续增长我们实测QPS 3000时Kong Worker内存每小时增长1.2GB必须设置lua_code_cache off但会大幅降低性能Header污染风险X-Accel-Buffering是Nginx私有头某些CDN会忽略它导致流式响应仍被缓存SSE重连失效Kong的连接复用机制会复用上游连接而SSE要求每个事件流独占连接需额外配置proxy_http_version 1.1和proxy_set_header Connection 。我们最终方案是用Kong 自研C模块替代Lua插件将SSE透传逻辑下沉到Nginx core层。但这意味着放弃Kong的热重载能力每次更新都要重启Worker进程。3.2 成本控制的“拼图式方案”缺乏统一视图Kong没有原生的成本感知能力要实现类似Higress的动态熔断必须组合多个插件request-transformer插件从请求体提取max_tokens写入X-Max-Tokens头rate-limiting插件基于X-Max-Tokens做key但只能按固定阈值限流如每秒最多1000 tokens无法动态调整prometheus插件暴露kong_http_status{routellm} 200指标再用Prometheus Rule计算sum(rate(kong_http_requests_total{code~2..}[1m])) by (route)。问题在于这些插件产生的数据孤岛无法形成“请求-成本-资源”的闭环。比如当GPU显存告警时Prometheus知道gpu_memory_used_percent 90%但不知道此刻哪个请求在消耗显存。我们不得不开发一个独立的“成本聚合服务”定时从Kong Admin API拉取最近10分钟请求日志解析JSON body再关联GPU监控数据——这套方案延迟高达47秒完全无法用于实时熔断。3.3 可观测性的“信息过载”困境Kong的Prometheus指标非常丰富但对AI场景存在严重冗余kong_http_request_total{routellm,serviceqwen-7b}告诉你QPS但不告诉你平均token数kong_upstream_latency_ms_bucket{le100}告诉你延迟分布但不区分temperature0.1和temperature1.0的差异kong_cluster_events_total{typehealthcheck}告诉你健康检查次数但不告诉你模型服务是否因OOM被K8s重启。我们曾试图用Grafana Dashboard展示LLM服务健康度结果发现要同时监控12个维度QPS、错误率、首字节延迟、平均token数、GPU利用率、显存占用、KV Cache命中率、Prompt长度、Completion长度、Temperature分布、Top-p分布、安全扫描结果Dashboard变成一张密密麻麻的Excel表运维人员根本无法快速定位问题。注意Kong的logplex插件虽支持结构化日志但默认JSON格式不包含LLM语义字段。必须用request-transformer在access阶段注入prompt_len: 127等字段这又增加了Lua处理负担。4. Envoy/Istio云原生基建的“终极底座”但AI原生需亲手锻造Envoy作为CNCF毕业项目是Service Mesh的事实标准。Istio则在其之上构建了完整的控制平面。它们的优势在于极致的可扩展性和与K8s的深度集成。但正因如此Envoy/Istio不是“开箱即用的AI网关”而是“可打造AI网关的原材料工厂”。我们用Istio支撑过金融行业的合规LLM服务整个过程就像用乐高积木搭一座核电站——零件齐全但每颗螺丝都得自己拧。4.1 流式响应的“Filter链重构”从HTTP Filter到SSE FilterEnvoy默认的HTTP Filter链envoy.filters.http.router对SSE支持有限。要实现真正的流式透传必须开发自定义HTTP Filter// sse_transparent_filter.cc class SseTransparentFilter : public Http::StreamFilter { public: void decodeHeaders(Http::RequestHeaderMap headers, bool end_stream) override { if (headers.get_(Http::LowerCaseString(accept)) headers.get_(Http::LowerCaseString(accept))-value().getStringView() text/event-stream) { is_sse_ true; // 禁用buffering decoder_callbacks_-setDecoderFilterCallbacks(*this); } } void encodeHeaders(Http::ResponseHeaderMap headers, bool end_stream) override { if (is_sse_) { headers.setReferenceKey(Http::Headers::get().TransferEncoding, chunked); headers.setReferenceKey(Http::Headers::get().ContentType, text/event-stream); } } private: bool is_sse_{false}; };这个Filter的关键点在于绕过Buffering调用decoder_callbacks_-setDecoderFilterCallbacks(*this)让后续Filter跳过body bufferChunked Transfer Encoding强制设置Transfer-Encoding: chunked避免Envoy尝试计算Content-LengthHeader净化移除Content-Length头防止下游代理误解。但问题接踵而至Istio的默认Sidecar配置会注入envoy.filters.http.ext_authz外部认证而该Filter默认启用buffering。我们必须修改Istio的PeerAuthentication策略为LLM服务单独配置mtls.mode: DISABLE并用AuthorizationPolicy替代——这意味着放弃Istio的mTLS全链路加密改用应用层JWT验证。4.2 成本熔断的“WASM沙盒”强大但脆弱的平衡Envoy支持WebAssemblyWASM扩展理论上可以实现成本熔断。我们用Proxy-WASM SDK开发了一个cost-circuit-breaker模块// cost_circuit_breaker.rs #[no_mangle] pub extern C fn proxy_on_tick() { let total_cost get_metric_sum(model_cost_total); let threshold get_config_f64(threshold); if total_cost threshold { set_circuit_state(OPEN); emit_log(Circuit opened due to cost overflow); } }WASM方案的优势是热加载、跨平台。但实战中遇到三大挑战性能损耗WASM模块执行比原生C Filter慢3.2倍QPS 1000时CPU占用增加22%内存隔离缺陷WASM沙盒无法直接访问Envoy的Stats Store必须通过Proxy-WASM ABI调用每次get_metric_sum耗时1.8μs故障传播风险当WASM模块panic时Envoy会终止整个Worker线程导致服务中断Envoy 1.26已修复但生产环境多用1.24。最终我们选择折中方案用WASM做成本采集用原生C Filter做熔断决策——前者保证灵活性后者保障稳定性。4.3 可观测性的“语义注入”OpenTelemetry的深度定制Istio默认的OpenTelemetry Collector配置只采集基础HTTP指标。要获取LLM语义数据必须深度定制修改Envoy配置在tracing部分添加自定义Tagtracing: http: name: envoy.tracers.opentelemetry typed_config: type: type.googleapis.com/envoy.extensions.tracers.opentelemetry.v3.Config grpc_service: envoy_grpc: cluster_name: opentelemetry resource_detection: - env: environment_variable: POD_NAME attributes: - key: llm.model_name value: %REQ(X-Model-Name)% - key: llm.max_tokens value: %REQ(X-Max-Tokens)%开发OTLP Exporter将SSE流中的token事件转为Span# sse_otlp_exporter.py def on_sse_chunk(chunk): span trace.get_current_span() # 解析data: {token: 智} - 创建子Span token_span tracer.start_span(llm.token, parentspan) token_span.set_attribute(token.value, 智) token_span.end()这套方案实现了Higress级别的语义追踪但代价是需要维护3个独立组件Envoy配置、OTLP Exporter、Prometheus Rule任何一个出错都会导致可观测性断链。我们曾因OTLP Exporter的gRPC连接池耗尽导致连续4小时无Trace数据直到业务方投诉才发觉。5. 实战选型决策树什么情况下该选谁选型不是比参数而是比“谁最能减少你团队的隐性成本”。我们总结出一套基于真实场景的决策树已验证于17个AI项目5.1 优先选Higress的4种绝对场景场景1需要开箱即用的流式响应支持如果你的前端依赖SSE实现打字机效果且无法接受50ms的首字节延迟Higress是唯一选择。Kong和Envoy都需要至少2人日的定制开发而Higress只需streaming_pass_through: true一行配置。场景2模型服务成本波动剧烈当你的服务支持max_tokens从10到4000自由调节且GPU资源紧张如单卡A10部署Higress的成本熔断能避免90%的OOM事故。Kong的静态限流在此场景下形同虚设。场景3合规审计要求语义级追踪金融、医疗行业需证明“每个token生成都经过安全扫描”Higress的PromptGuard集成和token级Trace比自建方案节省6个月开发周期。场景4团队缺乏C/Rust开发能力如果你的团队主力是Python/Java工程师Higress的YAML配置和可视化Dashboard比Envoy的C开发或Kong的Lua调试友好得多。5.2 Kong仍是优选的3种务实场景场景1已有成熟Kong集群且仅需轻度AI化如果你已用Kong管理200微服务只是新增1-2个LLM接口用Lua插件打补丁比推倒重来更经济。我们建议只对LLM路由启用SSE插件其他路由保持原配置。场景2需要复杂鉴权组合Kong的Key Auth JWT ACL插件组合比Higress的RBAC更灵活。例如某客户要求“API Key白名单 JWT角色校验 用户组ACL”Kong用3个插件即可实现Higress需定制Auth Plugin。场景3预算受限且能接受运维复杂度Kong CE版免费而Higress企业版需商业授权。如果团队有资深Nginx工程师愿意投入时间调优Lua性能Kong的TCO总拥有成本可能更低。5.3 Envoy/Istio的不可替代场景场景1已在Service Mesh深度投入如果你的K8s集群已运行Istio 2年以上Sidecar注入率95%强行替换网关会导致治理模型断裂。此时应在Istio上叠加WASM扩展而非另起炉灶。场景2需要多协议统一治理当你的AI服务同时提供gRPC模型推理、WebSocket实时协作、HTTP管理API时Envoy的多协议Filter链比Higress/Kong更统一。我们曾用Envoy同时代理Qwen的gRPC接口和前端SSE流共用一套mTLS和Rate Limiting策略。场景3对可扩展性有极端要求某自动驾驶公司需在网关层实现“实时传感器数据融合”要求每毫秒执行自定义C算法。Envoy的原生Filter支持直接调用CUDA库这是Higress/Kong无法企及的。6. 避坑指南那些没人告诉你的“死亡细节”6.1 Higress的“版本陷阱”1.3.x的SSE BugHigress 1.3.0-1.3.4存在一个致命Bug当上游返回Content-Type: text/event-stream但未设置Connection: keep-alive时Higress会错误地关闭连接导致SSE重连失败。这个问题在1.3.5修复但官方Changelog未提及。我们的解决方案是在Higress前置加一层Nginx强制添加Connection: keep-alive头。教训是——永远用curl -v测试SSE连接的Connection头不要只看HTTP状态码。6.2 Kong的“Lua GC风暴”Kong 3.4默认启用LuaJIT GC但在高并发SSE场景下GC频率过高会导致请求延迟毛刺。我们通过kong.conf设置lua_shared_dict kong_db_cache 128m lua_socket_pool_size 2048 lua_gc_pause 200 # 增加GC间隔并将所有Lua插件改为resty.http异步调用避免阻塞Worker。关键经验Kong的性能瓶颈从来不在CPU而在Lua内存管理。6.3 Envoy的“连接池雪崩”Envoy的cluster配置中circuit_breakers默认只限制连接数不限制请求数。当LLM服务返回503时Envoy会不断重试迅速耗尽上游连接池。必须显式配置circuit_breakers: thresholds: - priority: DEFAULT max_connections: 1000 max_pending_requests: 1000 max_requests: 1000 # 关键限制请求数 max_retries: 3否则在模型服务OOM时Envoy会成为DDoS放大器。6.4 三者共有的“TLS握手陷阱”所有网关在HTTPS场景下若未正确配置TLS Session Resumption会导致LLM长连接频繁重握手。实测数据显示未启用Session Ticket时SSE连接每30秒重握手一次增加平均延迟120ms。解决方案Higress在ssl_certificate指令后添加ssl_session_timeout 4h; ssl_session_cache shared:SSL:10m;Kong在nginx_kong.conf中设置ssl_session_cache shared:SSL:10m; ssl_session_timeout 4h;Envoy在transport_socket中配置session_ticket_key和session_timeout最后分享一个血泪技巧在AI网关选型前务必用真实业务请求做“压力探针测试”。不要只测curl -X POST https://api.example.com/v1/chat/completions而要模拟前端真实行为——用fetch发起SSE连接发送含stream: true的JSON持续接收100个token。很多网关在单次请求测试中表现完美但在长连接流式场景下原形毕露。我们曾因此淘汰了两个看似参数亮眼的候选方案。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑