yudaocode/SpringBoot-Labs · error · IllegalStateException
获取不到实例
Error message
获取不到实例
What it means
Same guard as the demo01 consumer, in the labx-22 demo02 variant (Eureka): DemoConsumerApplication fetches DiscoveryClient.getInstances("demo-provider"), takes instances.get(0) only when the list is non-empty, and otherwise throws IllegalStateException("获取不到实例") at line 59. The registry query returned zero instances for the service name 'demo-provider'. In the demo02 lab the provider module is the demo02 provider — the consumer code still hard-codes the logical name 'demo-provider', so a name/config mismatch between the demo02 provider's spring.application.name and this literal is a frequent cause unique to this variant.
Source
Thrown at labx-22/labx-22-scn-eureka-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx22/consumerdemo/DemoConsumerApplication.java:59
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/hello")
public String hello(String name) {
// 获得服务 `demo-provider` 的一个实例
ServiceInstance instance;
if (true) {
// 获取服务 `demo-provider` 对应的实例列表
List<ServiceInstance> instances = discoveryClient.getInstances("demo-provider");
// 选择第一个
instance = instances.size() > 0 ? instances.get(0) : null;
} else {
instance = loadBalancerClient.choose("demo-provider");
}
// 发起调用
if (instance == null) {
throw new IllegalStateException("获取不到实例");
}
String targetUrl = instance.getUri() + "/echo?name=" + name;
String response = restTemplate.getForObject(targetUrl, String.class);
// 返回结果
return "consumer:" + response;
}
}
}
View on GitHub (pinned to 6c12efaed0)
Solutions
- Open the Eureka dashboard and confirm a service named exactly 'demo-provider' (the name passed to getInstances) is UP; fix the provider's spring.application.name if it differs.
- Reorder startup: Eureka server → demo02 provider → wait for UP status → consumer; then retry the request.
- Align eureka.client.serviceUrl.defaultZone between provider and consumer so both talk to the same registry.
- Handle the empty case gracefully (503 + message) or use LoadBalancerClient.choose with a null check when absence is expected.
Example fix
// before
instance = instances.size() > 0 ? instances.get(0) : null;
if (instance == null) {
throw new IllegalStateException("获取不到实例");
}
// after
if (instances.isEmpty()) {
return "service demo-provider unavailable, please retry later";
}
ServiceInstance instance = instances.get(0); Defensive patterns
Strategy: validation
Validate before calling
List<ServiceInstance> instances = discoveryClient.getInstances("demo-provider");
if (instances.isEmpty()) {
return "demo-provider 暂无可用实例,请确认提供者已注册并稍后重试";
}
ServiceInstance instance = instances.get(0); Type guard
Optional<ServiceInstance> firstInstance(DiscoveryClient dc, String service) {
List<ServiceInstance> list = dc.getInstances(service);
return (list == null || list.isEmpty()) ? Optional.empty() : Optional.of(list.get(0));
} Try / catch
try {
return "consumer:" + restTemplate.getForObject(targetUrl, String.class);
} catch (RestClientException e) {
// instance disappeared between discovery and call: refresh and retry once
List<ServiceInstance> retry = discoveryClient.getInstances("demo-provider");
if (retry.isEmpty()) throw new IllegalStateException("获取不到实例");
return "consumer:" + restTemplate.getForObject(retry.get(0).getUri() + "/echo?name=" + name, String.class);
} Prevention
- Verify the exact service name on the Eureka dashboard matches the getInstances literal before wiring consumers.
- Use shared configuration for eureka.client.serviceUrl.defaultZone so provider and consumer cannot diverge.
- Sequence demo startups (registry, provider, consumer) and wait for UP status; add retry/backoff for the registration window.
- Return 503 with guidance on empty discovery instead of letting IllegalStateException surface as a 500.
When it happens
Trigger: Calling the consumer endpoint while getInstances("demo-provider") is empty: provider (demo02) not started, registered under a different spring.application.name, registration still propagating, Eureka server unreachable from either side, or the instance evicted (lease expiry / health-check failure).
Common situations: Provider started but with a name other than 'demo-provider'; consumer pointed at a different Eureka server than the provider (mismatched eureka.client.serviceUrl.defaultZone); consumer started immediately after the provider so the local fetch cache has not refreshed yet; provider crashed after registration and Eureka evicted it; copy-pasting this consumer against a provider from another lab module.
Related errors
AI-assisted analysis of yudaocode/SpringBoot-Labs@6c12efaed0 (2026-08-14).
Data as JSON: /api/errors/8ef9155dc9a92097.
Report an issue: GitHub.