This is the 28th day of my participation in the August Text Challenge.More challenges in August
🌈 Column Introduction
Thank you for reading, I hope to help you, if there is a flaw in the blog, please leave a message in the comment area or add my private chat in the home page, thank you for every little partner generous advice. I am XiaoLin, a boy who can both write bugs and sing rap. This column mainly introduces the most mainstream micro services solution, SpringCloudAlibaba, which will be introduced in groups. Column address: SpringCloudAlibaba
- 5️ retail Feign
- 4️ Ribbon (suggested collection)
- 3️ Nacos (suggested collection)
- 2️ retail (suggested collection)
- 1️ retail (suggested collection)
Eight, flow protection: Sentinel
8.1. Problems caused by high concurrency
In micro service architecture, we will split into small business service, service and service can call each other between, but due to network or its own reasons, 100% of the service does not guarantee available, if a single service problems, invoking the service network delay will occur and then if there is a lot of network, will form the task, Eventually, the service crashed.
8.2. Simulate high concurrency
8.2.1. Written SentinelController
@RestController
public class SentinelController {
@RequestMapping("/sentinel1")
public String sentinel1(a){
// Simulate a network delay
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "sentinel1";
}
@RequestMapping("/sentinel2")
public String sentinel2(a){
return "Testing problems with high concurrency"; }}Copy the code
8.2.2. Change the concurrency of Tomcat
tomcat:
threads:
max: 10 # change the maximum concurrency of tomcat to 10.
Copy the code
8.2.3 Use stress tests to simulate high concurrency
Download from jmeter.apache.org/
Modify the configuration to support Chinese
Go to the bin directory and change the language support in the jmeter.properties file to language=zh_CN.
Then click jmeter.bat to launch the software.
Adding a thread Group
Adding an HTTP Request
access
We went to visit http://localhost:8082/sentinel2, will find that have been in the circle, this is the prototype of the avalanche server.
8.3. Server avalanche
In distributed systems, services are generally not guaranteed to be 100% available due to network or its own reasons. If there is a problem with a service, a thread blocking occurs when calling the service. If a large number of requests come in, multiple threads will block and wait, causing the service to crash.
The “avalanche effect” of service failures is the spread of failures due to service-to-service dependencies, which can have catastrophic consequences for the entire microservice system.
The server step-by-step avalanche flow is as follows:
The avalanche effect of a server is that a small service dies and a whole service becomes unavailable. Similar to the avalanche effect in life, an avalanche is triggered by the last snowflake falling.
Avalanches can happen for a variety of reasons, from poor capacity design, to a method that is slow to respond to high concurrency, to a machine that runs out of resources. We cannot completely eliminate the avalanche source, only to do enough fault tolerance, to ensure that a problem in one service will not affect the normal operation of other services.
Avalanches can happen for a variety of reasons, from poor capacity design, to a method that is slow to respond to high concurrency, to a machine that runs out of resources. We cannot completely eliminate the avalanche source, only to do enough fault tolerance, to ensure that a problem in one service will not affect the normal operation of other services. That is, “Snow falls, not avalanche”.
8.4 common Solutions
To prevent the spread of avalanche, we need to do a good job of service fault tolerance, fault tolerance is to protect yourself from being dragged down by pig teammates some measures, the following introduces common service fault tolerance ideas and components.
Common fault tolerance ideas include isolation, timeout, current limiting, fusing and degradation.
8.4.1 Isolation mechanism
For example, if there are 100 threads in service A, now service A might call service B, service C, and service D. When service A makes A remote call, we assign fixed threads to different services, not all threads to A microservice. For example, call service B allocates 30 threads, call service C allocates 30 threads, and call service D allocates 40 threads. This isolation of resources ensures that even if A downstream service fails, service A will not run out of threads. For example, if service B dies, at most 30 threads of service A will be used, and service A will have 70 threads to call service C and service D.
8.4.2 Timeout mechanism
When the upstream service calls the downstream service, set a maximum response time. If the downstream does not respond after this time, the request is disconnected and the thread is released.
8.4.3 Flow limiting mechanism
Current limiting is to limit the input and output flow of the system to protect the system. In order to ensure the stable operation of the system, once the threshold of limiting traffic is reached, it is necessary to limit traffic and take a few measures to complete the purpose of limiting traffic.
8.4.4 Circuit breaker mechanism
In an Internet system, when downstream services respond slowly or fail due to excessive access pressure, upstream services can temporarily cut off calls to downstream services to protect the overall availability of the system. This measure of sacrificing part while preserving the whole is called circuit breaker.
Service fuses generally have three states:
- Fusible Closed: The state in which the fuses are located when the service is not faulty, which does not restrict the calls made by the caller.
- Fusing Open: Subsequent calls to the service interface do not go over the network, but directly execute the local fallback method.
- Half-open: An attempt is made to resume the service invocation, allowing limited traffic to invoke the service and monitoring the success rate of the invocation. If the success rate reaches the expected, it indicates that the service has been restored and enters the fusing shutdown state. If the success rate is still low, the circuit breaker is re-entered.
8.4.5 Demotion mechanism
Downgrading is essentially providing a bottom-of-the-line solution for the service, which is used when the service cannot be called properly.
8.5 common fuse components
8.5.1, Hystrix
Hystrix is an open-source delay and fault tolerance library provided by Netflflix to isolate access to remote systems, services, or third-party libraries to prevent cascading failures, thereby improving system availability and fault tolerance.
8.5.2, Resilience4J
Resilicence4J is a very lightweight, simple, well-documented, and rich fuse breaker, which is an official Hystrix recommended alternative. Resilicence4j also natively supports Spring Boot 1.x/2.x, and monitoring supports integration with several major products such as Prometheus.
8.5.3, Sentinel
Sentinel is an open source circuit breaker implementation of Alibaba. Sentinel itself has been adopted on a large scale in Alibaba and is very stable.
8.6. Sentinel Combat
8.6.1 What is Sentinel
Sentinel (Traffic Defender for Distributed System) is a comprehensive solution for service fault tolerance developed by Alibaba. It takes flow as the entry point to protect the stability of service from several dimensions such as flow control, fusing downgrading and system load protection.
Sentinel has the following characteristics:
-
Rich application scenarios: Sentinel has undertaken the core scenarios of Alibaba’s double Eleven traffic drive in the past 10 years, such as SEC killing (i.e. burst traffic control within the range of system capacity), message peaking and valley filling, cluster flow control, real-time fusing of unavailable downstream applications, etc.
-
Complete real-time monitoring: Sentinel provides real-time monitoring capabilities. The console allows you to see the second-level data of a single machine connected to an application, and even the summary performance of a cluster of less than 500 machines.
-
Extensive Open source ecosystem: Sentinel provides out-of-the-box integration modules with other open source frameworks/libraries, such as SpringCloud, Dubbo, and gRPC. Sentinel can be accessed quickly by introducing dependencies and simple configuration.
8.6.2 Sentinel components
Sentinel is divided into two parts:
- The core library (Java client) is independent of any framework/library, can run in all Java runtime environments, and has good support for frameworks such as Dubbo /Spring Cloud.
- The Console (Dashboard) is based on Spring Boot and can be packaged to run directly without the need for additional application containers such as Tomcat.
8.7. Sentinel integration
Microservice integration with Sentinel is very simple, just adding the Sentinel dependencies.
8.7.1 Adding a Dependency
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
Copy the code
8.7.2 Writing controllers
@RestController
public class SentinelController {
@RequestMapping("/sentinel1")
public String sentinel1(a){
// Simulate a network delay
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "sentinel1";
}
@RequestMapping("/sentinel2")
public String sentinel2(a){
return "Testing problems with high concurrency"; }}Copy the code
8.7.3. Install Sentinel console
Download the jar package
Sentinel provides a lightweight console that provides machine discovery, real-time monitoring of stand-alone resources, and rule management. We need to download the Sentinel console JAR package.
Modify the application. Yml
spring:
cloud:
sentinel:
transport:
port: 9999 Select an unused port to communicate with the console
dashboard: localhost:8080 Specify the address of the console service
Copy the code
Start console
#Start the project directly with the JAR command (the console itself is a SpringBoot project)java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar Sentinel dashboard - 1.8.0 comes with jarCopy the code
test
Access the console via a browser to localhost:8080 (default username password is sentinel/sentinel)
8.7.4 Principle of the console
Sentinel’s console is actually a program written by SpringBoot. We need to register our microserver with the console, that is, specify the address of the console in the microservice, and open a port to pass data to the console. The console can also call the monitor in the microservice through this port to get various information about the microservice.
8.8. Implement traffic limiting on an interface
Go to Cluster link -> Flow Control
Write the value in the single-machine threshold
Enter a value in the single-machine threshold to indicate the maximum number of requests per second
test
A few quick visits will tell you what went wrong.
8.9 Basic concepts and functions of Sentinel
8.9.1 Basic Concepts
8.9.1.1, resources,
Resources are what Sentinel is trying to protect. Resources are the key concept of Sentinel. It can be anything in a Java application, a service, a method, or even a piece of code.
One of the Sentinel2 methods in our example above is a resource.
8.9.1.2, rules,
Rules define how resources are protected. Function on resources, define the way to protect resources, mainly including flow control rules, fuse degradation rules and system protection rules.
Our example above adds flow control rules to Sentinel2, limiting its traffic.
8.9.2 Important Functions
The main function of Sentinel is fault tolerance, which is mainly reflected in the following three aspects:
-
Flow control
Flow control is a common concept in network transport, which is used to adjust the data of network packets. Requests arriving at any time are often random and uncontrollable, and the processing capacity of the system is limited. We need to control the flow according to the processing capacity of the system. Sentinel acts as a dispatcher that adjusts random requests to fit as needed.
-
Fusing the drop
When a resource in the invocation link is detected to be unstable, for example, the request response time is long or the proportion of exceptions is high, the invocation of this resource is restricted to ensure that the request fails quickly and avoid cascading faults caused by other resources.
Sentinel approaches this problem in two ways:
- Limit by number of concurrent threads: Sentinel reduces the impact of unstable resources on other resources by limiting the number of concurrent threads for resources. When a resource is unstable, such as a long response time, the direct effect on the resource is a gradual accumulation of threads. When the number of threads accumulates to a certain number on a particular resource, new requests for that resource are rejected. The piled thread completes the task before resuming receiving requests.
- Resource degradation by response time: In addition to controlling the number of concurrent threads, Sentinel can quickly degrade unstable resources by response time. If the response time of a dependent resource is too long, all access to the resource is denied until the specified time window expires.
-
System load protection
Sentinel also provides adaptive protection at the system dimension. When the system is under high load, continuing to let requests in can cause the system to crash and fail to respond. In a clustered environment, traffic that should be carried by this machine is forwarded to other machines. If other machines are in an edge state at this time, Sentinel provides a protection mechanism to balance the system’s incoming traffic with the system’s load, ensuring that the system can handle the most requests within its capacity.
Summary: What we need to do is to configure various rules on Sentinel resources to implement various fault-tolerant features.
8.10. Sentinel Flow control Rules
Traffic control monitors application traffic indicators, such as QPS(query rate per second) or number of concurrent threads, and controls the traffic when it reaches a specified threshold to avoid being overwhelmed by instantaneous traffic peaks and ensure high availability of applications.
Resource name: unique name, default is the request path, can be customized.
Source specific: Specifies which microservice to limit traffic. The default value is default, which means that all microservices are restricted regardless of source.
Threshold Type/Single-node threshold:
- QPS (Number of requests per second) : Traffic limiting is performed when the NUMBER of QPS calling the interface reaches the threshold.
- Number of threads: When the number of threads calling the interface reaches the threshold, traffic limiting is performed.
8.10.1. Flow limiting of Threads
We’ve already tested QPS limiting, so let’s change to thread limiting.
8.10.1.1. Add a flow control rule
8.10.1.2 Adding a thread to Jmeter
8.10.1.3, test,
8.10.2 Flow control mode
Click the edit button above to set flow control rules, and then click advanced options in the edit page, you will see the column of flow control mode.
He has three flow control modes:
- Direct (default) : Enables traffic limiting when the interface meets traffic limiting conditions.
- Association: When the associated resource reaches the traffic limiting condition, traffic limiting is enabled.
- Link: Enables traffic limiting when the resources from an interface meet traffic limiting conditions
8.10.2.1 Associated flow control mode
In associated flow control mode, when the interface associated with the specified interface reaches the traffic limiting condition, enable traffic limiting for the specified interface.
For example, two resources are associated when there is a resource contention or dependency relationship between them. For example, the read and write operations of the same database field compete. If the read speed is too high, the write speed will be affected, and the write speed will be affected. If read and write operations are left to scramble for resources, the cost of scrambling itself can reduce overall throughput. Association limiting can be used to avoid excessive contention between related resources.
We can correlate the sentinel1 resource while we test.
We use Jmeter to continuously send requests to/Sentinel1. Note that the QPS must be greater than 2. When we visit/Sentinel2, we find that the traffic is restricted.
8.10.2.2 Link flow control mode
In link flow control mode, when the resources from an interface meet traffic limiting conditions, traffic limiting is enabled. Its function is somewhat similar to that of the source-specific configuration item, except that source-specific is for the upper-level microservice, whereas link-flow control is for the upper-level interface, which means it is more granular.
Modify the application. Yml
spring:
cloud:
sentinel:
web-context-unify: false
Copy the code
TraceServiceImpl
@Service
@Slf4j
public class TraceServiceImpl {
@SentinelResource(value = "tranceService")
public void tranceService(a){
log.info("Call the tranceService method"); }}Copy the code
New TraceController
@RestController
public class TraceController {
@Autowired
private TraceServiceImpl traceService;
@RequestMapping("/trace1")
public String trace1(a){
traceService.tranceService();
return "trace1";
}
@RequestMapping("/trace2")
public String trace2(a){
traceService.tranceService();
return "trace2"; }}Copy the code
Restart the order service and add the link flow control rule
test
If /trace1 and /trace2 are accessed, /trace2 is ok, and /trace1 is limited.
8.10.3 Flow control effect
- Fail fast (default) : Fail directly, throwing an exception without doing any extra processing, is the simplest effect.
- Warm Up: It has a buffering phase from the start threshold to the maximum QPS threshold, starting at 1/3 of the maximum QPS threshold and growing slowly until it reaches the maximum threshold. It is suitable for scenarios where sudden increases in traffic are converted into slow increases.
- Queuing: Let the requests pass at a uniform speed, the single-machine threshold is the number of passes per second, the rest of the queuing; It also sets a timeout so that requests that have not been processed beyond the elapsed time are discarded.
8.11. Sentinel downgrade Rule
A degrade rule is a service that is degraded when certain conditions are met. Sentinel provides three measures:
- Slow call Ratio: Select slow call ratio as the threshold. You need to set RT (maximum response time) for slow calls. If the response time of a request is greater than this value, the request is counted as slow calls. If the number of requests per unit statistics period is greater than the minimum number of requests and the ratio of delayed calls is greater than the threshold, the requests will be fused automatically in the following fuse duration. After the fuse duration, the fuse will enter the probe recovery state (half-open state). If the response time of the next request is less than the set slow-call RT, the fuse will end. If the response time is longer than the set slow-call RT, the fuse will be disconnected again.
- Abnormal proportion: If the number of requests per unit statistical period is greater than the minimum number of requests and the proportion of abnormal requests is greater than the threshold, the requests will be fused automatically in the following fusing period. After the fuse period, the fuse enters the probe half-open state, terminating the fuse if the next request completes successfully (without error), otherwise it will be fused again. The threshold range for abnormal ratio is
[0.0, 1.0]
, represents 0-100%. - Number of exceptions: When the number of exceptions in a unit statistics period exceeds the threshold, the circuit breaker is automatically disabled. After the fuse period, the fuse enters the probe half-open state, terminating the fuse if the next request completes successfully (without error), otherwise it will be fused again.
8.11.1 Slow call ratio
New FallBackController
@RestController
@Slf4j
public class FallBackController {
@RequestMapping("/fallBack1")
public String fallBack1(a){
try {
log.info(FallBack1 executes business logic);
// Simulate service time
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "fallBack1"; }}Copy the code
New Demotion rule
The above configuration indicates that if there are [more than one request] within 1S, and the proportion of [response time > maximum RT] [requests >10%] in these requests, the fuse will be triggered, and the real method will not be called for the next 10s, and the degraded method will be directly used.
For example, maximum RT=900, ratio threshold =0.1, fusing duration =10, minimum number of requests =10
-
Case 1: There are 20 requests within 1 second, and only 10 requests have response time >900ms, then the slow call ratio =0.5, this situation will trigger the fuse.
-
Case 2: There are 20 requests within 1 second, only 1 request response time >900ms, then the slow call ratio =0.05, this case will not trigger the fuse.
-
Case 3: there are 8 requests within 1 second, and only 6 requests have response time >900ms, then the slow call ratio =0.75. This case will not trigger a fuse, because the minimum number of requests condition is not met.
We set the minimum number of requests to 1 in the experiment, because it is difficult to send two requests within 1 second manually, so it is best to set the minimum number of requests to 1 for effect.
8.11.2. Number of anomalies
Add an exception to the method
New fallBack3 method in fallbackController.java class of shop-order-server project.
@RequestMapping("/fallBack3")
public String fallBack3(String name){
log.info(FallBack3 executes business logic);
if("xiaolin".equals(name)){
throw new RuntimeException();
}
return "fallBack3";
}
Copy the code
Configuring degradation Rules
Within 1s, there will be [more than 3 requests]. If more than 2 requests are abnormal, the fuse will be triggered. The fuse duration is 10 seconds.
test
8.12. Sentinel Hotspot Rule
Hot spots are frequently accessed data. Most of the time, we want to collect the Top K data with the highest access frequency in a certain hotspot data and restrict its access. Such as:
- Item ID is used as parameter. The ID of the most commonly purchased item in a period of time is counted and restricted.
- The user ID is a parameter that limits the user IDS that are frequently accessed within a period of time.
Hotspot parameter traffic limiting Collects statistics on hotspot parameters in the incoming parameters and implements traffic limiting for resource invocation containing hotspot parameters based on the configured traffic limiting threshold and mode. Hotspot parameter traffic limiting is a special kind of traffic control that only applies to resource calls containing hotspot parameters.
New HotSpotController
You must annotate the request method with @SentinelResource, otherwise the hotspot rule is invalid
@RestController
@Slf4j
public class HotSpotController {
@RequestMapping("/hotSpot1")
@SentinelResource(value = "hotSpot1")
public String hotSpot1(Long productId){
log.info("Access item number :{}",productId);
return "hotSpot1"; }}Copy the code
Adding a Hotspot Rule
Because we only have one parameter, the parameter index is 0.
Visit /hotSpot1 and edit the hotspot rules
Before editing a rule, make sure to visit /hotSpot1 first, otherwise the parameter rule cannot be added.
New Parameter Rule
test
Visit: http://localhost:8082/hotSpot1? ProductId =2, no matter how you access it.
Visit: http://localhost:8082/hotSpot1? ProductId =1, will be degraded after multiple accesses.
8.13. Sentinel Authorization Rules
In many cases, we need to determine whether a request is allowed to pass based on the source of the call. In this case, Sentinel can use source access control. Source access control Restricts access to resources based on their origin:
- If a whitelist is configured, the request can pass only when the request source is in the whitelist.
- If a blacklist is configured, the request source in the blacklist does not pass, and the rest of the requests pass.
Add a utility class that defines how to obtain request sources
@Component
public class RequestOriginParserDefinition implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest request) {
/** * Define where to get the source information from the request * for example we could require all clients to carry the source information in the request header */
String serviceName = request.getParameter("serviceName");
returnserviceName; }}Copy the code
New AuthController
@RestController
@Slf4j
public class AuthController {
@RequestMapping("/auth1")
public String auth1(String serviceName){
log.info("Application :{}, access interface",serviceName);
return "auth1"; }}Copy the code
The new rules
test
Go to http://localhost:8082/auth1? ServiceName = The PC cannot be accessed
Go to http://localhost:8082/auth1? ServiceName =app accessible
8.14. System Rules
System protection rules control the incoming flow at the application level, and monitor application data from the total Load, RT, incoming QPS, CPU usage and threads of a single machine, so that the system can run at the maximum throughput and ensure the overall stability of the system.
System protection rules are application-wide, not resource-wide, and only apply to incoming traffic (traffic entering the application).
- Load (only for Linux or UNIX-like machines) : This function is triggered when load1 exceeds the threshold and the number of concurrent threads exceeds the system capacity.
- System protection. The system capacity is calculated by the system maxQps * minRt. The reference values are typically CPU cores * 2.5.
- RT: System protection is triggered when the average RT of all incoming traffic on a single machine reaches a threshold, in milliseconds.
- Number of threads: System protection is triggered when the number of concurrent threads for all incoming traffic on a single machine reaches a threshold.
- Inlet QPS: System protection is triggered when the QPS of all inlet flows on a single machine reaches the threshold.
- CPU usage: When the CPU usage of all incoming traffic on a single machine reaches the threshold, system protection is triggered.
8.15. Custom Exception Return
Common exceptions fall into these categories:
- FlowException: Flow limiting exception.
- DegradeException: Indicates a degraded exception.
- ParamFlowException: Parameter flow limiting is abnormal.
- AuthorityException: indicates an authorization exception.
- SystemBlockException: System load exception.
Define exception return handling classes in the shop-order-server project.
@Component
public class ExceptionHandlerPage implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
response.setContentType("application/json; charset=utf-8");
ResultData data = null;
if (e instanceof FlowException) {
data = new ResultData(-1."The interface is restricted.");
} else if (e instanceof DegradeException) {
data = new ResultData(-2."The interface was degraded.");
}else if (e instanceof ParamFlowException) {
data = new ResultData(-3."Abnormal parameter current limiting");
}else if (e instanceof AuthorityException) {
data = new ResultData(-4."Authorization exception");
}else if (e instanceof SystemBlockException) {
data = new ResultData(-5."The interface has been degraded..."); } response.getWriter().write(JSON.toJSONString(data)); }}@Data
@AllArgsConstructor// full parameter construction
@NoArgsConstructor
// No arguments
class ResultData {
private int code;
private String message;
}
Copy the code
8.16. Use of @SentinelResource
@SentinelResource is used to define resources and provides optional exception handling and Fallback configuration items. The main parameters are as follows:
attribute | role |
---|---|
value | Resource name, required (cannot be empty) |
entryType | It is an entry type. This parameter is optionalEntryType.OUT ) |
blockHandler/ blockHandlerClass |
blockHandler Corresponding processingBlockException The optional function name of the The access range of the blockHandler function must bepublic , the return type needs to match the original method, and the parameter type needs to match the original method and add an extra parameter at the end, of typeBlockException . The blockHandler function needs to be in the same class as the original method by default. You can specify if you want to use a function from another classblockHandlerClass Of the corresponding classClass Object, note that the corresponding function must be static, otherwise it cannot be parsed. |
fallback/ fallbackClass |
The optional fallback function name that provides fallback handling logic when an exception is thrown. The fallback function is available for all types of exceptions (exceptexceptionsToIgnore The type of exception that is excluded). Fallback function signature and position requirements:1. The return value type must be the same as that of the original function. 2. The parameter list of the method must be the same as the original function, or it can be an extra one Throwable Type to receive the corresponding exception.3. The fallback function must be in the same class as the original method by default. You can specify if you want to use a function from another class fallbackClass Of the corresponding classClass Object, note that the corresponding function must be static, otherwise it cannot be parsed. |
defaultFallback |
The default fallback function name, optional, is usually used for generic fallback logic (that is, it can be used for many services or methods). The default fallback function can be used for all types of exceptions (exceptexceptionsToIgnore The type of exception that is excluded). If both fallback and defaultFallback are configured, only fallback takes effect. DefaultFallback signature requirements:1. The return value type must be the same as that of the original function. 2. The method parameter list must be empty, or an extra parameter can be added Throwable Type to receive the corresponding exception.3. DefaultFallback must be in the same class as the original method by default. You can specify if you want to use a function from another class fallbackClass Of the corresponding classClass Object, note that the corresponding function must be static, otherwise it cannot be parsed. |
exceptionsToIgnore |
Used to specify which exceptions are excluded and will not be counted in the exception count or in fallback logic, but will be thrown as is. |
A method performed directly after limiting or downgrading.
8.17. Sentinel Rule Persistence
As we’ve already seen, Dashboard can be used to set up various rules for each Sentinel client, but one problem is that these rules are stored in memory by default and are extremely unstable, so they need to be persisted.
The local file data source periodically polls the file for changes and reads the rules. This allows us to either update the rules locally by modifying the files directly or push the rules through the Sentinel console. Taking local file data source as an example, the push process is shown in the figure below:
The Sentinel console first pushes the rules to the client via the API and updates them to memory. The registered write data source then saves the new rules to a local file.
Write processing classes
public class FilePersistence implements InitFunc {
@Value("${spring.application.name}")
private String appcationName;
@Override
public void init(a) throws Exception {
String ruleDir = System.getProperty("user.home") + "/sentinel-rules/" + appcationName;
String flowRulePath = ruleDir + "/flow-rule.json";
String degradeRulePath = ruleDir + "/degrade-rule.json";
String systemRulePath = ruleDir + "/system-rule.json";
String authorityRulePath = ruleDir + "/authority-rule.json";
String paramFlowRulePath = ruleDir + "/param-flow-rule.json";
this.mkdirIfNotExits(ruleDir);
this.createFileIfNotExits(flowRulePath);
this.createFileIfNotExits(degradeRulePath);
this.createFileIfNotExits(systemRulePath);
this.createFileIfNotExits(authorityRulePath);
this.createFileIfNotExits(paramFlowRulePath);
// Flow control rule
ReadableDataSource<String, List<FlowRule>> flowRuleRDS = new FileRefreshableDataSource<>(
flowRulePath,
flowRuleListParser
);
FlowRuleManager.register2Property(flowRuleRDS.getProperty());
WritableDataSource<List<FlowRule>> flowRuleWDS = new FileWritableDataSource<>(
flowRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);
// Demote rule
ReadableDataSource<String, List<DegradeRule>> degradeRuleRDS = new FileRefreshableDataSource<>(
degradeRulePath,
degradeRuleListParser
);
DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
WritableDataSource<List<DegradeRule>> degradeRuleWDS = new FileWritableDataSource<>(
degradeRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);
// System rules
ReadableDataSource<String, List<SystemRule>> systemRuleRDS = new FileRefreshableDataSource<>(
systemRulePath,
systemRuleListParser
);
SystemRuleManager.register2Property(systemRuleRDS.getProperty());
WritableDataSource<List<SystemRule>> systemRuleWDS = new FileWritableDataSource<>(
systemRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);
// Authorization rules
ReadableDataSource<String, List<AuthorityRule>> authorityRuleRDS = new FileRefreshableDataSource<>(
authorityRulePath,
authorityRuleListParser
);
AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
WritableDataSource<List<AuthorityRule>> authorityRuleWDS = new FileWritableDataSource<>(
authorityRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);
// Hotspot parameter rules
ReadableDataSource<String, List<ParamFlowRule>> paramFlowRuleRDS = new FileRefreshableDataSource<>(
paramFlowRulePath,
paramFlowRuleListParser
);
ParamFlowRuleManager.register2Property(paramFlowRuleRDS.getProperty());
WritableDataSource<List<ParamFlowRule>> paramFlowRuleWDS = new FileWritableDataSource<>(
paramFlowRulePath,
this::encodeJson
);
ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);
}
private Converter<String, List<FlowRule>> flowRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<FlowRule>>() {
}
);
private Converter<String, List<DegradeRule>> degradeRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<DegradeRule>>() {
}
);
private Converter<String, List<SystemRule>> systemRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<SystemRule>>() {
}
);
private Converter<String, List<AuthorityRule>> authorityRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<AuthorityRule>>() {
}
);
private Converter<String, List<ParamFlowRule>> paramFlowRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<ParamFlowRule>>() {
}
);
private void mkdirIfNotExits(String filePath) throws IOException {
File file = new File(filePath);
if (!file.exists()) {
file.mkdirs();
}
}
private void createFileIfNotExits(String filePath) throws IOException {
File file = new File(filePath);
if (!file.exists()) {
file.createNewFile();
}
}
private <T> String encodeJson(T t) {
returnJSON.toJSONString(t); }}Copy the code
After we restart, we find that the configured rule is still in, indicating that the persistence is successful!