Continue today with the Spring Cloud Gateway fuses and downgrades.

In a distributed system, the gateway as the flow of the entrance, so there will be a large number of requests into the gateway, with the rest of the service invocation, the rest of the service is inevitable there will be a call fails (timeout, abnormal), failure can’t let requests are stacked on the gateway, need to fail fast and returned to the client, want to achieve this requirement, it must be the gateway for fusing, degraded operation.

The concept is introduced

Service degradation: Proper coordination of the system’s limited resources

  • Concept: Service degradation refers to that some services and pages are strategically not processed or handled in a simple way according to the actual service usage and traffic when the server pressure increases sharply, so as to release server resources and ensure the normal and efficient operation of core services.
  • Reason: The server has limited resources and unlimited requests. During the peak concurrency period, the overall service performance may be affected. In serious cases, the system may break down and some important services may become unavailable. Therefore, in order to ensure the availability of core functional services during peak periods, some services need to be degraded. It can be understood as giving up small to protect large
  • Application scenario: Mainly used in microservice architecture. Generally, when the overall load of the microservice architecture exceeds the preset upper threshold (related to the configuration performance of the server), or the upcoming traffic is expected to exceed the preset threshold (such as double-11, 6.18 and other activities or seconds kill activities).
  • Service relegation from the load of the whole system, and consider to some load will be high, in order to prevent some function (business scenario) overload or slow response in load, in its internal put on some non-core interface and data requests, and direct returns a prepared ahead of timefallbackError processing information. In this way, although it provides a lossy service, it ensures the stability and availability of the whole system.
  • Issues to consider:
    • Distinguish between services that are core and those that are not
    • Demotion strategy (handling method, usually how to give user friendly prompts or actions)
    • Automatic downgrade or manual downgrade

Microservices Architecture – Service degradation is covered in great detail.

Service fuses: link self-protection mechanism against avalanche effect. Can be viewed as a special case of downgrade

  • Concept: A link protection mechanism against microservice avalanche effects, similar to stock market, fuse
  • Reason: Data interaction between microservices is done through remote calls. Service invoking A service, A service to invoke the service B c, sometime on the link to the service c call response time is too long, or service is not available, c as the growth of the time, is more and more on service call c, then the service c collapsed, but the link call, the call to service B continues to increase, and then collapse service B, then A collapse, also cause an avalanche effect
  • Service circuit breaker is a micro – service link protection mechanism against avalanche effect. In a high-voltage circuit, for example, if the voltage in one place is too high, the fuse will blow and protect the circuit. Similarly, circuit breakers play a similar role in microservices architecture. When a microservice on the invocation link is unavailable or the response time is too long, the service is fused. The microservice on this node is no longer invoked, and an incorrect response message is quickly returned. When detecting that the microservice invocation response of this node is normal, the call link is restored.
  • The function of a service fuse is similar to that of a fuse in our home. When a service becomes unavailable or the response times out, the call to the service is temporarily stopped to prevent the whole system from avalanche.

In the Spring Cloud framework, circuit breakers are implemented through Hystrix. Hystrix monitors the status of calls between microservices, and when the number of failed calls reaches a certain threshold, the default is 20 failed calls within five seconds, the circuit breaker is activated.

  • Application scenario: In the microservice architecture, multiple microservices are used when they call each other

  • Issues to consider:

    • How do dependent service objects become unstable
    • How to quickly recover a dependent object after a failure, and how to detect whether a dependent object is recovered

Service degradation and service circuit breaker

  • The trigger causes are different. Service fuses are caused by a service on the link, and service degradation is caused by the overall load
  • The management target level is different. Service circuit breaker is a framework level process, while service degradation is a business level process
  • The implementation methods are different. The service circuit breaker is generally self-fusing and recovery. Service degradation is equivalent to manual control
  • Trigger reason The fusing of different services is generally caused by a service (downstream service) fault, while service degradation is generally considered from the overall load.

In one sentence

Service circuit breaker is a kind of insurance measure against system service avalanche, which is given as a special downgrade measure. Service degradation, on the other hand, is a broader concept, mainly the rational allocation of resources to the system as a whole to cope with the stress.

Service circuit breaker is a special case of service degradation, which is taken to prevent service avalanche. If the system is abnormal, delayed, or has too much traffic, the service circuit breaker is triggered. Link circuit breaker is triggered, and the system returns to the bottom. This is a local insurance policy.

Service degradation is a reasonable allocation of system resources. Distinguish between core and non-core services. Estimate the latency of access to a service, exceptions, etc. This is a global consideration, managing the overall load of the system.

The code field

The above related concepts come from: Service degradation and service circuit breaker difference – Zhihu.com

With these concepts in mind, let’s take a look at how to configure circuit breaker degradation in Spring Cloud Gateway combat.

1.pom.xmlAdd to fileHystrixRely on

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
Copy the code

Note that there are issues with the Spring Cloud version, which may not be successful. I have the Hoxton.SR6 version

2,application.ymlconfiguration

server:
  port: 8080

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: cloud-gateway
          uri: http://localhost:8080
          predicates:
            - Path=/ytb/**
          filters:
            - StripPrefix=1
            # demote configuration
            - name: Hystrix
              args:
                name: testOne
                Degrade the address of the interface
                fallbackUri: forward:/fallback
# for global configuration
hystrix:
  command:
    default:
      execution:
        timeout:
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 3000
    # Set a timeout for the individual Hystrix commandKey
    testOne:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000
Copy the code

The configuration has an optional parameter fallbackUri. Currently, only forward urIs are supported. If a fuse is triggered, the request is forwarded to the controller corresponding to the URI. The controller can be a custom Fallback interface. Also can be custom Handler, you need to implement interface org. Springframework. Web. Reactive. The function. The server HandlerFunction < T extends ServerResponse >.

The interface timeout period is also set, that is, if the interface response exceeds this time, the fuse will be triggered.

3,fallbackUriThe configured degraded address interface

@RestController
public class FallbackController {

    @GetMapping("/fallback")
    public Map<String, Object> fallback(a) {
        Map<String, Object> map = new HashMap<>();
        map.put("code"."error");
        map.put("msg"."Service temporarily unavailable");
        returnmap; }}Copy the code

4. Test interface

@RestController
public class TestController {

    @GetMapping("/timeout")
    public String timeout(a){
        try {
            Thread.sleep(5000);
            System.out.println("Analog interface timed out");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Request successful"; }}Copy the code

Thread.sleep(5000) is used to simulate an interface call timeout.

Then you can start the project, visit this address localhost: 8080 / ytb/timeout

The following result is returned:

Since we set the timeout to 3 seconds and the interface to sleep 5 seconds, degraded fuses were triggered.

In this case, we modify the timeout time in application.yml to 6 seconds

There will be no downgrade circuit breakers this time.

5. CustomizeHandlerway

As mentioned earlier, the controller can be a custom Fallback interface; It can also be a custom Handler. I’m going to post Handler code

Route configuration:

@Configuration
public class RouterFunctionConfiguration
{
    @Autowired
    private HystrixFallbackHandler hystrixFallbackHandler;

    @SuppressWarnings("rawtypes")
    @Bean
    public RouterFunction routerFunction(a)
    {
        return RouterFunctions
                .route(RequestPredicates.path("/fallback").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), hystrixFallbackHandler); }}Copy the code

Custom Handler:

@Component
public class HystrixFallbackHandler implements HandlerFunction<ServerResponse>
{
    private static final Logger log = LoggerFactory.getLogger(HystrixFallbackHandler.class);

    @Override
    public Mono<ServerResponse> handle(ServerRequest serverRequest)
    {
        Optional<Object> originalUris = serverRequest.attribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
        originalUris.ifPresent(originalUri -> log.error("Gateway execution request :{} failed, Hystrix service degraded processing", originalUri));
        return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR.value()).contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(JSON.toJSONString("{"error":"Service has been downgraded to a circuit breaker"}"))); }}Copy the code

Start the gateway service GatewayApplication. Java, access localhost: 8080 / ytb/timeout test again, will return to service has to be demoted fusing found.

This concludes the article. It may be added later