This is the 20th day of my participation in the August Text Challenge.More challenges in August
The routing configuration
There are three ways to configure urIs in the Spring Cloud Gateway, including
- Websocket configuration mode
spring:
cloud:
gateway:
routes:
- id: demo-api
uri: ws://localhost:9090/
predicates:
- Path=/api/**
Copy the code
- HTTP address configuration mode
spring:
cloud:
gateway:
routes:
- id: demo-api
uri: http://localhost:9090/
predicates:
- Path=/api/**
Copy the code
- Registry configuration mode
spring:
cloud:
gateway:
routes:
- id: demo-api
uri: lb://demo-api
predicates:
- Path=/api/**
Copy the code
Current limiting configuration
As the name suggests, limiting traffic is restricting traffic. Through current limiting, we can control the QPS of the system well, so as to achieve the purpose of protecting the system. Common traffic limiting algorithms are the counter algorithm, Leaky Bucket algorithm, and Token Bucket algorithm.
Spring Cloud Gateway official provides RequestRateLimiterGatewayFilterFactory filter factory, using Redis and Lua scripts for the way the token bucket.
1. Add dependencies
<! -- Spring Data Redis Reactive -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
Copy the code
2. Traffic limiting rules: Limit traffic according to URI
spring:
redis:
host: localhost
port: 6379
password:
cloud:
gateway:
routes:
# System module
- id: demo-system
uri: lb://demo-system
predicates:
- Path=/system/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1 # Token bucket fill rate per second
redis-rate-limiter.burstCapacity: 2 Total token bucket capacity
key-resolver: "#{@pathKeyResolver}" Use SpEL expressions to reference beans by name
Copy the code
prompt
StripPrefix=1: indicates that the gateway automatically intercepts the prefix when forwarding to the service module.
3. Write URI traffic limiting rule configuration classes
package com.demo.gateway.config;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;
/** * Traffic limiting rule configuration class */
@Configuration
public class KeyResolverConfiguration
{
@Bean
public KeyResolver pathKeyResolver(a)
{
returnexchange -> Mono.just(exchange.getRequest().getURI().getPath()); }}Copy the code
4, test validation current-limiting starting gateway service DemoGatewayApplication. Java and system service DemoSystemApplication. Java. Because the gateway service has authentication, you can set the whitelist /system/** to test. If multiple requests are made, HTTP ERROR 429 will be returned, and two keys will be operated in Redis at the same time, indicating that traffic limiting is successful.
request_rate_limiter.{xxx}.timestamp
request_rate_limiter.{xxx}.tokens
Copy the code
Other traffic limiting rules
- Parameter current limiting:
key-resolver: "#{@parameterKeyResolver}"
@Bean
public KeyResolver parameterKeyResolver(a)
{
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
}
Copy the code
- IP current limit:
key-resolver: "#{@ipKeyResolver}"
@Bean
public KeyResolver ipKeyResolver(a)
{
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}
Copy the code
Fusing the drop
1. Add dependencies.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
Copy the code
2. The configuration requires fuse downgrading service
spring:
redis:
host: localhost
port: 6379Password: cloud: gateway: routes: # System module - id: demo-system URI: lb://demo-system
predicates:
- Path=/system/** filters: -stripprefix =1 # degrade configuration - name: Hystrix args: name: default # degrade interface address fallbackUri: 'forward:/fallback'Copy the code
prompt
The above configuration contains a Hystrix filter that applies Hystrix fuses and degradations, wraps the request named RouteHystrixCommand as a fallback, Routehystrixobservablecommand inherits Hystrix Observablecommand, which contains Hystrix circuit breaker core functions such as circuit breaking, resource isolation and degradation. When the request forwarded by the gateway is faulty, the gateway can quickly fail it and execute specific failure logic. Protect gateway security.
The configuration has an optional parameter fallbackUri. Currently, only forward urIs are supported. If the service is degraded, the request is forwarded to the controller corresponding to the URI. The controller can be a custom Fallback interface. Also can make custom Handler, it is necessary to implement the interface org. Springframework. Web. Reactive. The function. The server HandlerFunction < T extends ServerResponse >.
3. Add the return information of fusible downgrading
package com.demo.gateway.handler;
import com.alibaba.fastjson.JSON;
import com.demo.common.core.domain.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.HandlerFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import java.util.Optional;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR;
/** ** fuse downgrade processing ** /
@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(R.fail("Service has been downgraded to a circuit breaker.")))); }}Copy the code
Route configuration information plus a controller method to handle redirected /fallback requests
package com.demo.gateway.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import com.demo.gateway.handler.HystrixFallbackHandler;
import com.demo.gateway.handler.ValidateCodeHandler;
/** * Route configuration information ** /
@Configuration
public class RouterFunctionConfiguration
{
@Autowired
private HystrixFallbackHandler hystrixFallbackHandler;
@Autowired
private ValidateCodeHandler validateCodeHandler;
@SuppressWarnings("rawtypes")
@Bean
public RouterFunction routerFunction(a)
{
return RouterFunctions
.route(RequestPredicates.path("/fallback").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
hystrixFallbackHandler)
.andRoute(RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), validateCodeHandler); }}Copy the code
4, fusing the drop test services gateway service DemoGatewayApplication. Java, access/system / * * in the test, find return service has to be demoted fusing, said the relegation success.