报错来源:
restTemplate请求,报 : No instances avaliable for IP,原因请查看在springboot项目中是否有配置 @LoadBalanced 注解。
如下代码执行会报错:
@RequestMapping("/orderToMember")
public Object orderToMember() {
// 1.根据服务名称从 注册中心获取集群列表地址
List<ServiceInstance> instances =
discoveryClient.getInstances("meitemayikt-member");
// 2.列表任意选择一个 实现本地rpc调用 rest 采用我们负载均衡的算法
ServiceInstance srviceInstance = loadBalancer.getSingleAddres(instances);
// 待验证
// 会报错
// 负载均衡 必须使用注册中心上的服务名 不能用ip或域名
URI rpcMemberUrl = srviceInstance.getUri();
System.out.println(rpcMemberUrl);
String result = restTemplate.getForObject(rpcMemberUrl + "/getUser", String.class);
return "订单调用会员返回结果:" + result;
}
String result = restTemplate.getForObject(rpcMemberUrl + "/getUser", String.class);
// 改行代码会报错,通过bug调试,虽然知道已经获取了ip地址,但是依然报:No instances avaliable for IP
原因解释:
@LoadBalanced注解加在RestTemplate请求上,可以实现只调用注册中心内注册的服务,并且使用服务名地址进行调用。
通过添加@LoadBalanced注解,您可以使用服务名而不是显式的服务地址来调用服务。由服务注册中心提供的负载均衡器会处理请求的分发,将其发送到可用的服务实例。
以下是如何在RestTemplate中使用@LoadBalanced注解的示例:
@Configuration
public class MyConfiguration {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
通过上述配置,您可以使用RestTemplate向服务注册中心中注册的服务发起请求。您可以在URL中使用服务名而不是指定具体的服务地址:
@RestController
public class MyController {
private final RestTemplate restTemplate;
public MyController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping("/example")
public String example() {
String serviceUrl = "http://service-name/api/endpoint"; // 使用服务名
ResponseEntity<String> response = restTemplate.getForEntity(serviceUrl, String.class);
// 处理响应
return response.getBody();
}
}
通过在URL中使用服务名,负载均衡器将解析服务实例的地址并相应地分发请求。
请注意,@LoadBalanced注解特定于Spring Cloud生态系统,并与服务注册中心和负载均衡器(如Netflix Eureka或Spring Cloud LoadBalancer)配合使用。
转载请注明来源,谢谢