1, Introduction
Zuul 2. In May 2019, Netflix finally opened the zuul 2.0 version that supports asynchronous call mode, which can be said to be called for thousands of times. But Spring Cloud no longer integrates zuul2 X, then it's time to learn about Spring Cloud Gateway
Spring Cloud Gateway is an API gateway built on the spring ecosystem, including Spring 5, Spring Boot2 and Project Reactor. Spring Cloud Gateway aims to provide a simple and effective way to route to APIs and provide them with cross domain concerns, such as security, monitoring / indicators, current limiting, etc. Because Spring 5.0 supports Netty and Http2, while Spring Boot2 0 supports Spring 5.0, so it is natural that Spring Cloud Gateway supports Netty and Http2.
The gateway shall have the following functions:
- Performance: API, high availability, load balancing, fault tolerance mechanism.
- Security: authority, identity authentication, desensitization, traffic cleaning, back-end signature (to ensure the trusted call of the whole link), blacklist (restriction of illegal call).
- Log: once the log record is distributed, full link tracking is essential.
- Cache: data cache.
- Monitoring: record request response data, API time-consuming analysis and performance monitoring.
- Current limiting: flow control, peak staggering flow control, and multiple current limiting rules can be defined.
- Grayscale: Online grayscale deployment can reduce risk.
- Routing: dynamic routing rules.
2, Core concept
Route: route is the most basic part of the gateway. The route information consists of ID, target URI, a set of assertions and a set of filters. If the asserted route is true, the requested URI and configuration match.
Predicate: an assertion function in Java 8. The input type of the assertion function in the Spring Cloud Gateway is ServerWebExchange in the Spring 5.0 framework. The assertion function in Spring Cloud Gateway allows developers to define and match any information from Http Request, such as request header and parameters.
Filter: a standard Spring Web Filter. There are two types of filters in Spring Cloud Gateway: Gateway Filter and Global Filter. The filter processes requests and responses.
3, Code case
3.1 pom dependency
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
3.2 configuration items
spring: application : name: gateway-server cloud: gateway: #Routing rules routes: - id: gateway #Route ID, unique uri: lb:CONSUMER #Destination URI, the address of the route to the microservice predicates: #Assertion (judgment condition) - Path=/consumer/** #4. Change the request of the corresponding URL and append the matching request to the target URI eureka: client: service-url: defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/,http://eureka7001.com:7001/eureka/
3.3 startup items
There is no need to configure other annotations for startup items
4, Routing rules
4.1,path
spring: application : name : gateway-server #apply name cloud : gateway : #Routing rules routes : - id : product-service #Route ID, unique uri: http://localhost:7878 / # destination URI, which routes to the address of the microservice predicates: #Assertion (judgment condition) - Path=/product/** #Match the request of the corresponding URL, and append the matched request after the target URI
- request http://localhost:9999/product/1 Will be routed to http://localhost:7878/product/1
4.2,Query
spring: application: name : gateway-server #Application name cloud: gateway : #Routing rule routes: - id : product-service #Route ID, unique uri: http://localhost:7078 / # destination URI, the address routed to the microservice predicates : #Assertion (judgment condition) #-Query=token #Match the request containing token in the request reference - Query=token,abc. #The matching request parameter contains token and its parameter value satisfies the regular expression abc Request for
- Query=token: for example, http://localhost:9000/product/1?token=123
- Query=token,abc. : For example, http://localhost:9000/product/1?token=abc1
4.3,Method
spring: application : name : gateway-server #Application name cloud: gateway : #Routing rule routes: - id : product-service #Route ID, unique uri: http://localhost:7070 / # destination URI, the address of the route to the microservice predicates : #Assertion (judgment condition) - Method=GET #Match any GET request
4.4,Datetime
spring: application : name : gateway-server #Application name cloud: gateway : #Routing rules: - id : product-service #Route ID, unique uri: http://localhost:7870 / # destination URI, the address of the route to the microservice predicates : #Assertion (judgment condition) #Matching requests after 2820-82-0220:20:28 Shanghai time, China - After=2828-82-82T28:20:20.888+88:88[ Asia/Shanghai]
4.5,RemoteAddr
spring: application : name : gateway-server #Application name cloud: gateway : #Routing rules: - id : product-service #Route ID, unique uri : http://localhost:7078 / # destination URI, the address of the route to the microservice predicates: #Assertion (judgment condition) - RemoteAddr=192.168.10.1/0 #The matching remote address request is the request of RemoteAddr, and 0 represents the subnet mask
4.6,Header
spring: application : name : gateway-server #Application name cloud: gateway : #Routing rules: - id : product-service #Route ID, unique uri : http://localhost:7078 / # destination URI, the address of the route to the microservice predicates: #Assertion (judgment condition) #A request whose matching request header contains X-Request-Id and whose value matches the regular expression \ d + - Header=X-Request-Id, \d+
5, Dynamic routing
5.1. Add dependency
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
5.2 configuration items
Add eureka configuration item
eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka/
5.3. Get routes through the registry
Change uri to uri: lb://CONSUMER/ # lb: / / service name
5.4 forwarding by service name
cloud : gateway : discovery : locator : #Whether it is combined with the service discovery component and forwarded to the specific service instance through serviceId. enabled: true #Enable routing rules based on service discovery lower-case-service-id: true #Convert service name to lowercase
6, Filter
Spring Cloud Gateway is divided into GatewayFilter and GlobalFilter according to the scope of action. The differences between the two are as follows:
GatewayFilter: gateway filter, which needs to pass spring cloud. routes. Filters are configured under specific routes and only work on the current route or through spring cloud . Default filters are configured globally and act on all routes.
GlobalFilter: Global filter, which does not need to be configured in the configuration file, acts on all routes. Finally, it is packaged into a filter recognizable by GatewayFilterChain through the GatewayFilterAdapter. It is the core filter that converts the URI of the request service and route into the request address of the real service. It does not need to be loaded during system initialization and acts on each route.
6.1,GatewayFilter
6.1.1 path filter
6.1.1.1. Rewritepathgatewayfilterfactory (rewrite request path)
The RewritePath gateway filter factory uses path regular expression parameters and replacement parameters, and uses Java regular expressions to rewrite flexibly.
filters: #Gateway filter #Rewrite / API gateway / product/1 to / product/1 - RewritePath=/api-gateway(?<segment>/?.*),$\{segment}
6.1.1.2. Prefixpathgatewayfilterfactory (add the specified prefix to the request path)
The PrefixPath gateway filter factory is a matching URI.
filters: #Gateway filter #Rewrite / 1 to / product/1 - PrefixPath=/product
6.1.1.3 stripprefixgatewayfilterfactory (number of stripping paths)
The StripPrefix gateway filter factory adopts a parameter StripPrefix, which indicates the number of paths stripped from the request before sending the request to the downstream.
filters: #Gateway filter #Rewrite / api/123/product/1 to / product/1 - StripPrefix=2
6.1.1.4. SetPathGatewayFilterFactory (templated path segment)
The SetPath gateway filter factory takes path template parameters. It provides a simple method to manipulate the request path by allowing templated path segments. It uses the uri template in the spring framework and allows multiple matching segments.
predicates: #Assertion (judgment condition) #The request matching the corresponding URI is appended after the target URI - Path=/api/product/{sagment} filters: #Gateway filter #Rewrite / api/product/1 to / product/1 - SetPath=/product/{segment}
6.1.2 Parameter filter
AddRequestParameter the gateway filter factory adds the specified parameter to the matching downstream request.
predicates: #Assertion (judgment condition) #Match the request of the corresponding UR worker, and append the matched request after the target URI - Path=/api-gateway/** filters: #Gateway filter #Rewrite / API gateway / production / 1 to / product/1 - RewritePath=/api-gateway(?<segment>/?.*),$\{segment} #Add flag=1 in downstream request - AddRequestParameter=flag,1
6.1.3 Status filter
The Setstatus gateway filter factory takes a single status parameter, which must be a valid Spring HttpStatus. It can be an integer 404 or an enumeration not_ String representation of found.
filters : #Gateway filter #In any case, the HTTP status of the response will be set to 404 - SetStatus=404 #404 or corresponding calibration NOT_FOUND
6.2,GlobalFilter
The global filter does not need to be configured in the configuration file and acts on all routes. Finally, it is packaged into a filter recognizable by the GatewayFilterChain through the GatewayFilterAdapter. It is the core filter that converts the URI of the requested service and route into the request address of the real service. It does not need to be loaded during system initialization and acts on each route.
6.3. Custom filter
Even though Spring Cloud Gateway comes with many practical GatewayFilter Factory, Gateway Filter and Global Filter, we still hope to customize our own filters and implement some operations in many scenarios.
6.3.1 gateway filter
Custom gateway filters need to implement the following two interfaces: gatewayfilter and ordered
6.3.1.1. Define gateway filter
CustomGatewayFilter.java
public class CustomGatewayFilter implements GatewayFilter,Ordered { /* *Filter business logic * param exchange * param chain * @return */ @override public Mono<Void> filter(ServerWebExchange exchange,GatewayFilterChain chain) { System.out.println("Custom gateway filter executed"); return chain.filter (exchange); //Continue down } /** *Filter execution order: the smaller the value, the higher the priority* * @return */ @Override public int getOrder(){ return 0; } }
6.3.1.2 registration filter
@Configuration public class GatewayRoutesConfiguration{ @Bean public RouteLocator routeLocator(RouteLocatorBuilder builder) { return builder.routes().route(r -> r //Assertion (judgment condition) .path("/product/**") //Destination URI, the address of the route to the microservice .uri("lb://product-service" ) //Register custom gateway filters .filters(new CustomGatewayFilter()) //Route ID, unique .id("product-service") ) .build(); } }
6.3.2 global filter
To customize a global filter, you need to implement the following two interfaces: globalfilter and ordered. Through the global filter, the functions of permission verification and security verification can be realized.
6.3.2.1 define filter
Implement the specified interface and add @ component annotation.
Global filters do not need to be registered
CustomGlobalFilter.java
@Component public class CustomGlobalFilter implements GlobalFilter,Ordered { /* *Filter business logic * param exchange * param chain * @return */ @Override public Mono<Void> filter(ServerWebExchange exchange,GatewayFilterChain chain) { System.out.println("The custom global filter is executed"); return chain.filter (exchange) ; //Continue down } /** *Filter execution order: the smaller the teaching value, the higher the priority * return */ @Override public int getordef(){ return 0 ; } }
7, Current limiting
Spring Cloud Gateway officially provides a RequestRateLimiterGatewayFilterFactory filter factory, which uses Redis and Lua scripts to implement the token bucket.
7.1 configuration
rely on
The new version of redis uses pool2 connection pool
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>
Configuration item
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 a SpEL expression to reference bean s by name redis: timeout: 10000 #Connection timeout host: 127.0.0.1 #Redis server address port: 6379 #Redis server port password: root #Redis server password database: 0 #Select which library, default 0 Library lettuce: pool: max-active: 1024 #Maximum connections, 8 by default max-wait: 10000 #Maximum connection blocking waiting time, in milliseconds, default - 1 max-idle: 200 #Maximum idle connection, default 8 min-idle: 5 #Minimum idle connection, default 4
You also need a bean:pathKeyResolver, which is written differently according to different current limiting methods
7.2 current limiting mode
7.2.1 URL current limit
bean:pathKeyResolver
@Configuration public class KeyResolverConfiguration { @Bean public KeyResolver pathKeyResolver(){ return exchange -> Mono.just(exchange.getRequest().getURI( ).getPath()); } }
7.2.2 parameter current limiting
bean:parameterKeyResolver
@Bean public KeyResolver parameterKeyResolver(){ return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst( k: "userId")); }
7.2.3 IP current limiting
bean:ipKeyResolver
@Bean public KeyResolver ipKeyResolver() { return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName()); }