Apache APISIX Consumer 对象详解:基于身份识别的细粒度流量治理
2026/9/15 20:59:03 网站建设 项目流程

Apache APISIX Consumer 对象详解:基于身份识别的细粒度流量治理

【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix

Apache APISIX 的 Consumer(消费者)对象用于标识调用 API 的请求方身份,从而在认证通过后为不同用户执行差异化的插件与上游配置。本文基于官方术语文档,结合源码实现讲解 Consumer 的核心概念、配置字段、识别流程与实战示例,读完即可在真实网关场景中落地基于用户的限流、黑白名单等治理策略。

为什么需要 Consumer

对于 API 网关而言,通常可以通过请求的域名、客户端 IP 等手段区分请求来源,APISIX 可以据此借助 Plugin 过滤请求,并转发到指定的 Upstream。

但这在有些场景下并不够用。网关更关心的是:到底是谁在调用这个 API。只有知道了调用方是谁,才能为不同的调用方配置不同的规则,例如"同一个接口,A 客户限流 100 次/分钟,B 客户限流 1000 次/分钟"。

上图直观表达了这一诉求:多个请求方访问 APISIX 时,网关需要先回答"who are you?"(你是谁),再决定后续如何对待这个请求。这正是 APISIX 中Consumer构造要解决的问题。

在 APISIX 的配置优先级中,Consumer 拥有最高优先级:Consumer > Route > Plugin Config > Service。也就是说,当同一个路由同时被多个消费者命中时,挂在 Consumer 上的插件配置会优先生效。

Consumer 的配置字段

Consumer 对象的核心字段定义如下(与 schema_def.lua 中的 consumer schema 一一对应):

字段必填描述
usernameConsumer 的名称,也是其唯一标识,格式要求匹配^[a-zA-Z0-9_]+$(字母、数字、下划线)
pluginsConsumer 级别的插件配置,具体插件配置方式参考 Plugin
group_id关联的 Consumer Group 的 id(用于批量管理插件配置)
labels标签,用于资源分类与检索
desc描述信息

从源码看,schema_def.lua 的_M.consumer规定username为必填(required = {"username"}),且不允许出现未定义的额外字段(additionalProperties = false)。

值得注意的是,username同时就是 Consumer 的id。在 apisix/consumer.lua 的 filter 函数 中有明确处理:

-- We expect the id is the same as username. Fix up it here if it isn't. consumer.value.id = consumer.value.username

即无论请求中如何填写 id,最终都会以username作为 Consumer 的唯一标识,后续认证插件拿到的consumer_name也来自这里(见 plugin_consumer 中的注释)。

Consumer 的识别流程

APISIX 中识别一个 Consumer 的过程分为三步:

  1. 认证(Authentication):由认证类插件完成,例如 key-auth、JWT;
  2. 获取 Consumer id:认证通过后得到 Consumer 的id(即username),作为该 Consumer 的唯一标识;
  3. 执行绑定配置:执行挂载在该 Consumer 上的 Plugin、Upstream 等配置。

底层实现上,apisix/consumer.lua 的plugin_consumer()会在初始化时遍历 etcd 中/consumers下的所有 Consumer,筛选出其中配置了type == "auth"插件的项,将插件配置提取为auth_conf并缓存。认证插件(如 key-auth)通过_M.consumers_kv(plugin_name, consumer_conf, key_attr)(consumer.lua L116-L121)以"认证键"为索引建立 KV 缓存,实现 O(1) 的消费者查找。

认证通过后,认证插件调用_M.attach_consumer(ctx, consumer, conf)(consumer.lua L84-L89)将 Consumer 挂到请求上下文上:

function _M.attach_consumer(ctx, consumer, conf) ctx.consumer = consumer ctx.consumer_name = consumer.consumer_name ctx.consumer_group_id = consumer.group_id ctx.consumer_ver = conf.conf_version end

此后,consumer-restrictionlimit-count等插件即可通过ctx.consumer_name感知到当前请求的消费者身份,从而执行差异化策略。

Consumer 最适合的场景是:多个不同的消费者访问同一个 API,需要根据消费者身份执行不同的插件与上游配置。这类能力必须与用户认证体系配合使用。

APISIX 中可与 Consumer 配合的认证插件包括:basic-authhmac-authjwt-authkey-authldap-authwolf-rbac

更深入的概念可以结合 key-auth 认证插件文档理解;Consumer 对象的 Admin API 资源说明参见 Admin API Consumer。

实战示例:为特定 Consumer 启用插件

下面通过完整示例演示如何为指定 Consumer 启用插件。示例将使用key-auth做身份认证,并用limit-count对该消费者做限流。

首先,从config.yaml中取出管理密钥并保存为环境变量(Admin API 默认监听127.0.0.1:9180,数据面默认监听127.0.0.1:9080):

admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')

1. 创建 Consumer

创建一个名为jack的 Consumer,指定认证插件key-auth,并启用限流插件limit-count(60 秒窗口内最多 2 次请求,超出返回 503):

curl http://127.0.0.1:9180/apisix/admin/consumers \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "username": "jack", "plugins": { "key-auth": { "key": "auth-one" }, "limit-count": { "count": 2, "time_window": 60, "rejected_code": 503, "key": "remote_addr" } } }'

说明:Admin API 对 Consumer 只支持PUTDELETE,不支持POSTPATCH(见 apisix/admin/consumers.lua 的 unsupported_methods)。PUT时 URI 中的 username 必须与请求体中的username一致,否则会返回wrong username错误(见 check_conf)。

同时,Admin API 强制校验:Consumer 的plugins必须包含至少一个认证类(type 为 auth)插件,否则返回require one auth plugin(consumers.lua L40-L50)。这从管理面保证了"Consumer 必须能被认证识别"这一设计初衷。

2. 创建路由并开启插件

创建路由/hello,在路由上启用key-auth(网关先完成认证),并将请求转发到上游127.0.0.1:1980

curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "plugins": { "key-auth": {} }, "upstream": { "nodes": { "127.0.0.1:1980": 1 }, "type": "roundrobin" }, "uri": "/hello" }'

3. 验证限流效果

发送测试请求,携带jack的认证密钥auth-one

curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
  • 前两次请求正常返回,未达到限流阈值;
  • 第三次请求返回503,请求被限流拦截:
HTTP/1.1 503 Service Temporarily Unavailable ...

这正是 Consumer 级插件配置的典型效果:限流规则只作用于jack这一个消费者,不影响其他消费者访问同一路由。

进阶:用 consumer-restriction 做访问控制

除了限流,还可以用 consumer-restriction 插件按消费者身份做访问控制。下面把jack加入黑名单,禁止其访问该 API。

1. 在路由上配置黑名单

curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "plugins": { "key-auth": {}, "consumer-restriction": { "blacklist": [ "jack" ] } }, "upstream": { "nodes": { "127.0.0.1:1980": 1 }, "type": "roundrobin" }, "uri": "/hello" }'

2. 验证拦截效果

再次使用jack的密钥发起请求:

curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I

反复测试均返回403jack已被禁止访问该 API:

HTTP/1.1 403 ...

补充说明与源码路径

  • 配置优先级:Consumer > Route > Plugin Config > Service,意味着消费者维度的插件配置会覆盖路由维度的同名配置,这也是实现"同一接口不同客户不同策略"的基础。
  • Consumer 与 Consumer Group:当多个 Consumer 需要共享同一组插件配置时,可以通过group_id关联 Consumer Group 批量管理,避免逐个重复配置。
  • 数据加载:Consumer 配置在init_worker阶段通过core.config.new("/consumers", cfg)(consumer.lua L139-L155)从 etcd(或独立部署下的配置文件)加载,并在 etcd 配置变更时自动热更新,无需重启网关。
  • 相关资源
    • Consumer 核心实现:apisix/consumer.lua
    • Consumer Admin API 实现:apisix/admin/consumers.lua
    • Consumer Schema 定义:apisix/schema_def.lua
    • 认证插件参考:key-auth、jwt-auth
    • 相关测试:t/admin/consumers.t、t/node/consumer-plugin.t

总而言之,Consumer 是 APISIX 将"请求"与"人"关联起来的关键抽象。配合认证插件,它让网关能够在同一路由上针对不同调用方执行限流、黑白名单、灰度等精细化策略,是构建多租户、多客户 API 治理体系的基石能力。

【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询