Writing in the front
I drew a map using XMindRecord study notes on Spring Cloud Alibaba(The source file has detailed remarks and references for some nodes, but not all of them are shown because they are too large.Welcome to follow my official account: A Feng architecture Notes background send [map] to get the download link,Has been improved and updated) :
preface
Consider this question:
The configuration of Sentinel degrade fuse, when used in production environment, is generally managed on the console and persisted to Nacos; Microservices listen for configuration changes in Nacos to implement a degraded circuit breaker strategy for service invocation.
If there are many Feign interfaces, for example, service A and service B have some remote calls to Feign interfaces, which need to be configured one by one. ** And most of the parameters configured are the same. Such as:
1. Configure degrade policy for slow response policy of Feign remote call
2. Configure degrade policy for Feign remote call exceptions
3. Configure degradation strategy for the abnormal proportion of Feign remote calls
1-2 service methods are fine for the above configuration; But now that companies have 100-200 microservices in their production environments, there are many more ways to call each other. That for common standard downgrade fuse configuration need manual configuration one by one, that is not too troublesome.
This article will solve this problem, then continue to read.
Source code analysis
Let’s take a look at how Sentinel sets up its circuit breaker policy. In the figure above, we know that Sentinel is configured through the Sentinel console, and then microservices can subscribe to these configurations. Let’s take a look at the source code.
This is the code that listens for nacOS configuration
The core of the above code is the updateValue rule when configuration changes are found. It all adds up to a separated manager class with ruleMap and circuitBreakers. We can guess the demotion rule set and the circuit breaker rule set.
Further down the line, there is a RulePropertyListener in which the reloadFrom method **** reloads the rule; There’s a buildCircuitBreakers method in there, which you can tell by its name is buildCircuitBreakers.
In looking at the buildCircuitBreakers method, we see that it is essentially a matter of traversing the DegradeRule collection and then initializing the CircuitBreaker.
Here we see how the circuit breaker works; The essence is generated by a Survival ule.
The solution
It provides a custom DegradeRule object to generate a fuse. When we were studying Sentinel, they had an Api for defining the degradation rules, and you can go back and look at the previous article, which explained in detail how the Api defined the rules. Let’s look at the case
Provides a definition of a Survival Ule object and a Survival Manager object. The above code defines a slow response degradation policy for the resource name API.
Have you come up with some ideas? To look down.
Solution ideas
Give the overall solution first
The process described in the figure above
1When starting the service, scan the JAR and obtain@FeignClientAnnotated interface (technical difficulty 1: which JAR packages to scan)2Get the calling method in the Feign interface3Creates a DegradeRule object locally. (Technical difficulty 2: Sentinel resource name supports dynamic configuration)4, synchronize the default downgrade circuit breaker rules set to NacosCopy the code
Based on the above flow, we can see that once the microservice is started, the Feign interface is automatically configured with the default degrade circuit breaker and synchronized to Nacos. Combined with the Sentinel console transformation described in the previous article, these reversion rules are immediately displayed on the console without being considered configured.
** Note: ** The above is just an overview of the overall process, we need to consider many scenarios when writing code, such as:
A) When the service is started for the second time, relevant configuration has been found in NACOS. Do you need to modify the configuration of NACOS?
B) how is the default global configuration compatible with manual configuration for some special services degraded in Sentinel console?
These are not here to talk about, this article only introduces the core scheme ideas, core code
Other interested partners can follow the source code
Technical difficulties
The difficulties in the
We scan jar packages, and we scan jars that contain the @FeignClient annotation interface. We know that when using the Feign function, we need to add @enablefeignclients to the SpringBootApplication startup class;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ApplicationA {
public static void main(String[] args) { SpringApplication.run(ApplicationA.class, args); }}Copy the code
Sometimes Feign packages are stored as third-party jars, and the code becomes
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.rainbow.demo1.feign","com.rainbow.demo2.feign"})
public class ApplicationA {
public static void main(String[] args) { SpringApplication.run(ApplicationA.class, args); }}Copy the code
The ** @enableFeignClients attribute basePackages explicitly points to the Feign package location **. This is easier to fix by using the ClassScan utility class.
The ClassScan utility class supports subpackage scanning
There is no explicit definition of basePackages, so how to get the jar package path?
We can refer to the source code implementation method of SpringCloud to see the code.
Above is the start class object of the main method based on the stack information when the service is started.
Get the EnableFeignClients object based on the launch class object, or if there are no basePackages, the start class package is the entry to the scan.
This solves the problem of scanning jar entries.
The difficulties in the second
The conventional way
Get the resource name, for example
@FeignClient(name = "service-provider")
public interface ProviderServiceFeign {
@GetMapping("/transferHeaders")
public BaseRestResponse<String> transferHeaders(a);
}
Copy the code
According to the Sentinel resource name definition of microservice, @feignClient (name = “service-provider”), the microservice name is service-provider; The resource name of the degrade policy for the transferHeaders() method is
lb://service-provider/transferHeaders
Copy the code
The simple implementation is to get the @feignClient name value and the @getMapping value to concatenate the resource name.
Specify the Url address
@FeignClient(name = "service-provider",url = "http://xxxxx")
public interface ProviderServiceFeign {
@GetMapping("/transferHeaders")
public BaseRestResponse<String> transferHeaders(a);
}
Copy the code
In this case, the resource name of Sentinel is
http://xxxxx/transferHeaders
Copy the code
The technical implementation is also relatively simple, just need to consider this scenario, it is ok.
Dynamically Configuring the Url
Another situation is that when connecting to a third-party platform, we generally do not write dead Url, but through configuration, such as
@FeignClient(name = "service-provider",url = "${reqUrl}")
public interface ProviderServiceFeign {
@GetMapping("/transferHeaders")
public BaseRestResponse<String> transferHeaders(a);
}
Copy the code
${reqUrl} = ${reqUrl}; ** Essentially, the resource name is also the Url+ the specific requested address, i.e
http://${reqUrl}/transferHeaders
Copy the code
However, setting the resource name in this way is definitely not correct, you need to take the specific configuration value to concatenate. ${reqUrl} ${reqUrl} ${reqUrl} It’s just using
Environment environment ;// Environment variable object
this.environment.resolvePlaceholders(url);// Get the value of the variable
Copy the code
The core code
After the above technical difficulties are solved, we will let go of the hands of the code, here attached to the core code; Guys.
public class DegradeRuleInitializer implements ApplicationRunner.EnvironmentAware
Copy the code
Implementing ApplicationRunner, EnvironmentAware enables you to implement the run method in ApplicationRunner at startup, to scan the entry.
Scan class
Scanning FeignClient
Initialize the default rule
Default degradation rules are set and the configuration information is published to NACOS
The effect
Once the microservice is started, the NACOS configuration is available
We will publish the default values to nacOS. You can see the resource names in detail, and there will be a lot of degradation rules.
Take a look at the Sentinel console, which displays a list of downgrading rules. This paper designs three types of degraded circuit breaker strategies for the same resource name, such as number of exceptions, proportion of exceptions and slow response.
The global default value, exactly what the threshold is, can be configured, these will not be described. It’s easy.
By now, the default configuration of the degraded fuse policy of Feign interface in microservice has been realized. There is no need to add it manually. Of course, manual modification is supported. If the threshold value needs to be modified, it can be manually modified.
conclusion
In this paper, the implementation scheme of Sentinel global Feign default fuse is introduced. The overall idea and principle are not too complicated, but some extensions are made by using its own functions. This is more convenient for users.
Three things to watch ❤️
If you find this article helpful, I’d like to invite you to do three small favors for me:
- Like, forward, have your “like and comment”, is the motivation of my creation.
- Follow the public account “ARCHITECTURE Notes of A Wind” and share original knowledge from time to time.
- Also look forward to the follow-up article ing🚀
- [666] Scan code to obtain the architecture advanced learning materials package