0:问题:sentinel是怎么拦截并进行限流,熔断,降级的。
1:找自动配置类:
老规矩:直接搜索 spring.factories 文件,查询关键字 SentinelAuto,配置如下:
com.alibaba.cloud.sentinel.SentinelWebAutoConfiguration,\
com.alibaba.cloud.sentinel.SentinelWebFluxAutoConfiguration,\
com.alibaba.cloud.sentinel.endpoint.SentinelEndpointAutoConfiguration,\
com.alibaba.cloud.sentinel.custom.SentinelAutoConfiguration,\
com.alibaba.cloud.sentinel.feign.SentinelFeignAutoConfiguration
2:SentinelWebAutoConfiguration:
先看 SentinelWebAutoConfiguration:一看就是很关键的一个,以此为切入点,其他的AutoConfiguration慢慢看。
2.1 这个类继承或者实现了哪些接口。
这个类 实现了 WebMvcConfigurer 的 addInterceptors(InterceptorRegistry registry) 方法,
那这里就来讲讲它实现该接口的意义:其他不相关的属性就不列了。
@EnableConfigurationProperties(SentinelProperties.class)
public class SentinelWebAutoConfiguration implements WebMvcConfigurer {
@Autowired
private Optional<SentinelWebInterceptor> sentinelWebInterceptorOptional;
@Autowired
private SentinelProperties properties;
//这个方法的扩展点是在:创建 requestMappingHandlerMapping的Bean时,往这个Bean中添加拦截器SentinelWebInterceptor。
//这里就是添加sentinel的拦截器。去拦截所有的请求。
@Override
public void addInterceptors(InterceptorRegistry registry) {
//这里就是判断 SentinelWebInterceptor 是否存在
if (!sentinelWebInterceptorOptional.isPresent()) {
return;
}
SentinelProperties.Filter filterConfig = properties.getFilter();
//这里就是会取到 SentinelWebInterceptor,
registry.addInterceptor(sentinelWebInterceptorOptional.get())
.order(filterConfig.getOrder())
// 这里取到的是 默认的 /**
.addPathPatterns(filterConfig.getUrlPatterns());
log.info(
"[Sentinel Starter] register SentinelWebInterceptor with urlPatterns: {}.",
filterConfig.getUrlPatterns());
}
}
2.2看看这个类注入了哪些Bean.
@Autowired
private Optional<BlockExceptionHandler> blockExceptionHandlerOptional;
@Bean
@ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled",
matchIfMissing = true)
public SentinelWebInterceptor sentinelWebInterceptor(
SentinelWebMvcConfig sentinelWebMvcConfig) {
return new SentinelWebInterceptor(sentinelWebMvcConfig);
}
//这里就是注入一个 SentinelWebMvcConfig 的Bean,看名字是一个 sentinel的请求的一个配置类。
@Bean
@ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled",
matchIfMissing = true)
public SentinelWebMvcConfig sentinelWebMvcConfig() {
SentinelWebMvcConfig sentinelWebMvcConfig = new SentinelWebMvcConfig();
sentinelWebMvcConfig.setHttpMethodSpecify(properties.getHttpMethodSpecify());
//这里会获取到自定义的 MySentinelException,如果没有自定义就是空的。
if (blockExceptionHandlerOptional.isPresent()) {
blockExceptionHandlerOptional
.ifPresent(sentinelWebMvcConfig::setBlockExceptionHandler);
}
else {
//这里检查 是否又配置 Block
if (StringUtils.hasText(properties.getBlockPage())) {
sentinelWebMvcConfig.setBlockExceptionHandler(((request, response,
e) -> response.sendRedirect(properties.getBlockPage())));
}
else {
// 如果都没有 ,则配置一个 默认的:DefaultBlockExceptionHandler,因为这个 DefaultBlockExceptionHandler 不是Bean,所以不会在 blockExceptionHandlerOptional 中。
sentinelWebMvcConfig
.setBlockExceptionHandler(new DefaultBlockExceptionHandler());
}
}
//这个是 UrlCleaner 看名字 url清洁,没有实现累,暂时不知道做什么功能。
urlCleanerOptional.ifPresent(sentinelWebMvcConfig::setUrlCleaner);
//RequestOriginParser 这个接口的解释是:The origin parser parses request origin (e.g. IP, user, appName) from HTTP request.
//猜测:应该是 处理 公共的问题,类似与 网关拦截,geteway。
requestOriginParserOptional.ifPresent(sentinelWebMvcConfig::setOriginParser);
return sentinelWebMvcConfig;
}
下一章节讲:SentinelWebInterceptor。