"Microservices in Action" Chapter 7 GateWay of Spring Cloud

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

insert image description here


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.
insert image description here

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

insert image description here

  • 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.
insert image description here
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;
    }
}

Guess you like

Origin blog.csdn.net/s445320/article/details/130635327