If your service needs warm-up time, such as initializing the cache, waiting for related resources to be in place, etc., you can use delay for delayed exposure. In Dubbo version 2.6.5, we made minor adjustments to the service delay exposure logic, and postponed the countdown action for services that require delay exposure (delay > 0) until Spring initialization is complete. You will not feel this change while using Dubbo, so please feel free to use it.
Delay until Spring initialization completes before exposing services1
<dubbo:service delay="-1" />
Expose service with 5 second delay
<dubbo:service delay="5000" />
All services will be exposed after Spring initialization is complete. If you do not need to delay exposing services, you do not need to configure delay.
Expose service with 5 second delay
<dubbo:service delay="5000" />
When Spring resolves to <dubbo:service />
, the service has been exposed, and Spring is still initializing other beans. If a request comes in at this time, and there is a usage of calling applicationContext.getBean()
in the implementation class of the service.
The applicationContext.getBean() call of the requesting thread first synchronizes the singletonObjects to determine whether the Bean exists, and initializes the synchronization beanDefinitionMap if it does not exist, and then synchronizes the singletonObjects again to write the Bean instance cache.
The Spring initialization thread, because it does not need to judge the existence of the bean, directly synchronizes the beanDefinitionMap to initialize, and synchronizes singletonObjects to write the bean instance cache.
This causes the getBean thread to lock singletonObjects first, then beanDefinitionMap, and singletonObjects again. The Spring initialization thread first locks beanDefinitionMap and then singletonObjects. The reverse lock leads to thread deadlock, unable to provide services, and unable to start.
<dubbo:provider delay=”-1” />
to make Dubbo expose the service after the Spring container is initialized.Trigger exposure based on Spring’s ContextRefreshedEvent event ↩︎