【问题标题】:loadbalanced ribbon client initialization against discovery service (eureka)针对发现服务(eureka)的负载平衡功能区客户端初始化
【发布时间】:2017-02-03 19:04:02
【问题描述】:

我有在应用程序启动后运行一些初始化脚本的服务(使用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) 何时可用?

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

【问题讨论】:

    标签: spring-cloud netflix netflix-eureka spring-cloud-netflix netflix-ribbon


    【解决方案1】:

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

    【讨论】:

    • 即使我将事件更改为 InstanceRegisteredEvent 我也会遇到相同的异常(没有可用的实例 - 我将其推送到 github)。还有什么可以帮助我的吗?我可以看到来自 event 的配置对象可以转换为 EurekaInstanceConfigBean 并从那里我可以获得目标服务的 ip 地址和端口,但我认为在这种情况下我不能使用 @LoadBalanced 休息模板。如果我能以某种方式帮助您调查此问题,请告诉我。我需要在当前项目中具有此功能。谢谢
    • 我已经创建了监听器(见编辑过的问题),但是有一个问题是每次应用程序重启时它都不会执行。
    • 是否可以监听应用程序每次注册到注册服务器时调用的某些事件?
    猜你喜欢
    • 2018-10-11
    • 1970-01-01
    • 2020-05-22
    • 2017-06-05
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    相关资源
    最近更新 更多