introduce
Spring Cloud Gateway is a gateway officially developed by spring based on Spring 5.0, Spring Boot 2.0, Project Reactor and other technologies. Spring Cloud Gateway aims to provide a simple and effective unified API routing management method for microservice architecture. As a gateway in the Spring Cloud ecosystem, the goal of Spring Cloud Gateway is to replace ZUUL. It not only provides a unified routing method, but also provides the basic functions of the gateway based on the Filter chain, such as security, monitoring / embedding point, current limiting, etc.
Create API gateway module
pom. Add related dependencies to XML
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
Two different routing configurations
Gateway provides two different ways to configure routing, one is through yml file, the other is through Java Bean. Let's introduce them respectively.
Using yml configuration
- In application Configure in YML:
server: port: 9201 service-url: user-service: http://localhost:8201 spring: cloud: gateway: routes: - id: path_route #ID of the route uri: ${service-url.user-service}/user/{id} #Route address after matching predicates: # Assert that the path matches the route - Path=/user/{id}
-
Start Eureka server, user service and API gateway services, and call the address to test: http://localhost:9201/user/1
-
We found that the request was routed to the path of user service: http://localhost:8201/user/1
Using Java Bean configuration
- Add relevant configuration classes and configure a RouteLocator object:
/** * Created by macro on 2019/9/24. */ @Configuration public class GatewayConfig { @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("path_route2", r -> r.path("/user/getByUsername") .uri("http://localhost:8201/user/getByUsername")) .build(); } }
-
Restart the API gateway service and call the address test: http://localhost:9201/user/getByUsername?username=macro
-
We found that the request was routed to the path of user service: http://localhost:8201/user/getByUsername?username=macro
Use of Route Predicate
Spring Cloud Gateway takes route matching as part of the Spring WebFlux HandlerMapping infrastructure. Spring Cloud Gateway includes many built-in route predict factories. All these predictions match the different attributes of the HTTP request. Multiple route predictors can be combined. Let's introduce some common route predictors.
Note: the configurations mentioned in predict are all in application predict Modify in the YML file and start the API gateway service with this configuration.
After Route Predicate
Requests after the specified time will match the route.
spring: cloud: gateway: routes: - id: after_route uri: ${service-url.user-service} predicates: - After=2019-09-24T16:30:00+08:00[Asia/Shanghai]
Before Route Predicate
Requests before the specified time will match the route.
spring: cloud: gateway: routes: - id: before_route uri: ${service-url.user-service} predicates: - Before=2019-09-24T16:30:00+08:00[Asia/Shanghai]
Between Route Predicate
Requests within the specified time interval will match the route.
spring: cloud: gateway: routes: - id: before_route uri: ${service-url.user-service} predicates: - Between=2019-09-24T16:30:00+08:00[Asia/Shanghai], 2019-09-25T16:30:00+08:00[Asia/Shanghai]
Cookie Route Predicate
Requests with the specified Cookie match the route.
spring: cloud: gateway: routes: - id: cookie_route uri: ${service-url.user-service} predicates: - Cookie=username,macro
Using curl tool to send a request with a cookie of username=macro can match the route.
curl http://localhost:9201/user/1 --cookie "username=macro"
Header Route Predicate
The request with the specified request header matches the route.
spring: cloud: gateway: routes: - id: header_route uri: ${service-url.user-service} predicates: - Header=X-Request-Id, \d+
Using curl tool to send a request with request header X-Request-Id:123 can match the route.
curl http://localhost:9201/user/1 -H "X-Request-Id:123"
Host Route Predicate
Requests with the specified Host will match the route.
spring: cloud: gateway: routes: - id: host_route uri: ${service-url.user-service} predicates: - Host=**.macrozheng.com
Use curl tool to send a request with a header of Host:www.macrozheng.com Com requests can match the route.
curl http://localhost:9201/user/1 -H "Host:www.macrozheng.com"
Method Route Predicate
The request to send the specified method will match the route.
spring: cloud: gateway: routes: - id: method_route uri: ${service-url.user-service} predicates: - Method=GET
The route can be matched by sending a GET request using the curl tool.
curl http://localhost:9201/user/1
Sending a POST request using curl tool cannot match the route.
curl -X POST http://localhost:9201/user/1
Path Route Predicate
The request to send the specified path will match the route.
spring: cloud: gateway: routes: - id: path_route uri: ${service-url.user-service}/user/{id} predicates: - Path=/user/{id}
Using curl tool to send / user/1 path request can match this route.
curl http://localhost:9201/user/1
The / abc/1 path request sent by curl tool cannot match the route.
curl http://localhost:9201/abc/1
Query Route Predicate
Requests with specified query parameters can match the route.
spring: cloud: gateway: routes: - id: query_route uri: ${service-url.user-service}/user/getByUsername predicates: - Query=username
Using curl tool to send a request with username=macro query parameter can match the route.
curl http://localhost:9201/user/getByUsername?username=macro
Sending a request with or without query parameters using curl tool cannot match the route.
curl http://localhost:9201/user/getByUsername
RemoteAddr Route Predicate
Requests originating from the specified remote address can match the route.
spring: cloud: gateway: routes: - id: remoteaddr_route uri: ${service-url.user-service} predicates: - RemoteAddr=192.168.1.1/24
The route can be matched by sending a request from 192.168.1.1 using curl tool.
curl http://localhost:9201/user/1
Weight Route Predicate
Use the weight to route the corresponding requests. The following shows that 80% of the requests will be routed to localhost:8201 and 20% to localhost:8202.
spring: cloud: gateway: routes: - id: weight_high uri: http://localhost:8201 predicates: - Weight=group1, 8 - id: weight_low uri: http://localhost:8202 predicates: - Weight=group1, 2
Use of Route Filter
The routing filter can be used to modify the incoming HTTP request and the returned HTTP response. The routing filter can only be used by specifying the route. Spring Cloud Gateway
There are many built-in routing filters, which are generated by the factory class of GatewayFilter. Let's introduce the usage of common routing filters.
AddRequestParameter GatewayFilter
A filter that adds parameters to the request.
spring: cloud: gateway: routes: - id: add_request_parameter_route uri: http://localhost:8201 filters: - AddRequestParameter=username, macro predicates: - Method=GET
The above configuration will add the request parameter of username=macro to the GET request, and use the following command to test through curl tool.
curl http://localhost:9201/user/getByUsername
Equivalent to initiating the request:
curl http://localhost:8201/user/getByUsername?username=macro
StripPrefix GatewayFilter
A filter that removes a specified number of path prefixes.
spring: cloud: gateway: routes: - id: strip_prefix_route uri: http://localhost:8201 predicates: - Path=/user-service/** filters: - StripPrefix=2
The above configuration will remove two bits from the path of the request starting with / user service /, and use the following command to test through curl tool.
curl http://localhost:9201/user-service/a/user/1
Copying the code is equivalent to initiating the request:
curl http://localhost:8201/user/1
PrefixPath GatewayFilter
Contrary to the StripPrefix filter, it is a filter that adds to the original path.
spring: cloud: gateway: routes: - id: prefix_path_route uri: http://localhost:8201 predicates: - Method=GET filters: - PrefixPath=/user
The above configuration will add / user path prefix to all GET requests, and use the following command to test through curl tool.
curl http://localhost:9201/1
Equivalent to initiating the request:
curl http://localhost:8201/user/1
Hystrix GatewayFilter
The Hystrix filter allows you to add the circuit breaker function to the gateway routing, protect your service from cascading failures, and provide service degradation processing.
To turn on the circuit breaker function, we need to switch on the POM Add the related dependencies of Hystrix in XML:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
Then add the processing class of related service degradation:
/** * Created by macro on 2019/9/25. */ @RestController public class FallbackController { @GetMapping("/fallback") public Object fallback() { Map<String,Object> result = new HashMap<>(); result.put("data",null); result.put("message","Get request fallback!"); result.put("code",500); return result; } }
In application filter Add relevant configurations in YML. When the route fails, it will be forwarded to the controller for service degradation processing:
spring: cloud: gateway: routes: - id: hystrix_route uri: http://localhost:8201 predicates: - Method=GET filters: - name: Hystrix args: name: fallbackcmd fallbackUri: forward:/fallback
- Close the user service and call the address to test: http://localhost:9201/user/1 , it is found that the processing information of service degradation has been returned.
RequestRateLimiter GatewayFilter
The RequestRateLimiter filter can be used to limit the flow. The RateLimiter implementation is used to determine whether to allow the current request to continue. If the request is too large, the HTTP 429- too many request status will be returned by default.
In POM Add related dependencies to XML:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency>
Add the configuration class of current limiting policy. There are two strategies: one is to limit the current according to the username in the request parameter, and the other is to limit the current according to the access IP;
/** * Created by macro on 2019/9/25. */ @Configuration public class RedisRateLimiterConfig { @Bean KeyResolver userKeyResolver() { return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("username")); } @Bean public KeyResolver ipKeyResolver() { return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName()); } }
We use Redis to limit the flow, so we need to add the configuration of Redis and RequestRateLimiter. All GET requests are limited by IP;
server: port: 9201 spring: redis: host: localhost password: 123456 port: 6379 cloud: gateway: routes: - id: requestratelimiter_route uri: http://localhost:8201 filters: - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 1 #Number of requests allowed to be processed per second redis-rate-limiter.burstCapacity: 2 #Maximum number of requests processed per second key-resolver: "#{@ipKeyResolver}" #Current limiting policy, Bean corresponding to the policy predicates: - Method=GET logging: level: org.springframework.cloud.gateway: debug
Retry GatewayFilter
The filter that retries the routing request can determine whether to retry according to the HTTP status code returned by the routing request.
To modify a profile:
spring: cloud: gateway: routes: - id: retry_route uri: http://localhost:8201 predicates: - Method=GET filters: - name: Retry args: retries: 1 #Number of retries required statuses: BAD_GATEWAY #Which status code needs to be returned for retry? The status code returned is 5XX for retry backoff: firstBackoff: 10ms maxBackoff: 50ms factor: 2 basedOnPreviousValue: false
When the call returns 500, it will retry and access the test address: http://localhost:9201/user/111
It can be found that the user service console reported an error twice, indicating a retry.
2019-10-27 14:08:53.435 ERROR 2280 --- [nio-8201-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause java.lang.NullPointerException: null at com.macro.cloud.controller.UserController.getUser(UserController.java:34) ~[classes/:na]
Use with registry
Last time we talked about using Zuul as a gateway in combination with the registry. By default, Zuul will create a dynamic route with the service name as the path according to the service list registered in the registry. Gateway also realizes this function. Let's demonstrate how the gateway uses the default dynamic routing and filter in combination with the registry.
Use dynamic routing
In POM Add related dependencies to XML:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
Add application Eureka YML profile:
server: port: 9201 spring: application: name: api-gateway cloud: gateway: discovery: locator: enabled: true #Enable the function of dynamically creating routes from the registry lower-case-service-id: true #Use lowercase service name, which is uppercase by default eureka: client: service-url: defaultZone: http://localhost:8001/eureka/ logging: level: org.springframework.cloud.gateway: debug
Use application Eureka YML configuration file starts API gateway service and accesses http://localhost:9201/user-service/user/1, which can be routed to the user service http://localhost:8201/user/1 Office.
Use filter
When using the filter in combination with the registry, we should note that the uri protocol is lb, so that the load balancing function of the Gateway can be enabled.
Modify application Eureka YML file, using PrefixPath filter, will add / user path and route for all GET request paths;
server: port: 9201 spring: application: name: api-gateway cloud: gateway: routes: - id: prefixpath_route uri: lb://User service # requires lb protocol predicates: - Method=GET filters: - PrefixPath=/user discovery: locator: enabled: true eureka: client: service-url: defaultZone: http://localhost:8001/eureka/ logging: level: org.springframework.cloud.gateway: debug
Use application Eureka YML configuration file starts API gateway service and accesses http://localhost:9201/1 , which can be routed to the user service http://localhost:8201/user/1 Office.
Modules used
springcloud-learning
- eureka server - eureka registry
User service - the service that provides the CRUD interface of the user object
└ - API Gateway - Test Service of gateway