当前位置:网站首页>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
边栏推荐
- Current limiting and fusing of gateway gateway in Spirng cloud
- Mongodb multi field aggregation group by
- MongoDB 多字段聚合Group by
- Metartc4.0 integrated ffmpeg compilation
- 9. Errorstartevent and errorboundaryevent of error events
- MongoDB 多字段聚合Group by
- Case - the list set stores student objects and traverses them in three ways
- Agile conflicts and benefits
- Pychart encountered time zone problem when connecting to MySQL timezone
- MySQL installation in Linux Environment
猜你喜欢

C calls the API and parses the returned JSON string

Etcd understanding of microservice architecture

About anonymous inner classes

Web site learning and sorting

OpenGL馬賽克(八)

Django uses redis to store sessions starting from 0

Database design

Small project - household income and expenditure software (1)

Case - count the number of occurrences of each string in the string

Quartz basic use
随机推荐
安装harbor(在线|离线)
Understanding of speech signal framing
Vagrant virtual machine installation, disk expansion and LAN access tutorial
Bicolor case
[China & some provinces and cities] JSON file for offline map visualization
Database design
Standard input dialog for pyqt5 qinputdialog
Quartz database storage
Case - recursive factorial (recursive)
9. Errorstartevent and errorboundaryevent of error events
Solutions to conflicts between xampp and VMware port 443
Dynamic programming - longest common substring
SQL table columns and statements of database
Case - simulated landlords (primary version)
How to Algorithm Evaluation Methods
redis
Summary of the 11th week of sophomore year
About Evaluation Metrics
Browser screenshot method (long screenshot, node screenshot, designated area screenshot)
Calculate the number of days between two times (supports cross month and cross year)