我有一个服务,它在应用程序启动后运行一些init脚本(用ApplicationListener<ApplicationReadyEvent>
实现)。在这个脚本中,我需要使用RestTemplate
调用另一个服务@LoadBalanced
。当调用服务调用时,没有关于远程服务实例的信息,因为当时没有联系发现服务器(我猜)。
java.lang.IllegalStateException: No instances available for api-service
at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.execute(RibbonLoadBalancerClient.java:79)
在初始化脚本执行之前,如何在应用程序启动时从发现服务器获取可用服务列表?
由于
修改 问题与事实有关,在当前环境(dev)中,所有服务都在一个服务(api-service)中捆绑在一起。所以从api-service内部我试图调用@LoadBalanced客户端API服务而不了解自己?我可以注册一些听众或类似的东西,知道api-service(self)何时可用?
here是示例应用程序。我主要对如何工作this method
感兴趣EDIT2:
现在可以有解决方案来创建EurekaListener
public static class InitializerListener implements EurekaEventListener {
private EurekaClient eurekaClient;
private RestOperations restTemplate;
public InitializerListener(EurekaClient eurekaClient, RestOperations restTemplate) {
this.eurekaClient = eurekaClient;
this.restTemplate = restTemplate;
}
@Override
public void onEvent(EurekaEvent event) {
if (event instanceof StatusChangeEvent) {
if (((StatusChangeEvent) event).getStatus().equals(InstanceInfo.InstanceStatus.UP)) {
ResponseEntity<String> helloResponse = restTemplate.getForEntity("http://api-service/hello-controller/{name}", String.class, "my friend");
logger.debug("Response from controller is {}", helloResponse.getBody());
eurekaClient.unregisterEventListener(this);
}
}
}
}
然后像这样注册:
EurekaEventListener initializerListener = new InitializerListener(discoveryClient, restTemplate);
discoveryClient.registerEventListener(initializerListener);
但是,这仅在应用程序第一次注册到发现服务时执行。下次当我停止api-service并再次运行它时,事件不会发布。还有其他事件我能抓到吗?
答案 0 :(得分:4)
目前,在Camden及更早版本中,应用程序必须先在Eureka中注册,然后才能查询其他应用程序。您的通话可能在注册生命周期中过早。有一个InstanceRegisteredEvent
可能会有所帮助。有计划在Dalston发布列车上进行此项工作。