In fact, Sentinel intercepts method execution through adaptive module, no matter it realizes flow limiting or fusing degradation. It calls all entry methods of ProcessorSlot before method execution, and all exit methods of ProcessorSlot after method execution, using responsibility chain mode. A ProcessorSlot is generated by StatisticSlot to collect request information. A FlowSlot checks whether a request needs to be fuses, and a FlowSlot checks whether a request needs to be limited.
The entry method of StatisticSlot increases the number of Bucket requests in the current resource time window by 1. If traffic limiting or fusing is required, the total number of Bucket traffic limiting is increased by 1. The exit method is responsible for updating the Bucket’s total number of successes or exceptions, total elapsed time, maximum elapsed time, and subtracting the number of concurrent threads by one.
Sentinel provides various adaptors to make it easier to use Sentinel. These adaptors are nothing more than the entry method that calls ProcessorSlot and the exit method that calls ProcessorSlot. In the previous study of using Sentinel and OpenFeign integration to achieve fuse downgrading, we used Spring-cloud-start-Alibaba-Sentinel to realize Sentinel and OpenFeign integration.
Sentinel and OpenFeign integrated source code analysis
When Sentinel is integrated with OpenFeign and Ribbon, the client sends a request to the server as shown in the figure below.
- 1. When called
@FeignClient
Annotate interface methods bySentinel
To provide theSentinelInvocationHandler
The method invocation interceptor intercepts the execution of a method based on the method being calledurl
Generate the resource name, and then callSentinel
theSphU
theentry
Method (All doneProcessorSlot ` ` entry
Method) to determine whether the current initiated request needs traffic limiting or fuse downgrading; - 2. In the case of non-current limiting and fusing degradation, continue to submit the request
OpenFeign
theMethodHandler
Processing; - 3,
OpenFeign
fromRibbon
Get a service provider node there; - 4,
OpenFeign
useHttpClient
initiatehttp
Requests; - 5,
OpenFeign
Called when the request is successful or is abnormal (it has been retried)Sentinel
theEntry
theexit
Method (All doneProcessorSlot
theexit
Update the total number of successful requests and exceptions in the current time window;
As you can see, Sentinel is at the front of the interface call, so Sentinel statistics are not affected by retries by the Ribbon or OpenFeign.
Sentinel replaces OpenFeign’s InvocationHandler for request interception by providing its own InvocationHandler. As shown in the figure below SentinelInvocationHandler source code debugging.
InvocationHandler is a JDK dynamic proxy class that OpenFeign generates for the interface. It is the method interception handler of the interface. Sentinel replaces OpenFeign’s InvocationHandler to intercept the execution of the method. Before OpenFeign processes the interface call, it implements the logic of limiting the flow and fusing degradation, as well as the data statistics when the interface call is successful or abnormal. Sentinel, then, is how the original FeignInvocationHandler replacement for SentinelInvocationHandler?
OpenFeign creates a proxy class for the interface through the Feign.Builder class, so Sentinel directly replaces Feign.Builder with SentinelFeign.Builder. By SentinelFeignAutoConfiguration automatic configuration class to inject SentinelFeign Spring Bean container, the code is as follows.
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ SphU.class, Feign.class })
public class SentinelFeignAutoConfiguration {
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "feign.sentinel.enabled")
public Feign.Builder feignSentinelBuilder(a) {
returnSentinelFeign.builder(); }}Copy the code
Sentinelfeign. Builder inherits the Feign.Builder and overwrites the build method, just replacing the InvocationHandlerFactory, So called OpenFeign InvocationHandlerFactory becomes SentinelInvocationHandler InvocationHandler created by the create method. The sentinelfeign. Builder build method is listed below.
public final class SentinelFeign {
public static Builder builder(a) {
return new Builder();
}
public static final class Builder extends Feign.Builder
implements ApplicationContextAware {
/ /...
@Override
public Feign build(a) {
super.invocationHandlerFactory(new InvocationHandlerFactory() {
@Override
public InvocationHandler create(Target target, Map
dispatch)
,> {
/ / create SentinelInvocationHandler}});super.contract(new SentinelContractHolder(contract));
return super.build();
}
/ /...}}Copy the code
The anonymous inner class InvocationHandlerFactory in the Build method had a long create method code, so it was removed.
The create method is responsible for creating SentinelInvocationHandler, through the reflection from the FeignClientFactoryBean @ FeignClient annotations on the fallback configuration, when trigger current limiting or fusing, Sentinel retrieves and invokes a fallback from the Bean factory based on the type configured for the fallback.