Spring Cloud Gateway supports dynamic expansion limiting

Before sharing an article , "Spring Cloud Gateway native interface limiting how to play" , the core is dependent on Spring Cloud Gateway provides a default current limiting filter to achieve

Lack of native RequestRateLimiter

  • Configuration
spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: lb://pigx-upms
        order: 10000
        predicates:
        - Path=/admin/**
        filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 1  
            redis-rate-limiter.burstCapacity: 3
            key-resolver: "#{@remoteAddrKeyResolver}" #SPEL表达式去的对应的bean
        - StripPrefix=1
复制代码
  • RequestRateLimiterGatewayFilterFactory
public GatewayFilter apply(Config config) {
	KeyResolver resolver = getOrDefault(config.keyResolver, defaultKeyResolver);
	RateLimiter<Object> limiter = getOrDefault(config.rateLimiter,
			defaultRateLimiter);
	boolean denyEmpty = getOrDefault(config.denyEmptyKey, this.denyEmptyKey);
	HttpStatusHolder emptyKeyStatus = HttpStatusHolder
			.parse(getOrDefault(config.emptyKeyStatus, this.emptyKeyStatusCode));

	return (exchange, chain) -> {
				return exchange.getResponse().setComplete();
			});
		});
	};
}
复制代码
  • In the actual production process, we will not meet our needs

    Routing information is stored in the production database persistence or distribution center, RequestRateLimiterGatewayFilterFactoryand not as persistent changes dynamically changing data limiting parameters, it can not be done in real time to change the threshold value according to the traffic flow

Sentinel Spring Cloud Gateway flow control support

What Sentinel that?

With the stability between the popular micro-services, services, and services is becoming increasingly important. Sentinel to flow as the starting point, the flow control, fuse downgrade, the dimension of the system load protection to protect the stability of services, distributed system flow Defense soldiers.
From the start of version 1.6.0, Sentinel offers Spring Cloud Gateway adapter module, two resources can provide current limiting dimensions: route dimensions: the routing entries configured in the Spring configuration file, the corresponding resource called Custom routeId API dimensions: the user can use the Sentinel API provided from the API to define some packets

pom-dependent

<!--Spring Cloud Alibaba 封装的 sentinel 模块-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>

<!--使用nacos 保存限流规则-->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
复制代码

And configure the local routing rules data source sentinel

spring:
  application:
    name: sentinel-spring-cloud-gateway
  cloud:
    gateway:
      enabled: true
      discovery:
        locator:
          lower-case-service-id: true
      routes:
      - id: pigx_route
        uri: https://api.readhub.cn
        predicates:
        - Path=/topic/**
    sentinel:
      datasource.ds1.nacos:
        server-addr: 127.0.0.1:8848
        data-id: gw-flow
        group-id: DEFAULT_GROUP
        ruleType: gw-api-group
      filter:
        enabled: true
复制代码

Configuring limiting policies nacos data source

  • Common constants limiting policy
以客户端IP作为限流因子
public static final int PARAM_PARSE_STRATEGY_CLIENT_IP = 0;
以客户端HOST作为限流因子
public static final int PARAM_PARSE_STRATEGY_HOST = 1;
以客户端HEADER参数作为限流因子
public static final int PARAM_PARSE_STRATEGY_HEADER = 2;
以客户端请求参数作为限流因子
public static final int PARAM_PARSE_STRATEGY_URL_PARAM = 3;
以客户端请求Cookie作为限流因子
public static final int PARAM_PARSE_STRATEGY_COOKIE = 4;
复制代码
  • The core source code parsing SentinelGatewayFilter

Gateway sentinel extended by filters, by selecting different GatewayParamParsertoo limiting factor processing request and the data source is compared source arranged as follows:

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);

    Mono<Void> asyncResult = chain.filter(exchange);
    if (route != null) {
        String routeId = route.getId();
        Object[] params = paramParser.parseParameterFor(routeId, exchange,
            r -> r.getResourceMode() == SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID);
        String origin = Optional.ofNullable(GatewayCallbackManager.getRequestOriginParser())
            .map(f -> f.apply(exchange))
            .orElse("");
        asyncResult = asyncResult.transform(
            new SentinelReactorTransformer<>(new EntryConfig(routeId, EntryType.IN,
                1, params, new ContextConfig(contextName(routeId), origin)))
        );
    }

    Set<String> matchingApis = pickMatchingApiDefinitions(exchange);
    for (String apiName : matchingApis) {
        Object[] params = paramParser.parseParameterFor(apiName, exchange,
            r -> r.getResourceMode() == SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME);
        asyncResult = asyncResult.transform(
            new SentinelReactorTransformer<>(new EntryConfig(apiName, EntryType.IN, 1, params))
        );
    }

    return asyncResult;
}

复制代码

Demonstration effect

  • More nacos configured by only 5 per request, we use jmeter 4.0to test concurrency 10 threads

  • It can be proved by the sentinel FIG limiting credible

Dynamic modification of limiting parameters

  • sentinel-datasource-nacos As sentinel data source, and can be refreshed limiting parameter as a threshold value from the real-time management table nacos
  • Currently sentinel dashboard 1.6.2 yet to achieve the graphical control flow control gateway, 1.7.0will increase this feature

to sum up

Welcome Follow us get more fun JavaEE practice

Guess you like

Origin juejin.im/post/5d3f95a8f265da039e12959d