更新日志
3.10.5
发布日期:2026-08-11
不兼容变更
插件
-
升级说明
该插件现在会校验日志服务器的 TLS 证书。旧版本在完成 TLS 握手时完全不校验证书,因此日志服务器出示自签名证书、私有 CA 签发的证书或已过期的证书都会被静默接受,而携带所配置访问密钥的日志记录仍 会发往该服务器。
校验行为由新增的
ssl_verify选项控制,默认值为true。升级后,若网关无法校验日志服务器的证书,批处理器会丢弃这批日志,并在错误日志中记录failed to perform TLS handshake to TCP server。如果你的日志服务器出示的证书并非由公共可信 CA 签发,请在升级前把签发该证书的 CA 加入数据面的可信证书库,或在插件上把ssl_verify设为false以保持旧行为。
升级须知
headers 字段落盘加密在启用数据面数据加密(apisix.data_encryption.enable)时,控制面现在会对 Loki Logger 的 headers 字段做落盘加密。由于 API7 EE 的升级顺序是先控制面、后数据面,在升级窗口内 3.10.5 的控制面会加密该字段,而仍为 3.10.4 的数据面无法解密,可能导致该插件在数据面升级完成前无法正常工作。
如果你使用了 Loki Logger 的 headers,请在控制面升级后尽快把数据面也升级到 3.10.5,并在两侧都升级完成前避免编 辑该插件。
控制台会话 Cookie 的签名密钥此前是编译期常量,所有部署完全相同。现在改为首次启动时生成的 32 字节随机密钥,并按部署持久化保存,因此会话 Cookie 不再可能用一个各处相同的值签发。
升级前签发的会话使用的是旧的常量密钥,升级后不再被接受。控制面升级完成后,所有已登录用户都需要重新登录一次。升级前无需做任何准备,也不需要修改配置。
radixtree_host_uri 路由器Docker Compose 部署包现在会把 apisix.router.http 设为 radixtree_host_uri,与 Helm Chart 一直使用的默认值保持一致。此前该部署包不设置这一项,回落到 radixtree_uri,因此同一份配置在不同部署形态下的路由匹配结 果可能不同。
仅依赖普通 host 与路径匹配的配置不受影响。差异出现在「指定了 host 的路由」与「未指定 host 的路由」共享重叠路径时:radixtree_host_uri 会先查按 host 划分的子路由器,只有都未命中时才回落到未指定 host 的路由;而 radixtree_uri 把所有路由放在同一棵树中,按路径特异性与 priority 排序。如需保留旧的匹配引擎,可在 gateway_conf/config.yaml 中把 apisix.router.http 设为 radixtree_uri。
控制台现在在浏览器端应用界面语言,并用 Cookie 记住所选语言,因此 URL 不再带 /zh 前缀。升级后,含 /zh 的书签和已保存的链接会返回 HTTP 404,去掉该前缀后的同一路径即可访问对应页面。可选语言以及语言切换器本身没有变化。
新功能
插件
- LDAP Auth Advanced
- 新增该插件,用于对接 LDAP 目录完成客户端认证,并把认证结果映射到消费者。插件采用「先检索、后绑定」的方式解析用户:在
base_dn下按attribute=username检索,再以检索到的条目执行绑定,因此无需把目录结构写进网关配置。凭据从Authorization请求头读取,支持ldap和basic两种方案(header_type);可通过 LDAPS 或 StartTLS 连接目录,且默认开启证书校验;连接在请求之间复用。消费者通过其凭据上记录的user_dn匹配,因此消费者级插件、限流和用量统计对 LDAP 认证的流量与其它身份一视同仁。
- 新增该插件,用于对接 LDAP 目录完成客户端认证,并把认证结果映射到消费者。插件采用「先检索、后绑定」的方式解析用户:在
- OpenID Connect
- 新增对推送式授权请求(PAR,RFC 9126)的支持。设置
par.enabled后,网关会通过后通道把完整的授权请求发送到身份提供方的 PAR 端点,浏览器重定向中只携带request_uri,授权参数因此不再经过用户代理,也无法在那里被篡改。端点及其客户端认证方式通过par.endpoint与par.endpoint_auth_method配置。 - 新增对 DPoP 发送方约束令牌(RFC 9449)的支持。设置
dpop.enabled后,网关会用dpop.private_key为令牌请求签发 DPoP 证明,并声明与之匹配的dpop.public_jwk,使签发的令牌绑定到该密钥,令牌即使被窃取也无法从其它客户端重放。同时启用 PAR 时,密钥指纹还会按规范要求以dpop_jkt随推送请求一并发送。
- 新增对推送式授权请求(PAR,RFC 9126)的支持。设置
- AI AWS Content Moderation
- 新增
check_response,在审查请求 之外同时审查 LLM 的回复。非流式回复在返回客户端之前完成审查;流式回复的处理方式由stream_check_mode决定:默认值final_packet对拼装完成的响应审查一次,并在最后一个分片上标注风险等级;取值realtime时,在响应转发过程中按最多stream_check_cache_size个字符分批审查,一旦某批命中就把流的剩余部分替换掉,因此中途才出现有害内容的流会被截断,而不是完整送达。被拦截的回复以该服务商自身的响应格式返回,并使用配置的deny_code与deny_message。 - 新增
request_check_roles与request_check_mode,用于选择审查哪些消息角色,以及只审查最后一条消息还是所选角色的全部消息,与 AI Aliyun Content Moderation 中已有的选项保持一致。
- 新增
- AI Proxy Multi
- 新增
semantic负载均衡算法:不再按权重或哈希选择实例,而是把请求路由到examples与当前提示词语义最接近的实例。嵌入向量服务在semantic_opts.embeddings下配置,全局或按实例设置的threshold决定匹配需要多接近,匹配度均不达标的请求转发到semantic_opts.fallback。若嵌入服务不可达,请求同样转发到备用实例而不是直接失败。开启semantic_opts.debugging后,各实例的得分与最终选中的实例会通过响应头返回。
- 新增
控制面
- 自定义插件现在可以以完整包的形式上传,包内包含入口文件及其依赖文件,不再限于单个 Lua 文件。压缩包的顶层是
$NAME.lua,依赖模块放在$NAME/目录下,另有metadata.json;控制台会读取其中的元数据自动填充插件的分类、描述、文档链接和作者。整个包作为一个整体下发到数据面,因此不会出现插件只发布了部分文件的情况;更新时所有文件一并替换,且无需重启网关。 - 数据面 CPU 核数的许可用量现在可以按生产与非生产环境分开计量。每个网关组带有
environment属性,取值为production(默认)或non_production;许可证中相应地包含max_dp_cores与max_non_production_dp_cores。两份额度各自独立地运行用量、宽限与限制状态机,超出其中一份不会限制另一份所管辖的写操作。无法归属到已知网关组的用量计入生产额度。已有网关组按生产环境处理,本次改动之前签发的许可证不包含非生产额度,因此在把某个网关组标记为non_production之前行为不变——而一旦标记,该组就需要一张授予非生产核数的许可证。 - Stream 服务的上游现在支持
tls协议,网关会终止客户端的明文 TCP 连接,并与后端建立 TLS 会话。此前控制面只接受tcp和udp,尽管数据面一直支持四层上游使用tls。 - Docker Compose 部署包新增
portal.sh,用于在已运行的部署上启动开发者门户。该脚本会创建门户实例及其令牌、写入前端配置与数据库,并以 Compose profile 的方式启动前端,因此试用门户不再需要按手册逐步手工操作。执行portal.sh stop后再start,开发者账号与会话都会保留。 - API7 Gateway Admin API 参考文档中,每个接口现在只出现在一个位置。原先内容过载的 Service 分组已拆分为 Service、Route、Stream Route、Upstream 和 OpenAPI,同一个接口不会再重复出现在多个导航分组下。
数据面
- 全局规则筛选出的插件集现在每个请求只计算一次并跨阶段复用,而不是在每个阶段中重复计算。在通过全局规则启用 Prometheus 插件的部署上,单个 Worker 实测吞吐提升 12%。
控制台(Dashboard)
- 语言切换器不再显示与语言并不对应的国旗图标,并会标出当前生效的语言。
开发者门户
- 新增
emailAndPassword.revokeSessionsOnPasswordReset,用于控制开发者重置密码时是否吊销其它会话。默认值为true,与此前行为一致。
缺陷修复
插件
- AI Aliyun Content Moderation
- 修复问题:当
request_check_roles选中system时,放在developer角色消息中的内容不会被送去审查。developer是 OpenAI 在较新模型和 Responses API 中用来替代system的角色,因此客户端可以把指令放在该角色下,绕过审查直达 LLM。现在两个角色的内容会一并提取,已有的system条目同时覆盖这两个角色。 - 修复问题:在
realtime流式审查模式下使用协议转换器时(例如 Anthropic 客户端对接 OpenAI 兼容上游),同一段回复文本会按转换后的分片数重复提交给审查服务,而不是按上游分片提交一次。审查结果本身不受影响,但stream_check_cache_size会远早于配置值被触发,审查调用次数也随转换器的输出规模放大,带来额外的延迟和费用。
- 修复问题:当
- AI AWS Content Moderation
- 修复问题:超出 Amazon Comprehend 单段与单次请求限制的内容会被拒绝或静默截断,导致较长的提示词和回复只有一部分被审查。现在内容会按文档规定的上限切分,并分成所需数量的批次提交;同一请求内的多次调用复用同一个 HTTP 客户端,而不是每次都新建连接。
- Loki Logger
- 修复问题:
headers字段通常携带 Loki 端点的认证令牌, 此前以明文存储。在启用数据面数据加密时,该字段现在会落盘加密(参见升级须知)。
- 修复问题:
- Limit Conn
- 修复问题:当该插件配置在服务上时,该服务下的每个路由各自独立统计并发连接数,实际生效的上限因此被路由数量放大。现在计数键按插件所配置的资源确定,服务级别的限制会在其所有路由之间共享。
- Prometheus
- 修复问题:承载指标的共享内存字典中已过期的条目不会被回收,用量只增不减,最终一直处于写满状态,此后新的指标序列会被丢弃。现在过期条目会被正常回收。
- OpenID Connect
- 修复问题:在
bearer_only模式下,首尾带空白字符的Authorization请求头会被拒绝,因为空白字符被一并带进了提取出的令牌。现在会先去除首尾空白再读取令牌。
- 修复问题:在
数据面
- 修复问题:当网关使用
radixtree_host_uri路由器(Kubernetes 部署下的默认值)时,服务上配置的hosts与请求Host头之间是大小写敏感匹配。由于请求头在匹配前会被归一为小写,hosts中只要含有大写字母,该服务就永远无法匹配,其下所有路由对任何请求都返回HTTP 404。现在服务的 hosts 会被归一化,与路由 hosts 一贯的行为保持一致。本次发布之前,Docker Compose 部署因使用radixtree_uri路由器而不受影响(参见升级须知)。 - 修复问题:重写后的上游 URI 中的控制字符——例如从百分号编码的请求路径中带入的回车换行——会被原样写入上游请求行,客户端因此可以截断请求行,并向网关发往上游的请求中注入任意请求头。现在控制字符会被百分号编码。
- 修复问题:TCP/UDP TLS 监听所用的证书与私钥若以
$ENV://或$secret://引用形式存储,则不会被解析,TLS 握手因此以 PEM 解析错误失败。现在 TCP/UDP 子系统会像 HTTP 监听那样解析这些引用。 - 修复问题:配置存储的监视在无事件超时时,数据面会把修订版本推进到该时间点,仿佛已消费完所有事件,因此在超时前后到达的配置变更可能被跳过。现在超时不再推进修订版本,监视断开后的恢复重载开销也更低。
- 修复问题:全量配置重载中若某一项数据面无法接受,该项此前可用的值会被丢弃而不是保留,因此单个非法资源可能在重连后让本已正常的配置失效。现在会保留此前的值。
控制面
- 修复问题:列表接口的
order_by与direction参数未经校验就被拼接进生成的 SQL,因此非列名的取值会改变查询而不是被拒绝。现在这两个参数在所有使用处都会被校验;此前未声明这两个参数的六个列表接口——四个 AI Gateway 列表、证书 SNI 用量、告警联系人用量——现在会明确列出可用于排序的列,其它取值一律返回HTTP 400。按合法列排序的行为不变;向这些接口传入不受支持的取值时,现在会收到错误响应,而不是一个排序不确定的结果。 - 修复问题:上传自定义插件时用于读取其 Schema 的 Lua 解析器会在完整标准库可用的环境下求值上传的文件,因此一个文件可以在读取 Schema 的过程中在控制面主机上执行命令。现在解析器只加载 Schema 定义所需的库,且超过三秒预算的文件会被拒绝。普通插件的 Schema 是声明式表,不受影响。
- 修复问题:为网关组生成的 Helm 安装脚本会把数据面的私钥、证书和 CA 以运维默认的文件权限写入
/tmp下的固定路径,并且从不删除。现在脚本使用umask 077创建临时文件,文件名随机,并在退出时删除。 - 修复问题:数据面上报的指标此前按数据载荷中携带的
gateway_group_id标签存储,而不是按建立连接时认证到的凭据,因此一个数据面可以把指标序列写进其它网关组。现在该标签一律取自认证得到的身份。 - 修复问题:数据面读取配置所用的 etcd 兼容端点会转发调用方网关组命名空间之外的键,因此一个数据面可以读取、写入乃至删除其它网关组的配置。现在命名空间之外的键会被拒绝。
- 修复问题:数据面上报的注册中心健康检查与探测结果此前仅按注册中心 ID 应用,因此一个数据面可以覆盖属于其它网关组的注册中心的服务发现结果与连接状态。现在这类更新会限定在上报方所属的网关组内。
- 修复问题:
security.ssrf_protection设置对开发者门户进程不生效,因此启用后审批 webhook 与动态客户端注册仍可访问内网地址。开发者门户现在与控制面应用相同的策略。 - 修复问题:开发者门户的 API 用量接口按门户提供的开发者标识过 滤统计数据,而该标识仅在单个门户内唯一,因此一个开发者可以看到另一个门户中同名开发者的 API 产品名称与小时级调用量。现在统计数据被限定在调用方自己拥有的应用范围内。
- 修复问题:导入许可证后,控制台可能在缓存条目的整个生命周期内对所有请求返回
license clock signature is invalid,因为许可证与为其签名的时钟此前分别缓存、可以各自独立刷新。现在两者作为一个整体读取和缓存,并会相互校验,导入时也在同一个事务中写入。 - 修复问题:导入一张提高了许可核数额度的许可证之后,此前已经拦截过写操作的控制面副本仍会继续拒绝写操作,最长持续到许可证缓存过期。现在许可限制在每次请求时都按当前状态重新判定,不再缓存。
- 修复问题:在 SQL Server 上,中途被中断的查询与空结果无法区分,因此删除操作可能报告成功却没有真正记录删除,查询也可能对确实存在的配置返回空结果。现在被中断的查询会正确报错。另外,压缩事务所设置的隔离级别会残留在归还连接池的连接上,导致后续查询以可串行化级别执行,可能长时间排队在写操作之后直至超时,或与并发写操作死锁。现在压缩在独占连接上执行,并在归还连接池前复位其隔离级别。PostgreSQL 与 MySQL 部署不受这些问题影响。
控制台(Dashboard)
- 修复问题:监控页面在所选时间窗口内没有流量时,或后端上报的失败数超过请求数时,会把成功率显示为
0%,看上去像是所 有请求都失败了。这两种情况现在都显示为长破折号,因为此时并不存在可供展示的成功率。请求数与失败数本身的展示不变。 - 修复问题:离线网关实例的状态徽标在两种语言下都显示为断裂的文案,例如
Offline - In 6 DaysUntil Deletion。 - 修复问题:调试会话的采样规则预设使用了
http_uri、http_method和http_status。在数据面上,带http_前缀的变量解析为请求头,因此这些预设从不匹配,由预设创建的调试会话什么也捕获不到。预设现在改用uri、method和status。 - 修复问题:产品内的多个帮助链接指向已冻结的文档归档,而不是当前的文档集。
开发者门户
- 修复问题:发往门户后端代理的请求中若含有百分号编码的路径分隔符,实际发往上游的路径可能与代理执行访问控制检查时所用的路径不一致。现在路径分段会在解码之后再校验,含有路径分隔符、查询或片段定界符以及控制字符的分段会被拒绝。
- 修复问题:在强制启用双因素认证时,为放行登录流程而设置的豁免覆盖了整个
/api前缀,范围大于实际需要豁免的端点。现在豁免范围收窄到认证相关端点;此外,在执行该强制策略过程中若加载会话失败,请求会被拦截,而不是处于行为不确定的状态。 - 修复问题:双因素认证的密码对话框把尚未加载完成的账号列表当作「该账号没有密码」处理,因此启用双因素认证时可能跳过密码校验,强制启用流程也可能停在一个笼统的错误提示上无法继续。对话框现在会等待账号列表加载完成,并在需要时提示输入密码。
- 修复问题:启用双因素认证后会话缓存没有刷新,界面在页面重新加载之前仍显示此前的状态。
- 修复问题:缺少用于添加双因素认证锁定相关列的数据库迁移,因此从旧版本升级上来的部署在记录一次锁定时可能失败。
- 修复问题:使用已存在账号的邮箱注册时,没有提示该邮箱已被占用。
- 修复问题:门户发往控制面的请求没有设置超时时间,控制面无响应时可能导致门户请求长时间挂起。
3.10.4
发布日期:2026-07-27
升级须知
ClickHouse Logger、Elasticsearch Logger、File Logger、Loggly、Loki Logger、SkyWalking Logger、阿里云日志服务(SLS) 和 Syslog 插件的 max_req_body_bytes 与 max_resp_body_bytes 现在会被校验为不小于 1 的整数。旧版本接受的值——0、负数,以及带引号的数字(如 "1024")——现在会被拒绝并返回 HTTP 400。
升级后,已有的、带这类值的路由会在网关组的兼容性报告中被列为错误,并且不会下发到数据面;其他路由不受影响。升级前请检查这些插件的配置中是否存在设置为 0、负数或带引号数字的 max_req_body_bytes / max_resp_body_bytes,将其改为正整数,或删除该字段以使用默认值 524288。
Prometheus 插件元数据现在会拒绝那些会移除指标赖以成立的标签的 disabled_labels 配置——例如 latency 的 type,或 status 的 code。旧版本接受这类配置,导致本应区分的多组测量值被合并成同一条指标序列。
如果你的 Prometheus 插件元数据禁用了这类标签,升级后对它的任何更新都会被拒绝并返回 HTTP 400。请在升级前把这些结构性条目从 disabled_labels 中移除。route、service、consumer 等非结构性标签仍然可以禁用。
新功能
插件
- OpenID Connect
- 新增
set_raw_id_token_header。启用后,身份提供商签发的原始 ID 令牌会通过X-Raw-ID-Token请求头转发给上游服务,使上游可以自行校验令牌签名,而不必信任网关解码后的声明。
- 新增
- Proxy Rewrite
headers.set和headers.add现在支持为同一个请求头名称配置数组值,转发到上游时会生成多条独立的请求头,而不是用逗号拼接成一条。这对只读取首个同名请求头、或对重复请求头与逗号拼接值解析方式不同的上游服务尤为重要。
- Kafka Logger
- 新增
tls,支持通过 TLS 连接 Kafka broker,并由tls.verify控制是否校验 broker 证书。此前插件只能以明文连接,因此监听 TLS 端口的 broker 完全收不到日志。
- 新增
- 限流与缓存插件
- 为 Limit Conn、Limit Req 和 AI Cache 的 Redis 与 Redis Cluster 策略新增 Redis 连接 keepalive 设置(
redis_keepalive_timeout和redis_keepalive_pool),方便运营者调整空闲超时时间和连接池大小。
- 为 Limit Conn、Limit Req 和 AI Cache 的 Redis 与 Redis Cluster 策略新增 Redis 连接 keepalive 设置(
- 需要缓冲请求/响应体的插件
- 新增
max_req_body_size和max_resp_body_size,用于限制插件读入内存的请求体或响应体大小,默认值为 67108864 字节(64 MiB)。超过上限的请求体会被拒绝,响应体则会在上限处截断——Proxy Cache 例外,超限的响应会直接透传而不被缓存——从而避免单个超大 body 耗尽 worker 内存。该能力可用于 AI Proxy、AI Proxy Multi、AI Request Rewrite、AI prompt 系列插件、Request Validation、OAS Validator、Body Transformer、Response Rewrite、Proxy Cache、gRPC Transcode、SOAP 等会缓冲 body 的插件。
- 新增
- Logger 插件
- 为其余 logger 插件的 schema 补充
max_req_body_bytes和max_resp_body_bytes——ClickHouse Logger、Elasticsearch Logger、File Logger、Loggly、Loki Logger、SkyWalking Logger、阿里云日志服务(SLS) 和 Syslog——使这两个上限在配置时被校验并在控制台中展示(参见「升级须知」)。
- 为其余 logger 插件的 schema 补充
数据面
- 新增
nginx_config.stream.real_ip_from,用于列出在 stream(TCP/UDP)端口上被信任、可以发送 PROXY protocol 头的地址。当连接来自受信任地址时,客户端地址取自 PROXY protocol 头而非直连对端,使 stream 日志和基于地址的插件看到的是真实客户端,而不是网关前面的负载均衡器。该配置默认为空,且仅在启用了 PROXY protocol 的端口上生效。 - 升级健康检查引擎。检查目标现在以增量方式协调,不再整体销毁重建,因此上游扩缩容时不会出现「没有任何节点被检查」的窗口,未变更节点已累计的健康状态和失败计数也会被保留而不是被重置。
- 调试响应头
Apisix-Plugins现在按执行顺序列出实际执行过的插件,并标注各自执行的阶段(例如limit-count#access、response-rewrite#header_filter),而不是无序地列出已配置的插件。
控制面
/api/fe-config端点改由控制面二进制提供,并由console.*配置项驱动,因此控制台的 hybrid 模式、浏览器错误上报(Sentry)和侧边栏自定义外部链接分组都可以通过控制面配置或 Helm chart 配置。缺少名称或没有绝对http/httpsURL 的菜单项会被丢弃,不会下发给控制台。- 服务冲突检测现在会计入路由的 methods。同一 host 和 path 下方法集合互不相交的路由(例如
GET /foo和POST /foo)不再被判为冲突;方法范围完全相同判为 duplicate,部分重叠判为 overlapping。未配置methods的路由仍然匹配所有方法。 - 新增可选的出站 SSRF 防护。开启
security.ssrf_protection.enable后,控制面会拒绝连接环回地址、私网地址、链路本地地址和运营商级 NAT 地址——包括解析后落到这些网段的主机名——从而防止服务注册中心、SMTP 设置等功能被用来探测内网服务或云元数据端点。
控制台(Dashboard)
- 控制面版本号现在展示在顶部栏的组织菜单旁边,并支持一键复制,不再需要展开组织下拉菜单才能查看。
- 由 ADC 同步的资源(带
managed-by=adc标签)现在会在详情页展示 Managed by ADC 标记和提示横幅,对其执行编辑、删除、新建操作时会提示:下一次 ADC 同步会覆盖手工修改并移除手工添加的子资源。 归属于被 ADC 管理的 Service 或 Consumer 的子资源,即使自身没有该标签也会给出提示。这些提示仅作告知,不会阻断操作。 - 服务与路由的冲突提示弹窗新增 Methods 列,便于判断两条路由在哪些方法上发生冲突。未配置
methods的路由显示为 All。
缺陷修复
插件
- AI Proxy、AI Proxy Multi 和 AI Request Rewrite
- 修复问题:网关发往 LLM 服务商的请求会携带客户端自身的请求头,包括
Cookie、Authorization以及任意自定义头,导致最终用户的凭证泄漏给上游服务商。现在网关只发送插件自身设置的请求头。 - 修复问题:当 LLM 返回错误响应时,
$apisix_upstream_response_time和$llm_time_to_first_token记录的是秒(例如0.240)或0,而成功响应记录的是毫秒。现在错误路径也统一以毫秒上报,与成功路径一致。
- 修复问题:网关发往 LLM 服务商的请求会携带客户端自身的请求头,包括
- OpenID Connect
- 修复问题:收到 state 与当前会话不匹配的授权回调时——例如在同一浏览器中先后发起了两个登录流程——会返回
HTTP 500。现在网关改为 重定向到最初请求的页面。 - 修复问题:身份提供商 userinfo 中的空 JSON 数组(例如
"roles": [])在复用已有会话的请求中会被重新编码为空对象({})写入X-Userinfo头,导致按数组解析该字段的上游服务出错。现在空数组仍然是数组。
- 修复问题:收到 state 与当前会话不匹配的授权回调时——例如在同一浏览器中先后发起了两个登录流程——会返回
- wolf-rbac
- 修复问题:当鉴权服务返回成功但不带
userInfo时,客户端自己传入的X-UserId、X-Username、X-Nickname请求头会被透传给上游服务,使调用方可以伪装成任意身份。现在这些请求头在转发前总是被清除。
- 修复问题:当鉴权服务返回成功但不带
- Limit Count
- 修复问题:在
window_type: sliding且开启延迟同步时,剩余配额的计算没有按滑动窗口加权,导致窗口边界附近放行的请求明显多于配置值。现在剩余计数按窗口加权计算。
- 修复问题:在
- Limit Conn 和 Limit Req
- 修复问题:Redis 连接没有归还到 keepalive 连接池,导致每个请求都新建一条 Redis 连接,已配置的 keepalive 参数完全不生效。现在连接会被正确复用。
- Prometheus
- 修复问题:当指标使用的共享内存字典写满时,网关可能进入死循环,把某个 worker 的 CPU 占用拉满至 100%,且在流量停止后也不会恢复。现在字典写满会优雅降级,并记录「上报的指标数据可能不完整」的日志。
数据面
- 修复问题:使用
least_conn负载均衡时,增删上游节点会丢弃已记录的连接数,导致算法退化为轮询,把新请求发给已经持有长连接的节点。现在负载状态会在上游扩缩容期间保留。 - 修复问题:当插件字段引用的密钥无法解析时——例如环境变量未设置,或密钥管理器返回错误——失败是静默的,未解析的引用会被当作字面值使用。现在网关会记录错误日志,指明具体的引用和所在字段。
- 修复问题:网关通过执行
/bin/hostname获取主机名,因此在不包含该二进制的镜像上无法上报主机名,网关实例在控制台中显示为没有主机名。现在改为通过系统调用获取。 - 修复问题:
nginx_config.envs中值包含空格、引号或反斜杠的条目会生成非法的 NGINX 配置,导致网关启动失败。现在这些值会被正确地加引号和转义。 - 修复问题:通过 CLI 停止网关后立即启动可能失败,因为上一个实例尚未完全退出。现在 CLI 会等待其停止后再启动新实例。
- 修复问题:网关容器被强制杀死(而非正常关闭)后,残留的 worker event socket 可能导致下次启动无法绑定。现在启动时会先清理这些残留文件。
- 修复问题:在 arm64 架构上,某个依赖会把第二份 JSON 库拉入网关的模块搜索路径,遮蔽内置版本并把空数组编码成非法 JSON。现在已移除该冗余依赖,始终使用内置库。
控制面
- 修复问题:针对同一资源的两个并发 PATCH 请求可能各自在对方写入前读取资源,导致只有最后一次写入生效,而两个请求都返回成功。现在同一资源上的 PATCH 请求会被串行化。
- 修复问题:
PATCH /apisix/admin/routes在应用补丁时没有用路由 schema 校验合并结果,因此一次 PATCH 可能持久化超出 schema 限制的路由(例如超过 64 条 path),而后续的PUT请求和adc sync又会拒绝它。现在合并结果会在存储前完成校验。 - 修复问题:数据库连接池中的连接会被无限期复用,因此数据库发生主备切换后,控制面可能继续使用绑定在已被降级为只读的旧主库上的连接。现在连接生命周期默认限制为 1 小时,并可通过
database.max_lifetime调整。 - 修复问题:导入证书链已过期的 License 时,报错信息为
license certificate comes from an invalid issuer,指向签发机构而不是过期本身。现在证书链已过期或尚未生效会返回带有相应时间戳的专门提示。确实来自未知签发机构的证书仍然报告 issuer 非法。 - 修复问题:当前数据面核数统计包含了已停止上报心跳的实例——这些实例在被标记为离线前会在 LostConnection 状态停留最长两小时——因此数据面缩容或崩溃后很久,控制台上的核数用量仍然偏高。现在只统计处于标准运行模式的已连接实例。基于心跳用量计算的 License 计费不受影响。
控制台(Dashboard)
- 修复问题:路由 path 列表和服务 host 列表允许添加超过 schema 限制(64 条 path、32 个 host)的条目。此时新建资源会返回原始的服务端错误,而编辑资源则可能存下随后被
adc validate和adc sync拒绝的配置。现在列表达到上限后会隐藏 Add 控件;已经超出上限的列表仍会完整展示所有条目,便于删除多余项。
3.10.3
发布日期:2026-07-14
升级须知
多个数据面共享内存(lua_shared_dict)默认值被调高,因此在默认配置下,3.10.3 网关启动时预留的共享内存比 3.10.2 约多 365 MiB:
| 共享字典 | 3.10.2 默认值 | 3.10.3 默认值 |
|---|---|---|
prometheus-metrics(高级指标) | 15 MiB | 128 MiB |
kubernetes、nacos、nacos-stream、consul(服务发现) | 各 20 MiB | 各 64 MiB |
tracing_buffer(SkyWalking) | 10 MiB | 32 MiB |
api-calls-for-portal | 10 MiB | 64 MiB |
这些字典在网关启动时分配,无论对应功能是否被使用,因此该增长适用于每一个 3.10.3 网关。升级前,请调高网关容器的内存 requests 和 limits(在 Kubernetes 中还应检查节点的内存压力与驱逐阈值),避免网关被 OOM 杀死。如果你未使用某项功能——例如某种未配置的服务发现类型——可以通过网关配置或 Helm chart 的共享字典值把对应字典调回原先的大小。
内置 Dashboard 用户现在会在连续密码登录失败后被临时锁定。默认策略为启用状态,同一用户和来源 IP 连续失败 5 次后锁定 15 分钟。管理员可以通过新的登录失败限制系统设置调整或关闭该策略。升级后新密码和被修改的密码也必须至少 12 个字符,并继续满足原有复杂度要求。已有密码在登录时不会重新校验长度。
如果内置用户启用了双因素认证(2FA),该用户的 HTTP Basic Auth 会被拒绝,因为 Basic Auth 无法携带第二因素。程序化集成请改用 Token 认证;Token 通过 X-API-KEY 请求头传入,不需要携带 2FA 验证码。
网关现在通过 apisix.trusted_addresses 判断是否信任客户端传入的 X-Forwarded-* 和 RFC 7239 Forwarded 请求头。当未配置 trusted_addresses,或请求来自不可信地址时,网关会在转发上游前用自身观测到的值覆盖 X-Forwarded-Proto、X-Forwarded-Host 和 X-Forwarded-Port,并清除 Forwarded 请求头。如果上游应用依赖可信负载均衡器或反向代理传入的原始转发协议、host 或端口,请将该代理的 IP 或 CIDR 配置到 trusted_addresses。
openid-connect 插件不再默认把 refresh_session_interval 设为 900 秒。现在只有显式配置 refresh_session_interval 时才会执行周期性静默重认证。如果你的部署依赖此前 900 秒刷新一次的行为,请在升级前或升级过程中显式设置 refresh_session_interval: 900。
对于使用 SQL Server 的部署,控制面现在会先创建并准备数据库,再让其他组件连接,并启用 READ_COMMITTED_SNAPSHOT,避免网关配置读取被写事务阻塞。若既有 SQL Server 数据库尚未启用该设置,首次启动会以 ROLLBACK IMMEDIATE 应用该数据库级变更;正在进行的数据库事务和连接可能会被断开一次,之后连接池会重新连接,后续启动不会重复执行该操作。
控制面现在会在存储时加密更多保存凭证的插件字段。由于 API7 EE 升级时先升级控制面、再升 级数据面,在升级间隙中,3.10.3 的控制面会加密这些字段,而仍为 3.10.2 的旧数据面无法解密,可能导致相关插件失效,直到数据面也完成升级。
本次新增加密的字段,按插件列出如下:
- ai-cache:
semantic.embedding.openai.api_key、semantic.embedding.azure_openai.api_key
如果你使用了上述插件的相关字段,请在控制面升级后尽快将数据面升级到 3.10.3,并在两侧都升级到 3.10.3 之前避免编辑这些插件。
新功能
插件
- AI Cache
- 在精确匹配缓存之外,新增语义(L2)缓存层,通过 RediSearch 按 embedding 相似度匹配提示词。流式 LLM 响应现在可以被缓存并回放,而不再被跳过。新增 Prometheus 指标,报告缓存命中、未命中、绕过和 embedding 延迟。
- AI Aliyun Content Moderation
- 新增
request_check_roles,用于选择要审查的请求角色(user、tool和/或system)。user和tool内容遵循request_check_mode(last或all,默认last);选择system时,系统内容会在每个请求中检查。长内容现在以线性时间分块,且对多字节(UTF-8)安全。
- 新增
- AI AWS Content Moderation
- 请求审查现在在 AI 协议识别之后执行,检查上游 LLM 实际可见的解码后提示词内容,而不是原始 HTTP JSON 外壳。拒绝响应现在以提供商兼容格式返回,并新增可配置的
check_request、deny_code和deny_message。
- 请求审查现在在 AI 协议识别之后执行,检查上游 LLM 实际可见的解码后提示词内容,而不是原始 HTTP JSON 外壳。拒绝响应现在以提供商兼容格式返回,并新增可配置的
- IP Restriction
- 新增可配置的
response_code(403或404,默认403),在请求被拦截时返回,使运营者可以用404隐藏资源是否存在。
- 新增可配置的
- File Logger
- 日志文件
path现在可以在插件元数据中设置一次并在多条路由间共享,不必在每条路由的插件配置中都填写。插件配置中设置的path仍然优先于元数据中的值。
- 日志文件
- Logger 插件
- 为 HTTP Logger、RocketMQ Logger、TCP Logger、Tencent Cloud CLS 和 UDP Logger 的 schema 新增
max_req_body_bytes和max_resp_body_bytes,使请求/响应体大小上限(默认 524288 字节)在配置时被校验并在 Dashboard 中展示。
- 为 HTTP Logger、RocketMQ Logger、TCP Logger、Tencent Cloud CLS 和 UDP Logger 的 schema 新增
- 限流插件
- 为 Limit Count、Limit Count Advanced、GraphQL Limit Count 和 AI Rate Limiting 的 Redis 与 Redis Cluster 策略新增 Redis 连接 keepalive 设置(
redis_keepalive_timeout和redis_keepalive_pool),方便运营者调整空闲超时时间和连接池大小。
- 为 Limit Count、Limit Count Advanced、GraphQL Limit Count 和 AI Rate Limiting 的 Redis 与 Redis Cluster 策略新增 Redis 连接 keepalive 设置(
数据面
- 新增
apisix.trusted_addresses,根据解析后的客户端地址控制网关是否信任客户端传入的X-Forwarded-*和Forwarded请求头。 - 新增
apisix.match_uri_encoded_slash。启用后,编码斜杠(%2F)在路由匹配期间保持编码状态,可作为路径参数的一部分,而不是路径分隔符。 - 在 standalone YAML 模式中,环境变量占位符现在会在 YAML 解析前替换。未加引号的占位符可以解析为原生布尔值或数字;加引号的占位符仍保持字符串,从而精确保留大整数 ID 和 token 值。
控制面
- 为内置 Dashboard 用户新增 TOTP 双因素认证。用户可在账号设置中注册、启用、关闭和恢复 2FA;管理员可重置用户的 2FA 状态。
- 为内置用户新增登录失败限制。连续失败登录会 临时锁定用户和来源 IP,写入审计事件,并返回明确的锁定提示。
- 新增双因素认证的 Dashboard UI:账号设置中的二维码和恢复码设置流程、登录时的 OTP 步骤,以及管理员重置用户 2FA 的操作。
- 密码表单和随机密码生成已更新为新的 12 字符最小长度。
开发者门户
- 新增强制双因素认证选项。当启用 2FA 且设置了
twoFactor.required时,开发者必须先完成 2FA 注册才能访问受保护页面,该要求在登录和代理层都会强制执行。
缺陷修复
插件
- AI Proxy 和 AI Proxy Multi
- 修复问题:包含 tool result 且混有其他内容的 Anthropic Messages 请求会被转换成非法的 OpenAI Chat 消息顺序,导致 OpenAI 兼容上游拒绝该会话后续的每个请求。现在 tool 消息会紧跟在包含 tool call 的 assistant 消息之后,旁边的文本或媒体会保留在后续 user 消息中。若干其他 Anthropic 到 OpenAI 的转换细节也已与 LiteLLM 兼容行为对齐,包括工具名清洗、长工具名冲突处理、adaptive thinking effort、结 构化输出 schema 提取、空数组编码和内容块形状。
- 修复问题:结构化 chat content 可能以 table 形式传给下游 AI 插件并导致请求处理错误。协议适配器现在会在 AI guard 和 cache 插件消费前一致地拍平文本内容。
- AI Lakera Guard
- 修复问题:在
action: alert且fail_open: false的流式响应中,Lakera API 报错或超时可能放行已流出的响应,而不是 fail closed。现在 Lakera 报错会按fail_open处理,严格配置下会拦截响应。
- 修复问题:在
- AI AWS Content Moderation 和 AI Aliyun Content Moderation
- 修复问题:
deny_code此前接受任意数字。现在会校验为200–599范围内的整数 HTTP 状态码(默认200),超出范围的值会在配置时被拒绝。
- 修复问题:
- AI Aliyun Content Moderation
- 修复问题:在 body filter 中返回
ngx.OK可能中断后续 body filter 处理。现在插件会正常返回,使其他 filter 可以继续执行。
- 修复问题:在 body filter 中返回
- AI Rate Limiting
- 修复问题:部分已配置的 Redis 字段会被丢弃并替换为默认值——redis-sentinel 策略的
redis_username/redis_password,以及 redis 和 redis-cluster 策略的redis_keepalive_timeout/redis_keepalive_pool。现在所有已配置的 Redis 字段都会被转发。
- 修复问题:部分已配置的 Redis 字段会被丢弃并替换为默认值——redis-sentinel 策略的
- gRPC Transcode
- 修复问题:空的 protobuf
repeated字段会被编码为{}而不是 JSON 数组([])。现在空 repeated 字段会显示为数组,包括嵌套消息和 descriptor-set 方式的消息。
- 修复问题:空的 protobuf
- Key Auth 和其他 Consumer 认证插件
- 修复问题:如果 Consumer 凭据引用了无法解析的 secret,数据面可能仍把未解析的字面量加入索引,并用该字面量完成认证。现在引用的 secret 无法解析时,Consumer 认证会 fail closed。
- Secret 引用
- 修复问题:更新或删除
/secrets配置不会使 secret LRU 缓存失效,因此旧 secret 值可能继续使用到缓存过期,甚至无限期使用。现在 secret 配置变化后会重新解析 secret 引用。
- 修复问题:更新或删除
- Proxy Rewrite
- 修复问题:同时配置
use_real_request_uri_unsafe和uri时,请求 query string 会在 URI 改写中丢失。现在会保留原始 query string,并在改写后的 URI 已含 query 时正确合并。
- 修复问题:同时配置
- Loggly
- 修复问题:不同 route 的批量 Loggly 日志可能使用错误的 token 或 tags,因为异步处理器复用了最新 route 的配置。现在每个批处理器都会保留自己的 route 配置。
- Datadog
- 修复问题:较大的合并 DogStatsD datagram 可能超过常见的 8192 字节 agent 缓冲区并被静默截断。现在只有在 payload 可容纳时才合并,否则回退为每个 metric 一个 datagram。
- Zipkin
- 修复问题:明确标记为未采样的请求仍会构造完整 span tag table 和 access 阶段子 span。现在未采样请求会跳过这些额外追踪工作,同时保留 trace 传播。
- OpenTelemetry
- 修复问题:运行时更新 OpenTelemetry 插件元数据不会重建用于注入 core span 的 tracer,因此这些 span 可能继续使用旧 collector 或 resource 设置,直到 worker 重启。现在元数据变化后 tracer 会刷新。
- 修复问题:
additional_attributes在 log 阶段变量填充前求值,导致依赖最终请求状态的属性缺失或过期。现在这些属性在 log 阶段求值。 - 修复问题:当
trace_id_source设为x-request-id时,非合法十六进制的X-Request-Id值(例如 UUID)或重复的请求头可能返回HTTP 500。现在会校验该值,无法使用时回退为随机的合法 trace ID。 - 修复问题:插件元数据 schema 接受
resource属性和collector.request_headers的非标量值,这些值随后会在运行时被静默丢弃。现在这类值会在配置时被拒绝。
- OpenID Connect
- 修复问题:
refresh_session_interval错误地默认设为900,即使用户未配置也会启用静默重认证。该默认值已移除(见升级须知)。
- 修复问题:
- MQTT Proxy
- 修复问题:
protocol_name过去是必填项,尽管标准默认值是MQTT。现在该字段可省略,并默认使用MQTT。
- 修复问题:
- Forward Auth
- 修复问题:当
request_method为POST时,插件在缓冲请求体后仍可能把客户端的Transfer-Encoding、Content-Length和Expect请求头转发给认证服务,导致请求 framing 不一致。现在这些客户端 framing 头不会再复制到认证服务请求中。
- 修复问题:当
- Authz CASBIN
- 修复问题:在不同 route 之间切换不同 Casbin model 或 policy 形状时,可能触发
casbin enforce error/invalid request size。内置lua-casbin依赖已更新,包含相关 enforce 修复。
- 修复问题:在不同 route 之间切换不同 Casbin model 或 policy 形状时,可能触发
- Request ID
- 修复问题:配置
algorithm: range_id但省略可选 range 对象时可能返回HTTP 500。现在 range 对象有默认值。
- 修复问题:配置
- Workflow
- 修复问题:Workflow action 插件可能在 workflow 决定跳过或执行该 action 前先运行
_meta.pre_functionhook,从而影响本不应执行的 action。现在 workflow 会先决定是否运行 action,再执行这些 meta hook。
- 修复问题:Workflow action 插件可能在 workflow 决定跳过或执行该 action 前先运行
- Request Validation
- 修复问题:
Content-Type带 charset 参数或大小写不同(例如application/x-www-form-urlencoded; charset=utf-8)的表单请求体未被识别为 form-urlencoded,因而被当作 JSON 解析并以HTTP 400拒绝。现在这类 Content-Type 会被识别并按表单体校验。
- 修复问题:
数据面
- 修复问题:部分日志文件被 rotation 后,网关可能仍保持旧文件句柄。现在部分 rotation 后也会正确重新打开日志。
- 修复问题:当配置源上报的 revision 比网关已见过的更小时(例如控制面数据库被恢复到较早状态),网关可能持续下发过期配置,直到 worker 重启。现在观测到更小的 revision 时会强制进行一次完整配置重新同步。
- 修复问题:通过 global rule 或 consumer 挂载的插件(如
ai-proxy-multi)可能因网关无法在请求时获取插件的父配置而返回HTTP 5xx。现在所有承载插件的资源类型都能被正确解析。 - 修复问题:当
client-control配置max_body_size: 0(不限制)时,分块请求体仍可能被以HTTP 413拒绝。现在max_body_size为0会正确地对分块请求禁用大小检查。
控制面
- 修复问题:配置 revision 刚变化后、下一次 heartbeat 尚未上报新 revision 前,网关实例可能短暂显示为 OutOfSync。现在新增宽限窗口,在正常同步窗口内仍保持最近有 heartbeat 的实例为 Healthy。
- 修复问题:兼容性报告被截断为 200 条且顺序不稳定,因此大报告可能隐藏 error,并在不同网关实例间显示不同结果。现在控制面会存储完整且排序后的 报告,并基于全部条目计算兼容性。
- 修复问题:secret provider 的请求体可能匹配与 URL 路径中 provider 名称不同的类型,导致数据面丢弃或误读已保存 secret。现在控制面会按路径选择的 provider 类型校验请求体。
- 修复问题:控制面接受了一些数据面会静默丢弃的核心资源配置,包括非法 TLS、filter 和 IP match 配置。现在这些配置会在发布前被校验拒绝。
- 修复问题:运行时 services 端点上的插件配置未被校验,因此带有非法插件配置的 service 会被接受,随后被数据面静默丢弃。现在 service 的插件配置会被校验,非法时以
HTTP 400拒绝。 - 修复问题:OpenAPI schema 会拒绝 IPv6 upstream node host。现在 IPv6 host 可以被接受。
- 修复问题:batch
ssls校验使用了 SNI schema 而不是 SSL schema,导致缺少证书字段的条目可能通过校验。现在 batch SSL 校验使用正确 schema。 - 修复问题:审计日志导出只返回前 256 条。现在会导出所有匹配的审计日志。
- 修复问题:凭据查询索引可能被不执行数据库迁移的组件删除,且部分启动 schema repair 会不必要地重建当前索引。现在 schema repair 会保留当前索引,仅修复过期形状。
- 修复问题:在大型部署中,heartbeat 和实例状态查询可能变慢。新增索引和 Go 侧状态计算改善了这些查询。
3.10.2
发布日期:2026-06-29
升级须知
控制面现在会在存储时加密更多保存凭证的插件字段。由于 API7 EE 升级时先升级控制面、再升级数据面,在升级间隙中,3.10.2 的控制面会加密这些字段,而仍为 3.10.1 的旧数据面无法解密,可能导致相关插件失效,直到数据面也完成升级。
本次新增加密的字段,按插件列出如下:
- limit-count、limit-count-advanced 和 graphql-limit-count:
redis_password、sentinel_password - limit-conn:
redis_password - limit-req:
redis_password - ai-rate-limiting:
redis_password、sentinel_password - elasticsearch-logger:
headers(自定义认证请求头) - openid-connect:
session.redis.password - ai-cache:
redis_password - ai-lakera-guard:
api_key
如果你使用了上述插件的相关字段,请在控制面升级后尽快将数据面升级到 3.10.2,并在两侧都升级到 3.10.2 之前避免编辑这些插件。
当 hmac-auth 启用 validate_request_body 时,默认的 max_req_body_size 现在为 67108864 字节(64 MiB),与 Apache APISIX 对齐。在 3.10.1 中该默认值为 524288 字节(512 KiB),会以 HTTP 413 拒绝 512 KiB 到 64 MiB 之间的请求体。升级后,这类请求默认会被接受。如果你依赖较低的上限,请显式设置 max_req_body_size 以恢复。
开发者门户的注册同意项现在通过单个 signUpConsentLabel 选项配置(渲染在同意复选框旁边的 HTML 片段),且仅在配置了该标签时才强制要求同意。原有的 tosURL 和 beforeSignUpButtonHtml 选项已移除。如果你的门户配置设置了其中任一项,请在升级前将内容迁移到 signUpConsentLabel,否则注册同意文案将不再显示。
新功能
插件
- AI Cache(新插件)
- 缓存 LLM 响应,使相同的请求从缓存返回,而不再重复调用上游模型。精确匹配缓存以归一化后的请求体为键,存储在 Redis 中;缓存命中时返回存储的响应,并带
X-AI-Cache-Status: HIT和X-AI-Cache-Age响应头。流式请求会被跳过(X-AI-Cache-Status: BYPASS)。
- 缓存 LLM 响应,使相同的请求从缓存返回,而不再重复调用上游模型。精确匹配缓存以归一化后的请求体为键,存储在 Redis 中;缓存命中时返回存储的响应,并带
- AI Lakera Guard(新插件)
- 通过 Lakera Guard API 检测 AI 流量中的提示词注入和其他不安全内容。
direction选项(input、output或both)用于选择插件扫描请求提示词、LLM 响应(包括流式响应)还是两者。被标记的流量会以可配置的deny_code拒绝,或在action设为alert时仅记录日志。
- 通过 Lakera Guard API 检测 AI 流量中的提示词注入和其他不安全内容。
- AI Aliyun Content Moderation
- 新增
request_check_mode(last或all,默认last),用于控制审查多轮对话的范围:last仅检查最后一个 user 轮次,all检查每个 user 轮次。仅审查user角色的内容,忽略system和assistant内容。长内容现在以线性时间分块,且对多字节(UTF-8)安全。
- 新增
- AI Proxy
- 发送给 logger 插件的结构化
llm_summary对象(启用logging.summaries时)现在包含更多 AI 可观测性字段:stream、tool_count、has_tool_calls、end_user_id、cache_read_input_tokens、cache_creation_input_tokens和reasoning_tokens。
- 发送给 logger 插件的结构化
- Elasticsearch Logger
- 新增通过自定义请求头向 Elasticsearch 认证的支持(
headers选项,例如Authorization: Bearer <token>或 API key 请求头),作为基本auth的替代方式。
- 新增通过自定义请求头向 Elasticsearch 认证的支持(
- OpenID Connect
- 新增 Redis 作为会话存储后端。将
session.storage设为redis并配置session.redis(host、port 等选项),即可把会话存储在 Redis 而非会话 cookie 中;默认仍为cookie。
- 新增 Redis 作为会话存储后端。将
数据面
- 新增
log_format_extra——一种用于 logger 插件的叠加式日志格式,它在默认的丰富日志格式上追加字段,而不像log_format那样替换默认格式。新增变量$upstream_unresolved_host记录 DNS 解析前配置的上游 host。log_format_extra可通过插件元数据全局设置,也可按路由 设置。 - 为流(L4)TCP 代理新增按端口的 PROXY protocol 控制。每个
stream_proxy.tcp条目可独立启用接收 PROXY protocol(proxy_protocol)和向上游发送 PROXY protocol(proxy_protocol_to_upstream),覆盖全局默认值。 - 新增
max_post_args_readable_size配置项(默认 64 MiB),用于限制在匹配post_arg.*路由谓词(针对 JSON 和 multipart 请求)时读取的请求体大小。设为0可禁用该限制。 - 调试会话现在会把每个请求的日志作为 OpenTelemetry span event 记录在请求的 root span 上,因此无需外部日志收集器即可在 trace 中查看每个请求的日志。
控制面
- 新增数据面的 RPM 安装方式,与现有的 Docker 和 Helm 方式并列。Dashboard 的网关组部署页面新增 RPM 标签页;在隔离网络主机上安装
api7-gatewayRPM 后,生成的离线脚本会下发网关组客户端证书、写入网关配置,并将实例接入控制面。
开发者门户
- 禁用 API Hub:运营者可通过新增的
apiHub.enabled配置开关完全关闭 API Hub。禁用后,导航中的 API Hub 链接会隐藏,API Hub 页面返回 not-found,且 API Hub 的 URL 会从 sitemap 中移除。 - 强制邮箱验证:可配置在注册和 登录时要求开发者先验证邮箱地址才能完成认证。
- 自定义 PostgreSQL schema:门户可以部署到自定义的 PostgreSQL schema(而非
public),按连接应用该 schema 的search_path并运行 schema 范围内的迁移。 - 平台管理员的组织管理:管理员的 Organizations 页面现在可以接管组织(成为其 owner)或删除组织,作为对原有用户管理操作的补充。
- 文档 Markdown 与 LLM 端点:门户内文档站现在提供 Markdown 和面向 AI 工具的 LLM 友好文本端点,且可以将单个文档页面排除在这些端点之外,同时仍可在文档界面中正常阅读。
缺陷修复
插件
- AI Proxy
- 修复问题:当上游返回的工具调用的
arguments不是合法 JSON 时,整个响应转换会被中断,客户端收不到任何内容。现在该非法工具调用会回退为空参数对象,响应的其余部分(包括任何文本内容)得以保留。 - 修复问题:携带
tool_choice但没有可用tools的请求(例如只有一个在转换中被丢弃的内置工具)会带着孤立的tool_choice转发并被上游拒绝。现在这样的tool_choice(以及parallel_tool_calls)会被移除。另外,上游省略最后完成块的流式 Anthropic 请 求不再让客户端挂起到超时——流现在会被正确终止。 - 修复问题:当上游 LLM 返回错误状态(如
HTTP 429或5xx)时,错误响应体被丢弃,客户端收到空响应体。现在上游错误响应体和 content type 会被保留,ai-proxy-multifallback 场景下也是如此。
- 修复问题:当上游返回的工具调用的
- AI Proxy Multi
- 修复问题:构建工作实例池失败时可能抛出 Lua 错误并破坏性地清空池状态。现在该失败路径对 nil 安全且不具破坏性。
- Limit Count
- 修复问题:当
count或time_window来自变量时,非法值(非整数、零或负数、或超出安全整数范围)会被静默忽略,从而可能完全失效限流。现在这类值会被校验并拒绝,堵住了一处限流绕过。 - 修复问题:使用 Redis 策略和滑动窗口计数时,检查与自增不是原子操作,因此并发请求可能超过配置的上限。现在计数通过 Redis 脚本原子完成。
- 修复问题:当
- Limit Req
- 修复问题:限流计数的键设置方式导致挂在共享资源(如 Consumer)上的限流对每条路由分别计数,而不是共用一个桶。现在计数按父资源为键,因此 Consumer 级别的限流会在该 Consumer 的所有路由间共同生效。
- HMAC Auth
- 修复问题:当启用
validate_request_body且请求体超过max_req_body_size时,请求会以容易误解的HTTP 401被拒绝。现在改为以HTTP 413拒绝。默认的max_req_body_size也提升至 64 MiB( 见升级须知)。
- 修复问题:当启用
- Attach Consumer Label
- 修复问题:当匹配到的 Consumer 没有标签时,客户端可以伪造已配置的请求头,因为插件只在存在标签值时才覆盖该请求头。现在已配置的请求头总会从客户端请求中剥离,即使 Consumer 没有匹配的标签。
- Redirect
- 修复问题:
http_to_https仅重定向 scheme 恰好为http的请求,因此以非 HTTP、非 HTTPS scheme 到达的请求(例如通过伪造的X-Forwarded-Proto)不会被重定向。现在它会重定向所有非 HTTPS 的 scheme。
- 修复问题:
- Response Rewrite
- 修复问题:当上游响应被压缩(gzip 或 brotli)时,
filters作用在压缩字节上而无法匹配,产生损坏的响应体。现在会先解码响应再执行 filters。
- 修复问题:当上游响应被压缩(gzip 或 brotli)时,
- Batch Requests
- 修复问题:当某个流水线子请求超时时,响应数组可能比子请求数多出条目(一个多余的空对象)。现在子响应的数量总是与子请求的数量一致。
- Loki Logger
- 修复问题:从变量解析出的日志标签被写回共享的插件配置,导致第一个请求的值被冻结并复用于后续所有请求。现在标签会按请求解析。
- Tencent Cloud CLS
- 修复问题:启用
include_req_body时,由于未在 access 阶段读取请求体,请求体无法被捕获。现在会读取请求体,使其包含在上传的日志中。
- 修复问题:启用
- Authz Keycloak
- 修复问题:启用
lazy_load_paths时,按 URI 解析 Keycloak 资源时包含了请求的 query string,导致带 query 参数的请求无法匹配到资源而被拒绝。现在会在解析前剥离 query string。
- 修复问题:启用
- CAS Auth
- 修复问题:CAS 单点登出(SLO)回调
POST被代理到上游,而不是由插件处理。现在该回调由插件终止,不再转发到上游。
- 修复问题:CAS 单点登出(SLO)回调
- gRPC Web
- 修复问题:一条调试日志语句把解码后的请求体写入错误日志。该语句已移除,请求负载不再泄漏到日志中。
数据面
- 修复问题:在日志格式中解析点号上下文变量(如
$consumer.username或$llm_summary.model)时,若父对象不存在(例如没有 consumer 的未认证请求),会抛出错误并丢弃该日志行。现在缺失的值会被优雅处理。 - 修复问题:在一次瞬时 DNS 或服务发现失败后,域名上游即使在名称重新解析成功后仍可能持续返回
HTTP 503。现在上游会在解析成功后恢复。 - 修复问题:当节点健康状态变化时,一致性哈希(chash)环会按健康子集重建,导致原本属于健康节点的键被重新映射。现在该环会保持稳定,只有故障节点的键会被重新映射。
- 修复问题:配置指令中的环境变量替换在一个变量名是另一个变量名的前缀时,可能匹配到错误的变量。现在变量名会被精确解析。
- 修复问题:升级 Prometheus 指标库(
nginx-lua-prometheus-api7升至0.20260623),移除可能导致整次抓取被拒绝的重复指标序列。
控制面
- 修复问题:运行最新网关版本的数据面在其配置报告包含错误时会被标记为 Incompatible。现在运行最新版本的数据面会保持 Compatible,配置错误仍会在兼容性报告摘要中呈现。
开发者门户
- 修复问题:启用或关闭双因素认证时并未真正校验账号密码,备份码对话框可能显示为空,且在登录时输入错误的 TOTP 验证码会跳转到首页而非显示错误。现在密码校验、备份码展示和 TOTP 错误处理都能正确工作。
- 修复问题:邮箱域名的 SSO 策略此前仅在 UI 层强制,因此直接调用认证端点可以绕过它。现在该策略在服务端强制:对于要求使用 SSO 的域名,密码登录、magic link 和密码重置请求都会被拒绝。
3.10.1
发布日期:2026-06-15
不兼容变更
插件
-
升级说明
jwt-auth现在默认校验 token 的exp(过期)和nbf(生效时间)声明。此前,未设置claims_to_verify(或将其设为空列表)的 consumer 会接受任何签名正确的 token,包括已过期的 token。数据面升级后,这类 token 会被以HTTP 401拒绝。如果你依赖已过期 token 仍被接受,请在升级前评估此行为变更。如需只校验特定声明,请在 consumer 配置中显式设置
claims_to_verify。 -
Batch Requests
升级说明batch-requests插件现在会限制批量请求的规模。流水线子请求的数量由新增的插件元数据选项max_pipeline_items限制(默认1000),超过上限的批量请求会被以HTTP 400拒绝。包含文档之外字段的流水线条目现在会被拒绝,且每批的timeout至少为1毫秒。如果你发送的批量请求超过 1000 个子请求,请在插件元数据中调大
max_pipeline_items。如果客户端发送了未文档化的条目字段,请在升级前移除它们。
升级须知
控制面现在会在存储时加密更多保存凭证的插件字段。由于 API7 EE 升级时先升级控制面、再升级数据面,在升级间隙中,3.10.1 的控制面会加密这些字段,而仍为 3.10.0 的旧数据面无法解密,可能导致相关插件失效,直到数据面也完成升级。
本次新增加密的字段,按插件列出如下:
- http-logger:
auth_header - kafka-logger:
brokers.sasl_config.password - splunk-hec-logging:
endpoint.token - loggly:
customer_token - openfunction:
authorization.service_token - azure-functions:
authorization.apikey,以及插件元数据master_apikey - ai-aws-content-moderation:
comprehend.secret_access_key - openid-connect:
session.secret - error-log-logger(插件元数据):
kafka.brokers.sasl_config.password
如果你使用了上述插件的相关字段,请在控制面升级后尽快将数据面升级到 3.10.1,并在两侧都升级到 3.10.1 之前避免编辑这些插件。
此前仅 limit-count-advanced 独有的全部能力——redis-sentinel 策略、滑动窗口计数、在一份配置中设置多个独立限流(rules)、由 NGINX 变量驱动的动态 count 和 time_window、以及延迟 Redis 同步(sync_interval)——现已内置到 limit-count 插件中。既有的 limit-count-advanced 配置可继续原样使用(该插件作为薄封装保留),无需做配置迁移。
一个升级时的影响:对于基于 Redis 的策略,计数器存储格式发生了变化,且计数器 key 现在带版本号。既有计数器不会被迁移——它们会按各自的 TTL 自然过期——因此限流计数器会在升级时刻重置一次。(local 策略本就在重启时重置。)会有一个短暂的计数重置窗口,无需任何操作。
为了限制内存占用,多个插件现在会在缓冲之前拒绝过大的请求体:
- hmac-auth:当启用
validate_request_body时,请求体大小由新增的max_req_body_size选项限制(默认524288字节,即 512 KiB)。 - forward-auth、ai-proxy、ai-proxy-multi:请求体大小由新增的
max_req_body_size选项限制(默认67108864字节,即 64 MiB),超过上限的请求会被以HTTP 413拒绝。
这些默认值高于 NGINX 默认的 client_max_body_size(1 MiB),因此大多数部署不受影响。如果你确实需要在使用这些插件的 route 上处理更大的请求体(并已相应调大 client_max_body_size),请将 max_req_body_size 调整到匹配的值。
在开发者门户中,凭据的 key-auth key 和 basic-auth password 现在仅在创建或重新生成凭据时返回一次,不再包含在凭据的读取或列表响应中,这与 OAuth client_secret 的现有行为一致。basic-auth 的用户名仍然可见。
请在密钥首次展示时复制并妥善保存。如果密钥丢失,请重新生成凭据以获得新值。任何从凭据读取或列表接口回读这些密钥的集成都需要改为在创建时捕获它们。
独立的 apisix_llm_ttft 指标已被 apisix_llm_latency{type="ttft"} 取代,与 apisix_http_latency 的结构保持一致。如果你的 Prometheus 查询或 Grafana 看板引用了 apisix_llm_ttft,请改为选择 apisix_llm_latency 上 type 标签的 ttft 值。