Kong 3.3升级后自定义插件DAO查询返回Nil及ws_id为空问题咨询
Kong 2.2.1升级至3.3后自定义插件缓存/DAO查询异常问题
场景与环境
- 插件:自定义OAuth2插件,依赖Kong cache与DAO查询能力
- 部署:Kubernetes多实例集群部署Kong
- 版本:从Kong 2.2.1升级至3.3
核心代码片段
Cache查询逻辑
local credential_cache_key = kong.db.oauth2_credentials:cache_key(client_id) client, err = kong.cache:get(credential_cache_key, nil, load_oauth2_credential_by_client_id, client_id)
DAO实体查询回调
local function load_oauth2_credential_by_client_id(client_id) local credential, err = kong.db.oauth2_credentials:select_by_client_id(client_id) if err then return nil, err end return credential end
异常现象
- Kong集群首次启动后,插件频繁触发错误:
[error] 1261#0: *4864420 [kong] init.lua:359 [partner-custom-oauth2] /opt/kong/plugins/partner-custom-oauth2/access.lua:1071: attempt to index local 'client' (a nil value)
- 排查发现数据库中
oauth2_credentials实体确实存在,但ws_id字段为空;多次重启Kong集群后,该字段被自动填充,错误随之消失。 - 开启OpenTelemetry日志后确认:DAO查询语句会自动携带
ws_id作为过滤条件,这是导致空ws_id实体无法被查询到的直接原因。
问题分析与原因
1. Kong版本升级后的Workspace机制变化
Kong 3.x对Workspace(工作空间)的关联性做了强制强化:
- Kong 2.2.1中
ws_id为可选字段,旧数据默认不会填充该值;但Kong 3.x中所有实体查询默认会自动带上当前实例所属Workspace的ws_id作为过滤条件,空ws_id的实体无法被匹配到。
2. 启动时序导致的ws_id补全延迟
升级完成后首次启动Kong时,内置的旧数据ws_id补全逻辑可能未完全执行:
- 多实例部署场景下,多个Kong实例同时初始化会触发资源竞争,导致后台补全逻辑执行延迟或中断,使得
oauth2_credentials实体的ws_id仍为空,DAO查询因条件不匹配返回nil。 - 多次重启后,补全逻辑最终执行完成,将空
ws_id的实体自动填充为默认Workspace的ID,此时查询条件匹配,就能正常获取到实体数据。
3. 缓存的放大效应
首次启动时,Kong cache会把“查询不到实体”的nil结果缓存起来,即便后续ws_id被补全,缓存未过期前仍会返回nil;而重启Kong实例会清空本地缓存,此时重新查询就能获取到已补全ws_id的实体。
临时解决方案
- 手动提前补全ws_id:升级前或首次启动前,直接在数据库执行SQL,给所有空
ws_id的oauth2_credentials实体填充默认Workspace的ID(可从workspaces表中查询默认Workspace的ID)。 - 清空全局缓存:若已启动Kong,可通过Admin API调用
DELETE /cache清空全局缓存,避免缓存的nil结果持续生效。 - 单实例先初始化:多实例部署时,先启动单个Kong实例,待其完成数据初始化后再启动其他实例,规避多实例竞争导致的初始化延迟。
内容的提问来源于stack exchange,提问作者Evelyn Chua
相关产品推荐
相关产品推荐

