{"record":{"id":"59946fd72476007a","repo":"yudaocode/SpringBoot-Labs","slug":"error-59946f","errorCode":null,"errorMessage":"获取不到实例","messagePattern":"获取不到实例","errorType":"exception","errorClass":"IllegalStateException","httpStatus":500,"severity":"error","filePath":"labx-27/labx-27-sc-consul-discovery-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx27/consuldemo/consumer/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-27/labx-27-sc-consul-discovery-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx27/consuldemo/consumer/DemoConsumerApplication.java#L41-L70","documentation":"The labx-27 Spring Cloud Consul discovery consumer throws IllegalStateException(\"获取不到实例\") when DiscoveryClient.getInstances(\"demo-provider\") returns an empty list — Consul's catalog has no healthy instances registered under that name. Consul registers services with health checks (default TTL/HTTP per config); an instance that fails its health check is reported with a critical status, and Spring Cloud's Consul catalog query filters to passing instances by default. So this error arises both when the provider never registered and when it registered but its health check went critical — a distinction from plain Eureka lease semantics.","triggerScenarios":"Calling /echo when: the Consul provider app is not running or never registered (missing spring-cloud-starter-consul-discovery); spring.application.name ≠ 'demo-provider'; Consul agent not started (default localhost:8500) or consumer's spring.cloud.consul.host/port point to the wrong agent; the provider registered but its health check is critical so the passing-only query yields nothing; provider is mid-startup and registration/health-check propagation has not completed.","commonSituations":"Consul agent (dev mode: consul agent -dev) not running before the apps; health-check failures (e.g. the default /actuator/health endpoint unavailable because management deps missing, or a misconfigured spring.cloud.consul.discovery.health-check-path); name mismatches between the getInstances literal and provider's spring.application.name; Docker/remote Consul where host/port config is stale; querying a catalog in a different Consul datacenter.","solutions":["Open the Consul UI (http://localhost:8500) and check the 'demo-provider' service: no service listed → start the demo provider; listed but red/critical → fix its health check (dependency/endpoint) so it turns green.","Confirm the provider's spring.application.name equals demo-provider exactly and both apps use the same spring.cloud.consul.host/port.","Start Consul in dev mode first (consul agent -dev), then the provider, wait for its check to pass, then the consumer call.","If health-check strictness is unwanted in a demo, set spring.cloud.consul.discovery.register-health-check=false or configure queryOptions to skip checks, then retry.","Handle the empty list explicitly (503 + message) or fall back to LoadBalancerClient.choose 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 referencing Consul health\nList<ServiceInstance> instances = discoveryClient.getInstances(\"demo-provider\");\nif (instances.isEmpty()) {\n    throw new IllegalStateException(\n        \"获取不到实例: no passing Consul instances for 'demo-provider'; \" +\n        \"check http://localhost:8500 for registration and health status\");\n}\nServiceInstance instance = instances.get(0);","handlingStrategy":"validation","validationCode":"List<ServiceInstance> instances = discoveryClient.getInstances(\"demo-provider\");\nif (instances.isEmpty()) {\n    // includes 'registered but health check critical' cases, since queries filter to passing\n    throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE,\n        \"demo-provider 无健康实例, 请检查 Consul UI (http://localhost:8500)\");\n}\nServiceInstance instance = instances.get(0);","typeGuard":"boolean consulHasPassingInstance(DiscoveryClient dc, String service) {\n    List<ServiceInstance> list = dc.getInstances(service);\n    return list != null && !list.isEmpty();\n}","tryCatchPattern":"catch (IllegalStateException e) {\n    if (\"获取不到实例\".equals(e.getMessage())) {\n        // likely health-check critical or not yet registered: 503 + hint\n        return ResponseEntity.status(503)\n            .body(\"demo-provider not passing Consul health checks; check consul UI\");\n    }\n    throw e;\n}","preventionTips":["Run `consul agent -dev` before the apps and keep spring.cloud.consul.host/port aligned on both sides.","Ensure the provider's health-check endpoint works (actuator + correct spring.cloud.consul.discovery.health-check-path) so instances show green.","Watch the Consul UI catalog during development: red checks explain empty getInstances results instantly.","For demos, spring.cloud.consul.discovery.register-health-check=false removes health-gating while you test connectivity."],"tags":["consul","service-discovery","spring-cloud","health-check","registration","labx-27"],"backgroundTag":null,"analyzedSha":"6c12efaed06d12907a0f40dd2ad1f7020aec8798","analyzedAt":"2026-08-14T13:06:31.500Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}