- backend/: 13 Maven modules (cw-elevator-application, cloudwalk-cloud, intelligent-cwoscomponent, ninca-crk, etc.) - frontend/: 4 Vue projects (elevator-front, cwos-portal, alarm-front, front_acs) + decompiled + scripts - scripts/: build, test-env, tools (Docker Compose, service templates, API parity) - docs/: AGENTS.md, superpowers specs, architecture docs - .gitignore: standard Java/Maven exclusions Moved from legacy maven-*/ root layout to backend/ organized structure.
8.9 KiB
电梯应用「服务实例缺失」排查结论(2026-04-30)
本文档落实排查计划:锁定运行形态、Ribbon ServerList 行为、Consul 健康实例、最小风险修复分支。
1. 运行版本与配置目录
1.1 仓库内 Maven 验证日志(maven-cw-elevator-application/logs/elevator-app.log)
- Tomcat 端口:
18081(与deploy/README.md中 v2-maven 并行对拍端口一致)。 - Profile:
access-control。 - Kafka:
192.168.3.12:9092(本地验证栈)。 - 结论:该日志对应 本机/验证环境 启动的 Maven 构建版 V2 JAR(非生产星中心 V1 目录),用于 API 对拍或本地联调。
1.2 生产侧采集证据(artifacts/elevator-evidence-20260430-000038/)
- JAR:
星中心/cw-elevator-application-V1.0.0.20211103/cw-elevator-application-V1.0.0.20211103.jar(V1 fat-jar)。 start.sh:java -jar cw-elevator-application-V1.0.0.20211103.jar,未附加--spring.config.location。bootstrap.properties(现场快照):spring.cloud.consul.discovery.enabled=false,Consul host 为 主机名(与发布包内 IP 形式不同)。application.properties(现场快照):含feign.*.name、业务参数、ninca-crk-std.ip,未见ninca-crk-std.ribbon.listOfServers(与deploy/v1-legacy/application.properties中显式 Ribbon 静态段不一致时,行为依赖 JAR 版本与配置合并)。
结论:排查时需区分 (A) 本仓库 Maven V2 + deploy/v2-maven 与 (B) 星中心 V1 fat-jar + 同目录配置,二者 Consul/Ribbon 生效路径不同;勿混用日志归因。
2. ninca-crk-std 的 Ribbon ServerList 是否稳定
2.1 日志统计(同一 elevator-app.log)
| 模式 | 日志特征 | 次数(近似) |
|---|---|---|
| Consul 发现 | ServerList:ConsulServerList{serviceId='ninca-crk-std' |
19 |
| 配置型列表 | 后续行出现 ServerList:com.netflix.loadbalancer.ConfigurationBasedServerList@…,且实例列表含静态地址(如 10.128.161.95:16106) |
多条(ConfigurationBasedServerList@ 在全日志约 66 处,含换行续行;并非全部为同一客户端,但 ninca-crk-std 存在两种初始化交替) |
2.2 代码与配置依据
NincaCrkStdRibbonConfiguration强制使用ConfigurationBasedServerList,注释说明用于避免 Consul 返回空列表时覆盖静态listOfServers。- 事实:日志仍出现
ConsulServerList,说明在部分生命周期/上下文刷新路径下,负载均衡仍会按 Consul 解析;不稳定,与「仅静态 Ribbon」预期不完全一致。
2.3 次要现象(同一日志)
- 即使走
ConfigurationBasedServerList且实例为10.128.161.95:16106,仍可能出现Connection refused(对端未监听或网络不通),与「无实例」不同,需区分。
3. Consul 侧是否存在依赖服务实例(验证环境实测)
对 http://192.168.3.12:8500(仓库 deploy 文档中的本地 Consul)执行:
GET /v1/health/service/<service>?passing=true
| 服务名 | 结果 |
|---|---|
cwos-portal |
[] |
ninca-common |
[] |
ninca-common-component-organization |
[] |
ninca-crk-std |
[] |
elevator-app |
有 passing 实例(摘录响应中含 elevator-app 注册信息) |
结论:当前验证用 Consul 上 四个上游均无健康实例。若应用侧 spring.cloud.consul.discovery.enabled=true(早期发布包曾在 bootstrap 中如此配置;当前基线见 deploy/v2-maven/bootstrap.properties),Ribbon 走 ConsulServerList 时会出现 Load balancer does not have available server,这与实测一致。
生产环境请在 目标 Consul 地址上重复上述 HTTP 检查(scripts/collect_elevator_runtime_evidence.sh 已内置相同请求)。
4. 最小风险修复分支(二选一)
分支 A:禁用 Consul 客户端发现 + 静态 Ribbon(与 deploy/v1-legacy、较新发布包中对齐)
- 设置
spring.cloud.consul.discovery.enabled=false(仍可保留consul.enabled=true用于配置中心等其他用途,以现场为准)。 - 在
application.properties(与 JAR 同目录或 Consul KV,以实际生效源为准)为各 Feign 客户端补充*.ribbon.NIWSServerListClassName=com.netflix.loadbalancer.ConfigurationBasedServerList与*.ribbon.listOfServers=host:port(至少覆盖:cwos-portal、ninca-common、ninca-common-component-organization、ninca-crk-std)。 ninca-crk-std:与deploy/v1-legacy/application.properties一致,配置ninca-crk-std.ribbon.*与ninca-crk-std.ip;Maven V2 已含NincaCrkStdRibbonConfiguration,仍需保证 静态列表属性在运行期可见。- 配置来源探针 默认已运行(
ConfigSourceProbeRunner);在*-probe.log核对*.ribbon.listOfServers的最终来源(无需再设elevator.config.probe.enabled)。
分支 B:启用 Consul 服务发现
- 保持
spring.cloud.consul.discovery.enabled=true。 - 在 同一 Consul 上确保四个服务 注册成功且健康检查 passing;服务名须与
feign.*.name一致(如cwos-portal、ninca-common等)。 - 不要求静态
listOfServers;若仍报错,用 Consul UI/API 核对实例与健康检查脚本。
版本选择提示
- 较早的发布包(如 v2.0.1~v2.0.3):
bootstrap中曾discovery.enabled=true,在无上游注册的环境下更易触发本问题。 - v2.0.4 及以后发布包:
discovery.enabled=false,与「静态 Ribbon」分支一致。
deploy/v2-maven/run.sh 注意
当前 run.sh 仅 java -jar,不注入 file:./application.properties。若未通过 Consul KV 提供 Ribbon 键,则依赖 JAR 内默认配置 —— 本地「仅 Consul、无上游」时仍会失败。验证/对拍时请确保 外置 application.properties 与 JAR 同目录 或 显式 --spring.config.location=...(以团队约定为准)。
5. 建议的只读复核命令(现场)
- 进程与 JAR:
ps -ef | grep cw-elevator-application;确认 工作目录与 JAR 文件名(V1 vs V2)。 - Consul:
curl -s "http://<consul>:8500/v1/health/service/<feign服务名>?passing=true"。 - 日志关键字:
ConsulServerList、ConfigurationBasedServerList、Load balancer does not have available server。
6. 一次性评估:应用内探针与对照方式
以下均在 cn.cloudwalk.elevator.debug 包内输出(WARN 用于异常路径),并 双写 主日志与 *-probe.log(见 logs/logback.xml);默认始终启用,调度见源码 ElevatorProbeConstants(不再使用 elevator.*.probe.enabled)。Spring Cloud Consul、Netflix loadbalancer、Discovery 相关 logger 在 logback.xml 中按 DEBUG 双写到 *-probe.log(与 cn.cloudwalk.elevator.debug 一致)。
| 探针 | 作用 | 与其他探针对照 |
|---|---|---|
ConfigSourceProbeRunner |
启动期打印 Consul/Feign/Ribbon 关键键的 value 及 PropertySource 命中链 | 确认 discovery.enabled、*.ribbon.listOfServers 是否被 KV/本地覆盖 |
RibbonLoadBalancerProbeRunner |
延迟后打印各 Ribbon 客户端 实例级 host/port 与 serverCount |
Consul passing=0 且此处也为 0:多为静态配置未生效或未调用;Consul>0 此处仍 0:重点查 NIWSServerListClassName / 懒加载 |
ConsulUpstreamHealthProbeRunner |
延迟 HTTP:本服务与上游 /v1/health/service/... 逐实例(endpoint、checks 摘要)、/v1/agent/self |
与上一行 交叉验证:区分「注册侧无实例」与「应用侧 Ribbon 未吃到地址」 |
启动时会打一行 ELEVATOR DIAGNOSTIC PROBES always on 汇总。进程外仍建议配合 scripts/collect_elevator_runtime_evidence.sh 做完整证据包。
一次性阅读顺序:*-probe.log 中先 CONFIG SOURCE →(延迟后)CONSUL → RIBBON,再对照主日志中的业务异常时间线。
文档维护:若发行包 bootstrap 或 run.sh 再变更,请同步更新第 4 节与「版本选择提示」。