Files
starRiverProperty/docs/testing/elevator-service-instance-missing-investigation.md
T
hpd840321 7b2bd307f1 Initial commit: reorganized source tree
- 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.
2026-05-09 09:56:45 +08:00

115 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 电梯应用「服务实例缺失」排查结论(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`](../../maven-cw-elevator-application/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`](../../maven-cw-elevator-application/cw-elevator-application-starter/src/main/java/cn/cloudwalk/ribbon/NincaCrkStdRibbonConfiguration.java) 强制使用 `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`](../../maven-cw-elevator-application/deploy/v2-maven/bootstrap.properties)),Ribbon 走 **`ConsulServerList`** 时会出现 **`Load balancer does not have available server`**,这与实测一致。
生产环境请在 **目标 Consul 地址**上重复上述 HTTP 检查([`scripts/collect_elevator_runtime_evidence.sh`](../../scripts/collect_elevator_runtime_evidence.sh) 已内置相同请求)。
---
## 4. 最小风险修复分支(二选一)
### 分支 A:禁用 Consul 客户端发现 + 静态 Ribbon(与 `deploy/v1-legacy`、较新发布包中对齐)
1. 设置 **`spring.cloud.consul.discovery.enabled=false`**(仍可保留 `consul.enabled=true` 用于配置中心等其他用途,以现场为准)。
2.**`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`)。
3. **`ninca-crk-std`**:与 [`deploy/v1-legacy/application.properties`](../../maven-cw-elevator-application/deploy/v1-legacy/application.properties) 一致,配置 `ninca-crk-std.ribbon.*``ninca-crk-std.ip`Maven V2 已含 `NincaCrkStdRibbonConfiguration`,仍需保证 **静态列表属性**在运行期可见。
4. 配置来源探针 **默认已运行**[`ConfigSourceProbeRunner`](../../maven-cw-elevator-application/cw-elevator-application-starter/src/main/java/cn/cloudwalk/elevator/debug/ConfigSourceProbeRunner.java));在 `*-probe.log` 核对 `*.ribbon.listOfServers` 的最终来源(无需再设 `elevator.config.probe.enabled`)。
### 分支 B:启用 Consul 服务发现
1. 保持 **`spring.cloud.consul.discovery.enabled=true`**。
2.**同一 Consul** 上确保四个服务 **注册成功且健康检查 passing**;服务名须与 `feign.*.name` 一致(如 `cwos-portal``ninca-common` 等)。
3. **不要求**静态 `listOfServers`;若仍报错,用 Consul UI/API 核对实例与健康检查脚本。
### 版本选择提示
- **较早的发布包(如 v2.0.1v2.0.3**`bootstrap` 中曾 **`discovery.enabled=true`**,在无上游注册的环境下更易触发本问题。
- **v2.0.4 及以后发布包****`discovery.enabled=false`**,与「静态 Ribbon」分支一致。
### `deploy/v2-maven/run.sh` 注意
当前 [`run.sh`](../../maven-cw-elevator-application/deploy/v2-maven/run.sh) 仅 **`java -jar`**,不注入 `file:./application.properties`。若未通过 Consul KV 提供 Ribbon 键,则依赖 JAR 内默认配置 —— 本地「仅 Consul、无上游」时仍会失败。验证/对拍时请确保 **外置 `application.properties` 与 JAR 同目录****显式 `--spring.config.location=...`**(以团队约定为准)。
---
## 5. 建议的只读复核命令(现场)
1. **进程与 JAR**`ps -ef | grep cw-elevator-application`;确认 **工作目录**与 **JAR 文件名**V1 vs V2)。
2. **Consul**`curl -s "http://<consul>:8500/v1/health/service/<feign服务名>?passing=true"`
3. **日志关键字**`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`](../../scripts/collect_elevator_runtime_evidence.sh) 做完整证据包。
**一次性阅读顺序**`*-probe.log` 中先 **CONFIG SOURCE** →(延迟后)**CONSUL** → **RIBBON**,再对照主日志中的业务异常时间线。
---
**文档维护**:若发行包 `bootstrap``run.sh` 再变更,请同步更新第 4 节与「版本选择提示」。