2

我有在应用程序启动后运行一些初始化脚本的服务(用 实现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-service?我可以注册一些侦听器或类似的东西以了解 api-service (self) 何时可用?

是示例应用程序。我主要对如何使用这种方法感兴趣

编辑2:

现在可能有创建 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 并再次运行它时,不会发布事件。还有其他我可以捕捉的事件吗?

4

1 回答 1

4

目前,在Camden及更早的版本中,应用程序需要先在Eureka中注册,然后才能查询其他应用程序。您的电话可能在注册生命周期中为时过早。有一个InstanceRegisteredEvent可能会有所帮助。有计划在 Dalston 发布火车上解决这个问题。

于 2016-09-26T22:01:34.910 回答