Aller au contenu
login
arrow_backRetour aux issues
apache/dubbo-go #3303

[BUG] Polaris uid-only route rule 未命中时会打空 invoker 并触发 nil pointer panic

ecoDébutant verifiedApache help wanted good first issue ☢️ Bug 3.3.2

descriptionDescription

### ✅ 验证清单 - [x] 🔍 我已经搜索过 [现有 Issues](https://github.com/apache/dubbo-go/issues),确信这不是重复问题 ### 🚀 Go 版本 go1.26.1 darwin/arm64 ### 📦 Dubbo-go 版本 dubbo.apache.org/dubbo-go/v3@v3.3.2-20260419 ### 🖥️ 服务端配置 Dubbo-go v3.3.2-20260419 使用 dubbo-go-samples 的 router/polaris 场景,启动 3 组 provider: - Dev provider - Pre provider - Prod provider 三组 provider 注册到 Polaris,用于验证基于 uid 的路由规则。 ### 💻 客户端配置 Dubbo-go v3.3.2-20260419 使用 dubbo-go-samples 的 router/polaris consumer。 Consumer 通过 Polaris 获取 provider,并根据请求中的 uid / label 触发路由规则。 ### 🌐 协议配置 Triple ### 📋 注册中心配置 Polaris standalone / local test instance 测试场景: - 同一组 Dev / Pre / Prod provider 注册到 Polaris - 配置基于 uid 的 route rule - 对比两种规则配置: 1. 只有 uid 条件 rule,没有 discovery fallback 2. uid 条件 rule + discovery fallback ### 💾 操作系统 🍎 macOS ### 📝 Bug 描述 使用 `dubbo.apache.org/dubbo-go/v3@v3.3.2-20260419` 验证 `dubbo-go-samples/router/polaris` 时,发现如果 Polaris 只配置基于请求 label / uid 的 route rule,而没有 discovery fallback 规则,consumer 在目录初始化或路由规则未命中阶段会出现 `RouteRuleNotMatch`,随后可能触发 nil invoker / nil pointer panic。 补充 discovery fallback 后,同一组 provider 和同一组 uid 路由语义可以稳定通过。因此问题重点不是 RPC 本身不通,而是 Polaris route rule 未命中 / discovery 阶段 label 不完整时,core 路由链路缺少防御。 影响范围: - Polaris router - `router/polaris` sample - 基于 invocation label / uid 的路由规则 - route rule 未命中或 discovery 阶段无法匹配 rule 的场景 ### 🔄 重现步骤 1. 启动 Polaris standalone / local test instance。 2. 启动 `dubbo-go-samples/router/polaris` 的三组 provider: - Dev provider - Pre provider - Prod provider 3. 在 Polaris 中只配置基于 uid 条件的 route rule,不配置 discovery fallback。 示例语义: - `uid=user-2` -> Dev - `uid=user-1` -> Pre - empty uid -> Prod 4. 启动 consumer,分别执行三组调用: - empty uid - `uid=user-1` - `uid=user-2` 5. 观察 consumer 启动、discovery 阶段 invoker list、调用结果和进程日志。 6. 再补充 discovery fallback 规则,重复同样三组调用。 7. 对比无 discovery fallback 和有 discovery fallback 的结果。 ### ✅ 预期行为 1. Polaris route rule 未命中时不应触发 nil pointer panic。 2. 如果 route rule 在 discovery 阶段不能使用 invocation label,框架应安全 fallback,或明确区分 discovery 路由与调用级路由。 3. 即使规则未命中,也应返回清晰错误,例如 route rule not match / no provider available,而不是 nil invoker panic。 4. 配置 discovery fallback 后,三组 uid 应稳定命中预期 provider: - empty uid -> Prod - `user-1` -> Pre - `user-2` -> Dev 5. `router/polaris` README 应提供完整 route rule 初始化步骤,并说明 discovery fallback 是否为必要配置。 ### ❌ 实际行为 没有 discovery fallback 时,consumer 可能出现: RouteRuleNotMatch panic: runtime error: invalid memory address or nil pointer dereference 也就是 route rule 未命中后,invoker 可能被打空,后续调用链路没有足够 nil 防御。 补充 discovery fallback 后,同一组 provider 和 uid 语义可以稳定通过: empty_prod_count=5 user1_pre_count=5 user2_dev_count=5 PASS 这说明 Dev / Pre / Prod provider 本身可以正常注册和调用,问题集中在 Polaris route rule 未命中 / discovery fallback 缺失时的路由防御逻辑。 ### 💡 可能的解决方案 建议从两个方向处理: 1. dubbo-go core 防御: - 在 Polaris router 中处理 route rule 未命中场景; - discovery 阶段如果 invocation label 不完整,不应直接把 invoker list 打空到 nil; - 后续调用链路需要避免 nil invoker panic; - 对 route rule not match 返回清晰错误或走明确 fallback。 2. 增加集成测试: - uid-only rule,无 discovery fallback; - uid rule + discovery fallback; - route rule 未命中; - empty uid / user-1 / user-2 三组断言; - 验证不会 panic,且 fallback 语义稳定。 3. 更新 `router/polaris` sample README: - 增加 route rule 初始化脚本或完整控制台配置步骤; - 明确 discovery fallback 是否必须配置; - 给出 Dev / Pre / Prod 三组 uid 的预期输出。
codeOuvre sur GitHub