Skip to content

starting invoke failed

chengyouling edited this page Jun 12, 2025 · 3 revisions

启动过程中调用失败问题

基于ApplicationReadyEvent事件调用异常

  • 问题现象

从Nacos、Eureka等注册中心切换到Servicecomb注册中心后,或者初次接入Servicecomb引擎项目,服务启动过程中基于ApplicationReadyEvent事件调用下游服务显示无服务实例可用,但是微服务又能正常注册,错误日志如下:

Caused by: java.lang.IllegalStateException: No instances available for provider
  • 问题原因

Spring的bean初始化是无序的,ApplicationReadyEvent事件发布时并不能保证微服务注册过程已完成,而基于Servicecomb引擎做服务发现需要校验当前服务注册信息,所以当微服务注册过程还未完成时,仅依赖ApplicationReadyEvent事件发起RPC调用可能出现服务发现失败无法获取服务实例的问题。

推荐方案

基于ApplicationReadyEvent、MicroserviceInstanceRegistrationEvent(Servicecomb注册实例完成事件)均完成情况下,发起下游服务的调用,如下代码示例:

@Component
public class InvokeProviderByEvent implements ApplicationListener<ApplicationReadyEvent> {
  private final RestTemplate restTemplate;

  private boolean isApplicationReady = false;

  private boolean isServiceInstanceRegistry = false;

  @Autowired
  public InvokeProviderByEvent(RestTemplate restTemplate) {
    EventManager.getEventBus().register(this);
    this.restTemplate = restTemplate;
  }

  @Subscribe
  public void onMicroserviceInstanceRegistrationEvent(MicroserviceInstanceRegistrationEvent event) {
    if (event.isSuccess()) {
      isServiceInstanceRegistry = true;
    }
    invokeProvider();
  }

  private void invokeProvider() {
    if (isApplicationReady && isServiceInstanceRegistry) {
      restTemplate.getForObject("http://provider/eventInvoke", String.class);
    }
  }

  @Override
  public void onApplicationEvent(ApplicationReadyEvent event) {
    isApplicationReady = true;
    invokeProvider();
  }
}
Clone this wiki locally