文章目录
问题:@SentinelRestTemplate不生效
今天使用和@LoadBalanced和@SentinelRestTemplate进行负载均衡和链路流量控制。
@Configuration
public class MainConfig {
@Bean
@LoadBalanced
@SentinelRestTemplate(
blockHandler = "handleException",blockHandlerClass = GlobalExceptionHandler.class,
fallback = "fallback",fallbackClass = GlobalExceptionHandler.class
)
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
但是发现restTemplate中只有一个用于负载均衡的拦截器LoadBalancerInterceptor,就是说@SentinelRestTemplate未生效,@LoadBalanced生效了。
解决
开始以为@SentinelRestTemplate开关没打开,于是添加以下配置
#是否开启@SentinelRestTemplate注解
resttemplate:
sentinel:
enabled: true
配置后仍未生效。
最后发现将RestTemplate 配置在配置在主类才生效
@SpringBootApplication
public class SentinelOrderApplication {
@Bean
@LoadBalanced
@SentinelRestTemplate(
blockHandler = "handleException",blockHandlerClass = GlobalExceptionHandler.class,
fallback = "fallback",fallbackClass = GlobalExceptionHandler.class
)
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(SentinelOrderApplication.class);
}
}
问题原因
源码分析
@LoadBalanced作用时机
smartSingleton.afterSingletonsInstantiated()
首先,经过查看@LoadBalanced源码发现,起作用的时机
finishBeanFactoryInitialization(beanFactory);
->beanFactory.preInstantiateSingletons();
->smartSingleton.afterSingletonsInstantiated();
(loadBalancedRestTemplateInitializerDeprecated)
->customizer.customize(restTemplate);
(restTemplateCustomizer)
最终起作用的是LoadBalancerAutoConfiguration配置类中的匿名内部类RestTemplateCustomizer ,通过此类添加了loadBalancerInterceptor拦截器