アプリケーションの起動後にいくつかの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)
initスクリプトが実行される前に、アプリケーションの起動時に検出サーバーから利用可能なサービスのリストを取得する方法はありますか?
ありがとう
編集: 問題は、現在の環境(dev)ではすべてのサービスが1つのサービス(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 を停止して再度実行すると、イベントが発行されません。他にキャッチできるイベントはありますか?