1. Fusing down: in a distributed system, the gateway as traffic entrance, a large number of requests into the gateway, back-end remote system calls, or service by the back-end service would inevitably produce call fails (timeout or abnormal), failure can’t let requests are stacked on the gateway, need to fail fast and return back, this would require the fuse on the gateway and degraded operation.

2. Traffic limiting: There are a large number of requests on the gateway. Traffic limiting for a specified service greatly improves the availability and stability of the service. Once the speed limit is reached, the service can be denied, queued or waited, and degraded.

3. Integrated fusing and current limiting of Spring Cloud Gateway

1. Integrate Hystrix fuse degrade based on the previous blog code, reference Hystrix dependencies, add fuse degrade configuration under filters, set the route to return after the degrade, and configure semaphore isolation by default and 3-second active timeout

<! - fusing, relegation - > < the dependency > < groupId > org. Springframework. Cloud < / groupId > <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> 12345Copy the code

application.yml

filters:
Fuse downgrading configuration
- name: Hystrix
  args:
    name : default
    fallbackUri: 'forward:/defaultfallback'

# Hystrix semaphore isolation, automatic timeout after 3 seconds
hystrix:
  command:
    default:
      execution:
        isolation:
          strategy: SEMAPHORE
          thread:
            timeoutInMilliseconds: 3000
  shareSecurityContext: true
1234567891011121314151617Copy the code

Create a new RestController for DefaultHystrixController as follows:

@restController Public Class DefaultHystrixController {@requestMapping ("/defaultfallback")
    public Map<String,String> defaultfallback(){
        System.out.println("Degrade operation...");
        Map<String,String> map = new HashMap<>();
        map.put("resultCode"."fail");
        map.put("resultMessage"."Abnormal service");
        map.put("resultObj"."null");
        returnmap; }} 12345678910111213141516Copy the code

Add a timeout method to the IndexController of the consumer-Service to make the thread sleep for 5 seconds, which is longer than the 3 seconds set in the gateway.

@RestController
public class IndexController {

    @RequestMapping("/hello")
    public String hello(String name){
        return "hi " + name;
    }

    @RequestMapping("/timeout")
    public String timeoutThread.sleep(2000) {try{// Hystrix3 timeout triggers fuse downgrade thread.sleep (2000); }catch (Exception e){ e.printStackTrace(); }return "timeout"; }} 12345678910111213141516171819Copy the code

Start the project, accesshttp://localhost:9999/consumer/timeout, the result is the following, triggering the downgrade



Change the gateway timeout configuration to 6000, that is, 6 seconds, restart the gateway, access againhttp://localhost:9999/consumer/timeout, the result returns normally, and Hystrix fuse degradation is set on the gateway, which can cover most scenarios where back-end services are unavailable

  • 2. Integrated traffic limiting. The Spring Cloud Gateway integrates Redis traffic limiting by default and can perform traffic limiting in different dimensions for different services, such as: IP traffic limiting, user traffic limiting, and interface traffic limiting This article demonstrates IP traffic limiting. Add a Redis dependency, KeyResolver, and configuration first, and start Redis
<! --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency> 12345Copy the code

Use KeyResolver to specify the Key for limiting traffic. Create a RateLimiterConfig class. The IP limiting code is as follows:

/** * @author zhuyu * @date 2019/1/15 */ @configuration public class RateLimiterConfig {@bean (value ="remoteAddrKeyResolver")
    public KeyResolver remoteAddrKeyResolver() {
        returnexchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()); }} 12345678910111213Copy the code

Add traffic limiting configuration under application.yml:

spring:
  redis:
    host: localhost
filters:
The filter name must be RequestRateLimiter
- name: RequestRateLimiter
  args:
    # Reference the Bean with the SpEL name, the same name as the Bean in the newly created RateLimiterConfig class above
    key-resolver: '#{@remoteAddrKeyResolver}'
    # Maximum number of accesses per second
    redis-rate-limiter.replenishRate: 20
    # Maximum token bucket capacity
    redis-rate-limiter.burstCapacity: 20
12345678910111213Copy the code

Filter name must be RequestRateLimiter redis-rate-limiter. ReplenishRate: Number of requests processed per second by the user redis-rate-limiter. BurstCapacity: replenishRate: replenishRate: replenishRate: replenishRate: replenishRate: Number of requests processed per second by the user redis-rate-limiter. The capacity of the token bucket, the maximum number of requests allowed to be completed in one second key-resolver: references beans by name using SpEL

  • 3. Test whether the gateway achieves traffic limiting by using jMeter test tool. The test configuration is as follows: 100 threads, 2 cycles within 2 seconds, a total of 200 requests, request address:http://localhost:9999/consumer/hello?name=zy

Set the number of current limits for the first time to 2 and 10

redis-rate-limiter.replenishRate: 2

redis-rate-limiter.burstCapacity: 10

The test results were as follows: only 14 requests were returned, and all the others were rejected

Set the second traffic limit 20 and 20

redis-rate-limiter.replenishRate: 20

redis-rate-limiter.burstCapacity: 20

The test results are as follows: a large number of requests were responded to, and some were rejected

The key and value changes of Redis are given

You can also use user traffic limiting and interface traffic limiting. In this mode, the request path must carry the userId parameter

@Bean
KeyResolver userKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
}
1234Copy the code

The uri of the request address is used as the traffic limiting key

@Bean
KeyResolver apiKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getPath().value());
}
1234Copy the code

In real scenarios, the traffic limit adjustment depends on the configuration center. When websites are active, the traffic limit adjustment is dynamically adjusted. When new services come online, the configuration center performs dynamic routing

The code has been uploaded to the code cloud, source code, the version information used by the project is as follows:

- SpringBoot 2.0.6.RELEASE - SpringCloud finchley. SR2 12Copy the code

This paper links: https://blog.csdn.net/zhuyu19911016520/article/details/86499528