当前位置:网站首页>Working principle of sentinel series (source code analysis)
Working principle of sentinel series (source code analysis)
2022-06-13 05:41:00 【codain】
stay SpringCloud Use in sentinel Achieve current limiting , We don't need too many configurations in the project ,Sentinel Will automatically protect all HTTP service
Let's see Spring-Cloud-Starter-Alibaba-Sentinel Under this bag , This bag with this Starter The automatic assembly is realized , So we went straight to the bag below spring.factories file , All I see is key=value Configuration information , I won't post it here , Mainly explain the main configuration classes
1、SentinelWebAutoConfiguration It's right Web Servlet Environmental support
2、SentinelWebFluxAutoConfiguration It's right Spring WebFlux Support for
3、SentinelEndpointAutoConfiguration expose Endpoint Information
4、SentinelFeignAutoConfiguration For adaptation Feign Components
5、SentinelAutoConfiguration Support for RestTemplate Service invocation using Sentinel To protect
Let's focus on :SentinelWebAutoConfiguration, This Web Servlet The implementation of the , Source code :
package com.alibaba.cloud.sentinel;
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler;
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner;
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import javax.annotation.PostConstruct;
import javax.servlet.Filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@ConditionalOnClass({CommonFilter.class})
@ConditionalOnProperty(
name = {"spring.cloud.sentinel.enabled"},
matchIfMissing = true
)
@EnableConfigurationProperties({SentinelProperties.class})
public class SentinelWebAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(SentinelWebAutoConfiguration.class);
@Autowired
private SentinelProperties properties;
@Autowired
private Optional<UrlCleaner> urlCleanerOptional;
@Autowired
private Optional<UrlBlockHandler> urlBlockHandlerOptional;
@Autowired
private Optional<RequestOriginParser> requestOriginParserOptional;
public SentinelWebAutoConfiguration() {
}
@PostConstruct
public void init() {
this.urlBlockHandlerOptional.ifPresent(WebCallbackManager::setUrlBlockHandler);
this.urlCleanerOptional.ifPresent(WebCallbackManager::setUrlCleaner);
this.requestOriginParserOptional.ifPresent(WebCallbackManager::setRequestOriginParser);
}
@Bean
@ConditionalOnProperty(
name = {"spring.cloud.sentinel.filter.enabled"},
matchIfMissing = true
)
public FilterRegistrationBean sentinelFilter() {
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean();
com.alibaba.cloud.sentinel.SentinelProperties.Filter filterConfig = this.properties.getFilter();
if (filterConfig.getUrlPatterns() == null || filterConfig.getUrlPatterns().isEmpty()) {
List<String> defaultPatterns = new ArrayList();
defaultPatterns.add("/*");
filterConfig.setUrlPatterns(defaultPatterns);
}
registration.addUrlPatterns((String[])filterConfig.getUrlPatterns().toArray(new String[0]));
Filter filter = new CommonFilter();
registration.setFilter(filter);
registration.setOrder(filterConfig.getOrder());
registration.addInitParameter("HTTP_METHOD_SPECIFY", String.valueOf(this.properties.getHttpMethodSpecify()));
log.info("[Sentinel Starter] register Sentinel CommonFilter with urlPatterns: {}.", filterConfig.getUrlPatterns());
return registration;
}
}
In this class , Found an automatic assembly FilterRegistrationBean, The main function is to register a CommonFilter, And the default is /*, Means to intercept all requests , Let's check CommonFilter Source code logic of , It's very simple :
public class CommonFilter implements Filter {
public static final String HTTP_METHOD_SPECIFY = "HTTP_METHOD_SPECIFY";
public static final String WEB_CONTEXT_UNIFY = "WEB_CONTEXT_UNIFY";
private static final String COLON = ":";
private boolean httpMethodSpecify = false;
private boolean webContextUnify = true;
private static final String EMPTY_ORIGIN = "";
public CommonFilter() {
}
public void init(FilterConfig filterConfig) {
this.httpMethodSpecify = Boolean.parseBoolean(filterConfig.getInitParameter("HTTP_METHOD_SPECIFY"));
if (filterConfig.getInitParameter("WEB_CONTEXT_UNIFY") != null) {
this.webContextUnify = Boolean.parseBoolean(filterConfig.getInitParameter("WEB_CONTEXT_UNIFY"));
}
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest sRequest = (HttpServletRequest)request;
Entry urlEntry = null;
try {
// Parse requested URL
String target = FilterUtil.filterTarget(sRequest);
//URL cleaning
UrlCleaner urlCleaner = WebCallbackManager.getUrlCleaner();
if (urlCleaner != null) {
target = urlCleaner.clean(target);
}
if (!StringUtil.isEmpty(target)) {
String origin = this.parseOrigin(sRequest);
String contextName = this.webContextUnify ? "sentinel_web_servlet_context" : target;
ContextUtil.enter(contextName, origin);
if (this.httpMethodSpecify) {
String pathWithHttpMethod = sRequest.getMethod().toUpperCase() + ":" + target;
// We talked about this in hot data flow restriction
urlEntry = SphU.entry(pathWithHttpMethod, 1, EntryType.IN);
} else {
urlEntry = SphU.entry(target, 1, EntryType.IN);
}
}
chain.doFilter(request, response);
} catch (BlockException var15) {
HttpServletResponse sResponse = (HttpServletResponse)response;
WebCallbackManager.getUrlBlockHandler().blocked(sRequest, sResponse, var15);
} catch (ServletException | RuntimeException | IOException var16) {
Tracer.traceEntry(var16, urlEntry);
throw var16;
} finally {
if (urlEntry != null) {
urlEntry.exit();
}
ContextUtil.exit();
}
}
private String parseOrigin(HttpServletRequest request) {
RequestOriginParser originParser = WebCallbackManager.getRequestOriginParser();
String origin = "";
if (originParser != null) {
origin = originParser.parseOrigin(request);
if (StringUtil.isEmpty(origin)) {
return "";
}
}
return origin;
}
public void destroy() {
}
}
Is the logic simple , Actually, I did three things :
1、 Obtain requested URL
2、 obtain Urlcleaner, If non empty exists , Just explain URL The cleaning strategy is configured , call clean Methods to replace target
3、 Use SphU.entry For the current URL Add current limiting buried point
therefore , about Web Servlet Environmental Science , Only by Filter All requests are automatically set to Sentinel Resources for , So as to achieve the purpose of current limiting
边栏推荐
- Comment procéder à l'évaluation des algorithmes
- NVIDIA Jetson Nano/Xavier NX 扩容教程
- redis
- Top slide immersive dialog
- Parallelgateway and exclusivegateway of 14 gateways
- NVIDIA Jetson nano/xavier NX capacity expansion tutorial
- @Detailed explanation of propertysource usage method and operation principle mechanism
- About the solution of pychart that cannot be opened by double clicking
- Unity游戏优化[第二版]学习记录6
- ZABBIX proxy, sender (without agent monitoring), performance optimization
猜你喜欢
Course outline of market drawing 1- basic knowledge
Problems encountered in the use of PgSQL
Quartz database storage
KVM hot migration for KVM virtual management
Case - traversing the directory (file class & recursive call)
MySQL log management and master-slave replication
SQL table columns and statements of database
Information collection for network security (2)
10 signalstartevent and signalcatchingevent of flowable signal events
float类型取值范围
随机推荐
Explanation of service registration and discovery API of Nacos series
High availability of Nacos series
为什么那么多人讨厌A-Spice
Case - traversing the directory (file class & recursive call)
使用cmake交叉编译helloworld
行情绘图课程大纲1-基础知识
Create a harbor image library from the command line
Database design
MySQL transactions and foreign keys
powershell优化之一:提示符美化
How to Algorithm Evaluation Methods
How to Algorithm Evaluation Methods
MySQL basic query
Small project - household income and expenditure software (2)
10 signalstartevent and signalcatchingevent of flowable signal events
Etcd understanding of microservice architecture
Anaconda configuring the mirror source
Unity game optimization [Second Edition] learning record 6
MySQL built-in functions
Vagrant virtual machine installation, disk expansion and LAN access tutorial