Series Article Directory
Chapter 32 Microservice Link Tracking-sleuth zipkin
Chapter 30 Distributed Transaction Framework seata TCC Mode
Chapter 29 Distributed Transaction Framework seata AT Mode
Chapter 12 Spring Cloud Alibaba Sentinel
Chapter 11 Spring Cloud Alibaba nacos Configuration Center
Chapter 10 Spring Cloud Alibaba’s Nacos discovery
Chapter 7 Spring Cloud’s GateWay
Chapter 6 Spring Cloud’s OpenFeign
foreword
The API gateway is a service built between the client and the microservice. We can handle some non-business function logic in the API gateway, such as authorization verification, monitoring, caching, request routing, etc.
1. Access the service through the API gateway
- When the client interacts with the microservice through the API gateway, the client only needs to know the address of the API gateway, and does not need to maintain a large number of service addresses, which simplifies the development of the client.
- The client directly communicates with the API gateway, which can reduce the number of interactions between the client and various services.
- The service coupling between the client and the backend is reduced.
- Save traffic, improve performance, and enhance user experience.
- API Gateway also provides API management functions such as security, flow control, filtering, caching, billing, and monitoring.
2. The main function of Spring Cloud GateWay is routing and forwarding
When defining forwarding rules, the following three core concepts are mainly involved, as shown in the following table.
Core idea | describe |
---|---|
Route | The most basic module of a gateway. It consists of an ID, a target URI, a set of assertions (Predicate) and a set of filters (Filter). |
Predicate | Judging conditions for route forwarding, we can match HTTP requests through Predicate, such as request method, request path, request header, parameters, etc. If the request matches the assertion successfully, the request will be forwarded to the corresponding service. |
Filter | Filter, we can use it to intercept and modify the request, and we can also use it to reprocess the above response. |
3. Gateway workflow
- The client sends the request to Spring Cloud Gateway.
- Spring Cloud Gateway finds the route that matches the request through Gateway Handler Mapping and sends it to Gateway Web Handler.
- Gateway Web Handler forwards the request to the actual service node through the specified filter chain (Filter Chain), executes the business logic and returns the response result.
- Filters are separated by dotted lines because filters may execute business logic before (pre) or after (post) forwarding the request.
- Filters can intercept and modify requests before they are forwarded to the server, such as parameter verification, permission verification, traffic monitoring, log output, and protocol conversion.
- The filter can intercept and reprocess the response before it is returned to the client, such as modifying the response content or header, log output, traffic monitoring, etc.
- The response is returned to the client in the same way.
4, Predicate affirmation
pring Cloud Gateway realizes the matching rules of Route routing through Predicate assertion. To put it simply, Predicate is the judging condition for routing forwarding. Only when the request meets the condition of Predicate will it be forwarded to the specified service for processing.
Common Predicate assertions are as follows (assuming the forwarded URI is http://localhost:8001).
Affirmation | example | illustrate |
---|---|---|
Path | - Path=/user/listUserInfo/** | When the request path matches /user/listUserInfo/**, the request can be forwarded to http://localhost:8001. |
Before | - Before=2022-12-07T11:47:34.255+08:00[Asia/Shanghai] | Requests made before 11:47:34.255 on December 07, 2022 will be forwarded to http://localhost:8001. |
After | - After=2022-12-07T11:47:34.255+08:00[Asia/Shanghai] | Requests made after 11:47:34.255 on December 07, 2022 will be forwarded to http://localhost:8001. |
Between | - Between=2022-12-07T15:18:33.226+08:00[Asia/Shanghai],2022-12-07T15:23:33.226+08:00[Asia/Shanghai] | Only requests between 15:18:33.226 on December 07, 2022 and 15:23:33.226 on December 07, 2022 will be forwarded to the http://localhost:8001 server. |
Cookie | - Cookie=name,hqyj.com | Only requests that carry cookies and whose content is name=hqyj.com will be forwarded to http://localhost:8001. |
Header | - Header=X-Request-Id,\d+ | Only requests with the attribute X-Request-Id in the request header and the attribute value is an integer will be forwarded to http://localhost:8001. |
Method | - Method=GET | Only GET requests will be forwarded to http://localhost:8001. |
5. Examples
Create a submodule: gateway-service
5.1, pom.xml configuration
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.hqyj</groupId>
<artifactId>SpringCloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>gateway-service</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
</project>
5.2, application.xml configuration
server:
port: 80
spring:
application:
name: gateway-service
cloud:
gateway: #网关路由配置
routes:
#将 drp-user-service 提供的服务隐藏起来,不暴露给客户端,只给客户端暴露 API 网关的地址 80
- id: drp-user-service_routh #路由 id,没有固定规则,但唯一,建议与服务名对应
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
#以下是断言条件,必选全部符合条件
- Path=/user/userInfoList/** #断言,路径匹配 注意:Path 中 P 为大写
- Method=GET #只能时 GET 请求时,才能访问
eureka:
instance:
instance-id: gateway-service
hostname: localhost
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://localhost:7001/eureka
5.3, startup class
@SpringBootApplication
@EnableEurekaClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class,args);
}
}
Access: http://localhost/user/userInfoList
6. Dynamic routing
Use the service name (spring.application.name) as the path to create a dynamic route for forwarding, so as to realize the dynamic routing function. The
uri address of Route is changed to the following form.
lb://service-name
6.1. Modify application.xml configuration
server:
port: 80
spring:
application:
name: drp-gateway-service
cloud:
gateway: #网关路由配置
routes:
#将 drp-user-service 提供的服务隐藏起来,不暴露给客户端,只给客户端暴露 API 网关的地址 80
- id: drp-user-service_routh #路由 id,没有固定规则,但唯一,建议与服务名对应
uri: lb://USER-SERVICE #匹配后提供服务的路由地址
predicates:
#以下是断言条件,必选全部符合条件
- Path=/user/userInfoList/** #断言,路径匹配 注意:Path 中 P 为大写
- Method=GET #只能时 GET 请求时,才能访问
metadata:
connect-timeout: 10
#单位毫秒
response-timeout: 10000
eureka:
instance:
instance-id: drp-gateway-service
hostname: localhost
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://localhost:7001/eureka
7. Filter
User login status verification, signature verification.
Spring Cloud Gateway provides the following two types of filters
filter type | illustrate |
---|---|
Pre type | This filter can intercept and modify the request before it is forwarded to the microservice, such as parameter verification, permission verification, traffic monitoring, log output, and protocol conversion. |
Post type | This filter can intercept and reprocess the response after the microservice responds to the request, such as modifying the response content or response header, log output, traffic monitoring, etc. |
7.1, Filter classification
According to the scope of action, the Filter of Spring Cloud gateway can be divided into two categories: GatewayFilter, GlobalFilter
7.1.1、GatewayFilter
A filter applied to a single route or a group of routes.
Commonly used GatewayFilter filters
route filter | describe | parameter | Example of use |
---|---|---|---|
AddRequestHeader | Intercept incoming requests and add a specified request header parameter to the request. | name: the key of the request header parameter to be added value: the value of the request header parameter to be added. |
- AddRequestHeader=my-request-header,1024 |
AddRequestParameter | Intercept incoming requests and add a specified request parameter to the request. | name: the key of the request parameter to be added; value: the value of the request parameter to be added. |
- AddRequestParameter=my-request-param,c.biancheng.net |
AddResponseHeader | Intercepts the response and adds a specified response header parameter to the response. | name: the key of the response header to be added; value: the value of the response header to be added. |
- AddResponseHeader=my-response-header,c.biancheng.net |
PrefixPath | Intercept incoming requests and add a specified prefix to the request path. | prefix: The path prefix that needs to be added. | -PrefixPath=/consumer |
PreserveHostHeader | When forwarding the request, keep the client's Host information unchanged, and then pass it to the microservice that provides specific services. | none | -PreserveHostHeader |
RemoveRequestHeader | Remove the parameters specified in the request header. | name: The key of the request header to be removed. | - RemoveRequestHeader=my-request-header |
RemoveResponseHeader | Remove the parameters specified in the response header. | name: The response header that needs to be removed. | - RemoveResponseHeader=my-response-header |
RemoveRequestParameter | Remove the specified request parameter. | name: The request parameter to be removed. | - RemoveRequestParameter=my-request-param |
RequestSize | Configure the size of the request body. When the request body is too large, 413 Payload Too Large will be returned. | maxSize: The size of the request body. | - name:RequestSize args: maxSize: 5000000 |
7.1.2. Examples
spring:
application:
name: drp-gateway-service
cloud:
gateway: #网关路由配置
routes:
#将 drp-user-service 提供的服务隐藏起来,不暴露给客户端,只给客户端暴露 API 网关的地址 80
- id: drp-user-service_routh #路由 id,没有固定规则,但唯一,建议与服务名对应
uri: lb://USER-SERVICE #匹配后提供服务的路由地址
predicates:
#以下是断言条件,必选全部符合条件
- Path=/userInfoList/** #断言,路径匹配 注意:Path 中 P 为大写
- Method=GET #只能时 GET 请求时,才能访问
filters:
- AddRequestHeader=token,tigergege
- PrefixPath=/user
7.1.2、GlobalFilter
A filter applied to all routes, which can be used to unify exception handling
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;
/***
* @title DrfGlobalFilter
* @desctption 登录验证
* @author Administrator
* @create 2023/5/15 14:17
**/
@Component
public class DrfGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
//获取URI地址
RequestPath path = request.getPath();
HttpHeaders headers = request.getHeaders();
List<String> stringList = headers.get("token");
//是否登录验证
if(CollectionUtils.isEmpty(stringList)){
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
//过滤器优先级,0为最高
return 0;
}
}