Files
starRiverProperty/docs/testing/consul-ribbon-no-server-walkthrough.md
反编译工作区 8b15445328 feat: add service config templates and extraction script
Former-commit-id: 1de24b7eb79676d1aba9d799a58c5a753290cf52
2026-05-01 19:38:01 +08:00

9.5 KiB
Raw Permalink Blame History

Consul 可访问且「有清单」仍拿不到 IP/端口 — 走查结果(证据执行)

证据根maven-cw-elevator-application/logs/evidence/
主日志elevator-app.log
配置探针elevator-app-probe.log
Consul 快照(示例)elevator-evidence-20260430-113912/consul-health-ninca-common-component-organization.json

本文对应走查计划的四项核对:客户端名Ribbon 初始化时序ConsulServerList vs ConfigurationBasedbootstrap 多源合并。结论与 elevator-evidence-v1-v2-diff-20260430.md §6–§10、elevator-service-instance-missing-investigation.md 一致并细化到可 grep 的行级证据。

本服务是否注册到 Consul、与探针日志

  • 拉不到上游 IP 常见原因是 Ribbon 客户端名 / listOfServers / 时序(见下文),不等价于本机未注册;但仍应单独核实 本进程 在 Consul 的登记名是否与 spring.application.name 一致、健康是否 passing
  • 诊断探针 默认始终运行(无 elevator.*.probe 开关);Consul HTTP 首次延迟见源码 ElevatorProbeConstantsConsulUpstreamHealthProbeRunner 会请求本服务 /v1/health/service/<spring.application.name>passing=true 与全量各一遍,并 逐实例 DEBUG)、上游同名列表,以及 /v1/agent/self
  • RibbonLoadBalancerProbeRunner 在同一延迟窗口输出各 client 的 ServerList 实现类ILoadBalancerDiscoveryClient.getInstances(本服务 + ElevatorUpstreamServiceNames)明细。
  • logback.xmlorg.springframework.cloud.consulcom.netflix.loadbalancerorg.springframework.cloud.client.discoverycn.cloudwalk.elevator.debug 均按 DEBUG 双写${logging.file}-probe.log(与自建 consulProbe / ribbonProbe / discoveryProbe 及框架行对照)。

1. 报错栈中的 Ribbon client 名 vs Consul 注册名

核对方法:在出错 JVM 日志中搜索 Load balancer does not have available server for client:for client:,将后缀字符串与 Consul UI / /v1/health/service/<name>Service逐字比对(含 ninca-common- 前缀)。

本仓库证据包结论

项目 结论
for client: 在本份 elevator-app.log 仅出现 ninca-crk-std(大量重复),未出现 component-organization
Feign 逻辑名 component-organization feign.component-organization.name=ninca-common-component-organization(探针:file:classpath: 均为该值)
Ribbon 实际客户端名 Client: ninca-common-component-organizationConsulServerList{serviceId='ninca-common-component-organization'}
Consul ninca-common-component-organization 健康快照为 3 个 passing 实例,与日志中三台 :17016 一致

与人对齐时的表述:若微信群截图写 for client: component-organization,而本电梯进程配置将 Feign 解析服务名设为 ninca-common-component-organization,则二者 不是 同一 Ribbon client;对方环境若在 component-organization 名下查实例会得到 0 台,即使 Consul 里注册的是 ninca-common-component-organization。结论:先看报错里的精确 client 字符串,再对 Consul 注册名。


2. DynamicServerListLoadBalancer 初始化与 Servers=[] 时间序

核对方法:对关心的 client 搜索 DynamicServerListLoadBalancer for client <name> initialized,并向上查看同一 client 的 current list of Servers=[...];若在列表仍为空窗口内发生首次 Feign 调用,会抛 no available server

ninca-common-component-organizationConsul 路径)

时间(日志) 事件
11:16:33.087 Client: ninca-common-component-organization,首次 current list of Servers=[]ServerList:null
11:16:33.097 DynamicServerListLoadBalancer for client ninca-common-component-organization initialized,已为 3 台 :17016ConsulServerList{serviceId='ninca-common-component-organization'}

10ms 内由空列表变为三台;若首次 RPC 落在此窗口仍可能失败(计划中的「首轮请求早于填充」风险)。

ninca-crk-stdConfigurationBased 路径)

时间(日志) 事件
11:16:34.109 Client: ninca-crk-stdServers=[]ServerList:null
11:16:34.111 DynamicServerListLoadBalancer for client ninca-crk-std initialized仍为 Servers=[]ServerList:ConfigurationBasedServerList
11:16:34.346 连续 no available server for client: ninca-crk-std

本证据包中 no-server 全部归因于 ninca-crk-std,且发生在 ninca-common-component-organization 已填充三台之后,说明主因不是「Consul 查错 organization 名」,而是 ninca-crk-std 的静态 Ribbon 列表未配置(见下节)。

同一全量日志内 第二次启动(约 11:43)后 ninca-crk-std 可出现非空列表,详见 elevator-evidence-v1-v2-diff-20260430.md §6.2。


3. ConsulServerList 与 ConfigurationBasedServerListninca-crk-stdlistOfServers / ip

客户端 ServerList 实现 列表来源
ninca-common-component-organization ConsulServerList Consul serviceId=ninca-common-component-organization
ninca-crk-std ConfigurationBasedServerList Ribbon 属性(如 ninca-crk-std.ribbon.listOfServers),自动使用 ninca-crk-std.ip

代码侧:NincaCrkStdRibbonConfigurationninca-crk-std 固定注册 ConfigurationBasedServerList

探针(elevator-app-probe.log):

  • ninca-crk-std.ribbon.listOfServers value=null
  • ninca-crk-std.ip=10.0.22.102:16106file: / classpath: 一致)

因此即 Consul 上 ninca-crk-std passing=3Ribbon 仍可能 Servers=[],与 Consul 是否正常无关,除非另行配置 ribbon.listOfServers 或改变 ServerList 策略。部署模板对照:V1 legacy 含显式 ninca-crk-std.ribbon.listOfServers 段;V2 模板以 ninca-crk-std.ip 为主,见 deploy/v1-legacy/application.propertiesdeploy/v2-maven/application.properties


4. file:./bootstrapclasspath:/bootstrap 对 Consul 的合并结果

来源elevator-app-probe.logConfigSourceProbeRunner 行。

Environment 合并结果 file:./bootstrap.properties classpath:/bootstrap.properties
spring.cloud.consul.host 10.0.22.102 10.0.22.102 主机名(与磁盘不一致)
spring.cloud.consul.discovery.enabled true true false

走查要点:以 spring.application.* 合并后的 value= 为准核对「进程连的 Consul」是否与运维在浏览器里看的地址一致;磁盘与 jar 内嵌 bootstrap 并存时,以最终 Environment 为准(本样本下 host 为 10.0.22.102、发现 启用)。证据目录内亦有 bootstrap.properties 快照可与现场比对。


5. 建议的可复现 grep(本地)

# 锁定所有「for client:」后的客户端名(去重)
grep -E 'for client:' maven-cw-elevator-application/logs/evidence/elevator-app.log | sed -n 's/.*for client: \([^ ]*\).*/\1/p' | sort -u

# 各客户端初始化与非空列表
grep 'DynamicServerListLoadBalancer for client' maven-cw-elevator-application/logs/evidence/elevator-app.log

# 区分 Consul 与配置型列表
grep -E 'ConsulServerList|ConfigurationBasedServerList' maven-cw-elevator-application/logs/evidence/elevator-app.log

延伸阅读elevator-v1-v2-init-timing-config-audit.md(初始化顺序与探针)、elevator-evidence-v1-v2-diff-20260430.md §9listOfServers vs ninca-crk-std.ip)。