ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Apache APISIX 变量(Variable)详解:内置变量体系与自定义变量注册实战

2026/9/15 22:15:14 拓冰建站 浏览量
Apache APISIX 变量(Variable)详解:内置变量体系与自定义变量注册实战 Apache APISIX 变量Variable详解内置变量体系与自定义变量注册实战【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisixApache APISIX 在继承 NGINX 变量 的基础上由核心core模块与各协议插件如 MQTT、Redis 等扩展出了一套网关专用变量体系。本指南以官方文档 apisix-variable.md 为骨架逐一剖析每个变量的语义、来源与典型使用场景并结合 apisix/core/ctx.lua 等源码解释变量是如何被解析、缓存与注册的帮助你在日志格式化、限流键、路由匹配和自定义插件中正确选用变量。描述APISIX 除了支持 NGINX 变量外自身也提供了一些变量。这些变量覆盖了请求处理生命周期中的关键上下文上游节点信息、消费者与路由/服务标识、GraphQL 元数据、MQTT 客户端信息乃至日志阶段才能取到的响应体resp_body与 xRPC 协议下的rpc_time。它们由不同来源注入——core表示由 apisix/core/ctx.lua 这一核心上下文模块维护其余来源如mqtt-proxy、Redis、xRPC则来自对应协议插件。变量列表下表完整列出 APISIX 自身提供的变量即官方文档 apisix-variable.md 的原始清单变量名称来源描述示例balancer_ipcore上游服务器的 IP 地址。192.168.1.2balancer_portcore上游服务器的端口。80consumer_namecore消费者的名称。consumer_group_idcore消费者所在的组的 ID。graphql_namecoreGraphQL 的 operation name。HeroComparisongraphql_operationcoreGraphQL 的操作类型。mutationgraphql_root_fieldscoreGraphQL 最高级别的字段。[hero]mqtt_client_idmqtt-proxyMQTT 协议中的客户端 ID。route_idcoreAPISIX 路由的 ID。route_namecoreAPISIX 路由的名称。service_idcoreAPISIX 服务的 ID。service_namecoreAPISIX 服务的名称。redis_cmd_lineRedisRedis 命令的内容。resp_bodycore在 logger 插件中如果部分插件支持记录响应的 body 信息比如配置include_resp_body: true那可以在 log format 中使用该变量。rpc_timexRPC在 RPC 请求级别所花费的时间。core 来源变量来自请求上下文在 apisix/core/ctx.lua 中apisix_var_names表集中声明了这些核心变量并按其是否可直接读取分为两类直读型值为truebalancer_ip、balancer_port、consumer_group_id、consumer_name、route_id、route_name、service_id、service_name它们直接映射到ctx上的对应字段函数型resp_body通过一个取数函数返回ctx.resp_body or 注释明确说明它“只用于 logger 且要求 logger 有特殊配置”即下文要讲的include_resp_body。balancer_ip 与 balancer_port这两个变量由负载均衡器在选路阶段写入。在 apisix/balancer.lua 中普通上游节点选择完成后会执行ctx.balancer_ip node.host ctx.balancer_port node.port而当上游节点是通过 DNS 动态解析res为解析结果时apisix/balancer.lua 同样会写入这两个字段。从源码结构看这两个变量在健康检查上报apisix/init.lua、datadog 插件 的标签tag拼接以及 prometheus 插件 的upstream维度指标中都被直接使用因此它们也是监控与日志场景中定位“请求最终打到了哪台机器”的关键依据。consumer_name 与 consumer_group_id这两个变量在 apisix/consumer.lua 中于消费者完成认证后写入请求上下文ctx.consumer_name consumer.consumer_name ctx.consumer_group_id consumer.group_id其中consumer.consumer_name默认取消费者的id见 apisix/consumer.lua。实际使用中consumer-restriction 插件 把consumer_name、consumer_group_id列为type的可选枚举值并直接以ctx.consumer_name/ctx.consumer_group_id作为校验取值chash 负载均衡 也可以把chash_key设为ctx.consumer_name实现“同一消费者固定打到同一上游节点”的会话保持效果。route_id / route_name / service_id / service_name这四个变量分别对应当前请求所匹配到的路由与服务实体的 ID 与名称可用于日志区分、监控打点与权限隔离。例如 consumer-restriction 插件 的type枚举中同样包含service_id与route_id配合这些变量即可实现“仅允许特定消费者访问特定路由/服务”的精细化控制。graphql_name / graphql_operation / graphql_root_fieldsGraphQL 系列变量由 apisix/core/ctx.lua 中的parse_graphql流程解析得到解析器通过fetch_graphql_data分别处理 HTTP GET从 URI 参数query读取与 HTTP POST从请求体读取支持application/json与明文两种形态见 apisix/core/ctx.lua解析出的 GraphQL 文档会被缓存到ctx._graphql结构为{ name, operation, root_fields }见 apisix/core/ctx.lua其中name对应操作名、operation对应操作类型query/mutation/subscription、root_fields对应顶层字段数组变量名以graphql_为前缀取值时先剥离前缀再读取对应字段见 apisix/core/ctx.lua。需要说明解析失败时ctx._graphql会被置为空表见 apisix/core/ctx.lua此时对应变量取到的是空值当一次请求携带多个 GraphQL operation 时仅处理第一个并记录 warning见 apisix/core/ctx.lua。默认请求体大小上限为 1MiBGRAPHQL_DEFAULT_MAX_SIZE可通过config.yaml中的graphql.max_size调整见 apisix/core/ctx.lua。这些变量适合与 degraphql 插件 等 GraphQL 场景配合用于路由匹配或限流细分。resp_body响应体变量resp_body是一个“延迟取数”型变量只有响应体被保留后才有值。其实现为return ctx.resp_body or 见 apisix/core/ctx.lua。要让它生效必须满足使用的 logger 类插件支持include_resp_body配置例如 http-logger、file-logger、clickhouse-logger、elasticsearch-logger 等在该插件的路由/服务配置中设置include_resp_body: true部分插件还支持include_resp_body_expr表达式按条件记录在插件的log_format中引用$resp_body。底层上响应体会由 apisix/core/response.lua 的hold_body_chunk机制按需暂存并受max_resp_body_bytes上限约束避免大响应体拖垮内存。插件来源变量MQTT、Redis 与 xRPCmqtt_client_id来源mqtt-proxy该变量由 stream/mqtt-proxy 插件 注册取数函数直接返回ctx.mqtt_client_id当 MQTT 客户端完成 CONNECT 握手后其client_id被写入上下文apisix/stream/plugins/mqtt-proxy.lua。它主要用在TCP/Stream 代理场景例如结合 schema_def.lua 中提到的变量用法按 MQTT 客户端维度做限流或日志区分。redis_cmd_line来源Redis / xRPC该变量由 apisix/stream/xrpc/protocols/redis/init.lua 注册取数函数返回ctx.cmd_line。在 Redis 协议的 xRPC 解析流程中命令内容会被组装到cmd_line上见 apisix/stream/xrpc/protocols/redis/init.lua并随请求上下文流转。它用于在Redis 协议代理xRPC场景中记录/统计客户端发来的完整命令文本。rpc_time来源xRPC该变量由 apisix/stream/xrpc/runner.lua 注册反映单个 RPC 请求级别的耗时。以 Redis 协议为例redis/init.lua 在指标采集时直接使用ctx.var.rpc_time观测命令延迟commands_latency_seconds说明该变量是 xRPC 协议栈做延迟观测与日志输出的通用时间维度。变量的取值与缓存机制从源码实现看这些变量并非简单的“全局变量”而是通过 apisix/core/ctx.lua 中的mt.__index元方法统一接管首次读取某个变量时会计算结果并写入t._cache后续读取直接命中缓存避免重复计算。同时该表还聚合了Nginx 变量如upstream_scheme、upstream_host、upstream_uri、upstream_cache_key等见 apisix/core/ctx.lua用于代理与缓存相关逻辑请求方法/ Cookiemethod、cookie_*等快捷变量见 apisix/core/ctx.luaAPISIX 自身变量即上文表格所列的 core 变量。值得注意的是args、is_args这类变量不会被缓存因为它们在请求生命周期中可能被set_uri_args等操作修改见 apisix/core/ctx.lua这体现了 APISIX 在“缓存性能”与“取值正确性”之间的取舍。使用方式APISIX 变量与 NGINX 变量一样通过$前缀在字符串模板中引用。典型使用场景包括日志格式化在支持log_format的 logger 类插件如 http-logger、kafka-logger、tcp-logger中把$consumer_name、$route_id、$service_name、$balancer_ip、$balancer_port等拼进日志模板限流与键值计算在limit-*limit-count、limit-req、limit-conn插件中把变量用作限流 key例如按$consumer_name或$route_id限流路由与访问控制在路由的vars表达式中使用变量做条件匹配或在 consumer-restriction 等插件中按consumer_name/service_id/route_id做白名单/黑名单。以 http-logger 为例一个引用多个变量的日志格式示意如下plugins: http-logger: uri: http://127.0.0.1:8080/log include_req_body: true include_resp_body: true log_format: consumer: $consumer_name route: $route_id service: $service_id upstream: $balancer_ip:$balancer_port graphql_op: $graphql_operation注册自定义变量除上述变量外APISIX 也允许开发者通过core.ctx.register_var在全局范围内注册自定义变量注册后可像内置变量一样被引用。完整示例见 plugin-develop.md 的“注册自定义变量”一节其底层实现在 apisix/core/ctx.lua 的register_var函数。例如注册一个名为a6_labels_zone的变量来读取路由labels中zone标签的值local core require apisix.core core.ctx.register_var(a6_labels_zone, function(ctx) local route ctx.matched_route and ctx.matched_route.value if route and route.labels then return route.labels.zone end return nil end)此后任何对$a6_labels_zone的读取都会调用上面注册的取数函数。从 apisix/core/ctx.lua 的实现看register_var(name, getter, opts)接收变量名、取数函数与可选的opts配置对于这类自定义变量可以推断其同样会进入变量的取值/缓存统一通道因此注册后即可在路由 vars、插件配置、日志格式等位置直接引用。需要特别留意自定义变量不能用于依赖 Nginx 指令的功能例如access_log_format这类在 Nginx 层面直接展开的模板因为这类场景不会经过 APISIX 的 Lua 取值逻辑。总结APISIX 变量体系由三部分构成NGINX 原生变量、APISIX core 变量路由/服务/消费者/负载均衡/GraphQL/响应体与协议插件扩展变量MQTT、Redis、xRPC。理解每个变量的来源与生效时机是正确使用的前提例如balancer_ip只有在负载均衡完成后才有值、resp_body必须配合 logger 插件的include_resp_body: true才能使用、mqtt_client_id与redis_cmd_line仅在对应协议代理场景生效。当内置变量无法满足需求时通过core.ctx.register_var注册自定义变量是标准扩展途径。【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考