{"record":{"id":"fba9111d48e295d6","repo":"yudaocode/SpringBoot-Labs","slug":"error-fba911","errorCode":null,"errorMessage":"获取不到实例","messagePattern":"获取不到实例","errorType":"exception","errorClass":"IllegalStateException","httpStatus":500,"severity":"error","filePath":"labx-22/labx-22-scn-eureka-demo01-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx22/consumerdemo/DemoConsumerApplication.java","lineNumber":59,"sourceCode":"        private RestTemplate restTemplate;\n        @Autowired\n        private LoadBalancerClient loadBalancerClient;\n\n        @GetMapping(\"/hello\")\n        public String hello(String name) {\n            // 获得服务 `demo-provider` 的一个实例\n            ServiceInstance instance;\n            if (true) {\n                // 获取服务 `demo-provider` 对应的实例列表\n                List<ServiceInstance> instances = discoveryClient.getInstances(\"demo-provider\");\n                // 选择第一个\n                instance = instances.size() > 0 ? instances.get(0) : null;\n            } else {\n                instance = loadBalancerClient.choose(\"demo-provider\");\n            }\n            // 发起调用\n            if (instance == null) {\n                throw new IllegalStateException(\"获取不到实例\");\n            }\n            String targetUrl = instance.getUri() + \"/echo?name=\" + name;\n            String response = restTemplate.getForObject(targetUrl, String.class);\n            // 返回结果\n            return \"consumer:\" + response;\n        }\n\n    }\n\n}\n","sourceCodeStart":41,"sourceCodeEnd":70,"githubUrl":"https://github.com/yudaocode/SpringBoot-Labs/blob/6c12efaed06d12907a0f40dd2ad1f7020aec8798/labx-22/labx-22-scn-eureka-demo01-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx22/consumerdemo/DemoConsumerApplication.java#L41-L70","documentation":"Runtime guard in the Eureka consumer demo (labx-22 demo01): the code fetches all instances of service 'demo-provider' from the registry via DiscoveryClient.getInstances(\"demo-provider\"), blindly takes the first entry, and throws IllegalStateException(\"获取不到实例\") when the returned list is empty (instance == null). It means the consumer is asking Eureka for a service name that currently has zero registered, UP instances — the discovery lookup itself succeeded, it just found nothing. The `if (true)` branch shows the demo deliberately uses raw DiscoveryClient instead of LoadBalancerClient.choose.","triggerScenarios":"Hitting the consumer's /echo?name=xxx endpoint (the controller calls this code at DemoConsumerApplication.java:59) while discoveryClient.getInstances(\"demo-provider\") returns an empty list. That happens when: the provider application is not running, the provider registered under a different spring.application.name, the provider's Eureka registration has not completed or its lease expired, or the consumer itself never connected to the Eureka server so its DiscoveryClient has an empty local cache.","commonSituations":"Starting the consumer before the provider (registration takes a few seconds plus the client cache refresh interval, default 30s); provider's spring.application.name is not exactly 'demo-provider' (e.g. left as default or typo'd); Eureka server not started or wrong eureka.client.serviceUrl.defaultZone in the consumer, so the fetch returns nothing; provider registered but its instance was evicted (self-preservation/lease expiry); running demo02/demo03 variants whose provider registers a different name.","solutions":["Ensure the demo-provider application for this lab is running and registered: open the Eureka server dashboard (default http://localhost:8761) and confirm an instance named exactly 'demo-provider' with status UP.","Start the provider first, wait ~10-30s for registration plus the consumer's registry cache refresh, then retry the /echo call.","Compare spring.application.name in the provider's application.yaml with the literal \"demo-provider\" used in getInstances — they must match exactly (case-sensitive).","Verify the consumer's eureka.client.serviceUrl.defaultZone points at the same Eureka server the provider registered with.","If the service may legitimately be absent, handle the empty list explicitly (friendly message / HTTP 503) instead of IllegalStateException, or switch to the loadBalancerClient.choose branch with a null check."],"exampleFix":"// before\nList<ServiceInstance> instances = discoveryClient.getInstances(\"demo-provider\");\ninstance = instances.size() > 0 ? instances.get(0) : null;\nif (instance == null) {\n    throw new IllegalStateException(\"获取不到实例\");\n}\n\n// after — explicit empty handling with actionable message\nList<ServiceInstance> instances = discoveryClient.getInstances(\"demo-provider\");\nif (instances == null || instances.isEmpty()) {\n    throw new IllegalStateException(\n        \"获取不到实例: service 'demo-provider' has no registered instances; \" +\n        \"check provider is running and registered in Eureka\");\n}\nServiceInstance instance = instances.get(0);","handlingStrategy":"validation","validationCode":"List<ServiceInstance> instances = discoveryClient.getInstances(\"demo-provider\");\nif (instances == null || instances.isEmpty()) {\n    // do not proceed; surface a 503 with an actionable hint instead of IllegalStateException\n    throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE,\n        \"demo-provider unavailable: no instances registered in Eureka\");\n}\nServiceInstance instance = instances.get(0);","typeGuard":"boolean hasInstance(DiscoveryClient dc, String service) {\n    List<ServiceInstance> list = dc.getInstances(service);\n    return list != null && !list.isEmpty();\n}","tryCatchPattern":"try {\n    String response = restTemplate.getForObject(targetUrl, String.class);\n} catch (IllegalStateException e) {\n    if (\"获取不到实例\".equals(e.getMessage())) {\n        // registry empty: 503 + retry hint rather than 500\n        throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, \"demo-provider 暂无可用实例\", e);\n    }\n    throw e;\n}","preventionTips":["Start registry → provider → verify UP on the Eureka dashboard → then start the consumer.","Keep provider spring.application.name and the getInstances literal in one shared constant/config to prevent drift.","Prefer @LoadBalanced RestTemplate (http://demo-provider/echo?name=...) so empty-instance handling and instance choice are delegated to Spring Cloud LoadBalancer.","For startup races, add a brief readiness check (actuator health plus a discovery probe) or retry with backoff on SERVICE_UNAVAILABLE."],"tags":["eureka","service-discovery","spring-cloud","registration","labx-22"],"backgroundTag":null,"analyzedSha":"6c12efaed06d12907a0f40dd2ad1f7020aec8798","analyzedAt":"2026-08-14T13:06:31.500Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}