An overview,

  • The official documentation
  • SpringCloud Gateway is a new Project of SpringCloud, which is developed based on Spring 5.0+Spring Boot 2.0 and Project Reactor technology. It aims to provide a simple and effective unified API route management approach for microservices architecture.
  • The gateway supports reverse proxy, authentication, traffic control, fusing, and log monitoring.

  • features
    • Dynamic routing: can match any request attribute;
    • You can specify Predicate and Filter for a route;
    • Integrated Circuit breaker function of Hystrix;
    • Integrate Spring Cloud service discovery;
    • Easy to write Predicate and Filter;
    • Request traffic limiting function;
    • Path rewriting is supported.
    • The Spring Cloud Gateway builds on Spring Framework 5, Project Reactor, and Spring Boot 2 and uses a non-blocking API.
    • The Spring Cloud Gateway also supports WebSocket and is tightly integrated with Spring for a better development experience

Ii. Core Concepts

1. Route

  • Is the basic building block of a gateway, consisting of an ID, a destination URL, a set of assertions, filters, and matching the route if the assertion is true.
  • Analogy is the routing of a computer network to different places, depending on the destination address.

2. Predicate

  • It’s attached to a route. In a nutshell, it’s a matching rule. You can match by path, time, Cookie, Header, etc. If a match is found, the route is forwarded.

3. Filter

  • It’s just an interceptor. Requests can be modified or restricted before or after a request.
  • This is an instance of GatewayFilter in the Spring framework.

4. Workflow

  1. The client makes a request to the Spring Cloud Gateway.
  2. Gateway Handler Mapping Finds the route matching the request and sends the route to the corresponding Gateway Web Handler
  3. The Gateway Web Handler sends the request through the specified filter chain to our actual Service to execute the business logic (Proxied Service), and then goes back through the specified filter chain.
  4. Then “backtrack.”

Filter and Pre filters can perform parameter verification, permission verification, traffic monitoring, log output, and protocol conversion. The Post filter can modify the response content, response header, log output, and traffic monitoring.

Iii. Experiments

1. The package

  • spring-cloud-starter-gatewayIs the most important package, the gateway’s main package.
  • spring-cloud-starter-netflix-eureka-client, the gateway service needs to be registered in the registry, and the gateway service can be discovered through the registry to achieve dynamic routing.
<dependencies>
    <! --gateway-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <! --eureka-client-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <! -- General Basic Configuration class -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
Copy the code

2. Modify the configuration file

  • Normal operation, register in eureka.
server:
  port: 9527

spring:
  application:
    name: cloud-gateway

eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://localhost:7001/eureka
Copy the code
  • In addition to the above, you need to add some custom gateway configurations.routesThere can be multiple routes below, made up of lists. Each route contains the ID, matched route address, assertion, and filter.
server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true      # enable the function of dynamically creating routes from registries using microservice names
      routes:
        - id: payment_routh #payment_route # Specifies the route ID. There is no fixed rule but it must be unique
          uri: http://localhost:8002          # Route address to provide service after match
         #uri: lb:// cloud-payment-service
          predicates:
            - Path=/payment/**         # assert that the path matches the route
        # - After = 2021-05-23 T12: but. 017 + 08:00 [GMT + 08:00]
        # - Before = 2021-05-23 T12:28:00. 017 + 08:00 [GMT + 08:00]
        # - Between T12 = 2021-05-23:31:00. 000 + 08:00 / GMT + 08:00, the 2021-05-23 T12: charm. 000 + 08:00 [GMT + 08:00]
        # - Cookie=username,du # curl http://localhost:9527/payment/get/1 --cookie "username=du"
        # - Header=X-Request-Id,\d+ # curl http://localhost:9527/payment/get/1 -H "X-Request-Id:5"
        # - Query=username,\d+

        - id: payment_routh2 #payment_route # Specifies the route ID. There is no fixed rule but it must be unique
          uri: http://localhost:8001          # Route address to provide service after match
          predicates:
            - Path=/discovery/**         # assert that the path matches the route

        - id: payment_routh2 #payment_route # Specifies the route ID. There is no fixed rule but it must be unique
          uri: http://localhost:8002          # Route address to provide service after match
          predicates:
            - Path=/timeOut/**         # assert that the path matches the route
eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    # indicates whether to register yourself in EurekaServer. The default is true.
    register-with-eureka: true
    Whether to fetch existing registration information from EurekaServer. Default is true. The cluster must be set to True to use load balancing with the ribbon
    fetchRegistry: true
    service-url:
      #defaultZone: http://localhost:7001/eureka
      defaultZone: http://127.0.0.1:7001/eureka,http://127.0.0.1:7002/eureka  # version of the cluster
Copy the code

3. Main startup class

  • Normal operation
@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {
  public static void main(String[] args) { SpringApplication.run(GateWayMain9527.class, args); }}Copy the code

4. Test

  • Open the gateway and some servers that the gateway forwards to.
  • The browser makes a requesthttp://localhost:8527/payment/get/1, the gateway will forward tohttp://localhost:8002/payment/get/1

5. Configure gateway routes

  • In addition to the above configuration through a YAML file, you can also configure it by injecting beans into the container.
  • For example, at present, it is necessary to realize the routing from local forwarding to Baidu news.
@Configuration
@SuppressWarnings("all")  // If autowired is available, tell me it can't be found
public class GateWayConfig {
  @Bean
  public RouteLocator routeLocator1(RouteLocatorBuilder builder) {
    RouteLocatorBuilder.Builder routes = builder.routes();
    return routes.route("new_guonei", r -> r.path("/guonei").uri("http://news.baidu.com/guonei")).build();
  }

  @Bean
  public RouteLocator routeLocator2(RouteLocatorBuilder builder) {
    RouteLocatorBuilder.Builder routes = builder.routes();
    return routes.route("new_guoji", r -> r.path("/guoji").uri("http://news.baidu.com/guoji")).build(); }}Copy the code
  • In simple terms, the gateway is added to a router, and the matching path and destination routing address are added to the router. It’s really not that different from a configuration file.

6. Dynamic route description

  • Configuration file and beanuriBoth give direct IP addresses and then forward them directly. In fact, the gateway can also give the service name and find a suitable address from the matched address through the load balancing policy and forward the service.
uri: lb://CLOUD-PAYMENT-SERVICE      # Route address to provide service after match
Copy the code
  • The IP address is given in order tohttp://At the beginning, load balancing is usedlb://At the beginning

Fourth, the Predicate

  • Assertions can add more rules than path matching above.
  • The Predicate object is created using RoutePredicateFactory and then assigned to the route

1. After Route Predicate

  • Indicates that the current route takes effect after the specified time
predicates: 
    - After = 2021-05-23 T12: but. 017 + 08:00 [GMT + 08:00]
Copy the code

The date format in this format can be generated by Java code

public class Now {
  public static void main(String[] args) { ZonedDateTime now = ZonedDateTime.now(); System.out.println(now); }}Copy the code

2. Before Route Predicate

  • Indicates that the current route is valid before the specified time. Otherwise, the route is invalid.
predicates: 
    - Before = 2021-05-23 T12: but. 017 + 08:00 [GMT + 08:00]
Copy the code

3. Between Route Predicate

  • This parameter is valid in a period of time
predicates:
    - Between T12 = 2021-05-23:31:00. 000 + 08:00 / GMT + 08:00, the 2021-05-23 T12: charm. 000 + 08:00 [GMT + 08:00]
Copy the code

4. Cookie Route Predicate

  • Indicates that the request takes the specified Cookie and the value matches the specified regular expression
predicates:
    - Cookie=username,du   # curl http://localhost:9527/payment/get/1 --cookie "username=du"
Copy the code
  • Tests can be done through CMD
curl http://localhost:9527/payment/get/1 --cookie "username=du"
Copy the code

5. Header Route Predicate

  • Indicates that the request header must carry the specified Head and value
predicates:
    - Header=X-Request-Id,\d+   # curl http://localhost:9527/payment/get/1 -H "X-Request-Id:5"
Copy the code

6. Host Route Predicate

  • Matches the specified host address
predicates:
    - Host=**.atguigu.com
Copy the code

7. Method Route Predicate

  • Matches the specified methods, such as GET, POST, PUT, and DELETE
predicates:
    - Method=GET
Copy the code

8. Path Route Predicate

  • Matches the specified request path
predicates:
    - Path=/payment/lb/**         # assert that the path matches the route
Copy the code

9. Query Route Predicate

  • Matches the appropriate request parameters and values
predicates:
    - Query=username,\d+ # curl http://localhost:9527? username=5
Copy the code

Five, the Filter

  • Routing filters can be used to modify incoming HTTP requests and returned HTTP responses. Routing filters can only be used by specified routes.
  • There are many built-in filters, which can be divided into Pre and POST, GatewayFilter and GlobalFilter based on the life cycle. See the website

  • In the configuration file, you can add filters under routes
filters: 
    - AddRequestParameter=X-Request-Id,1024 The filter factory will add a pair of headers named x-request-id (1024) to the matching headers
Copy the code
  • You can also implement GlobalFilter,Ordered, and custom filters. Checks if the request parameter is null or intercepts if it is.
@Component
@Slf4j
public class MyFilter implements GlobalFilter.Ordered {
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    log.info("Execute custom filters");
    String username = exchange.getRequest().getQueryParams().getFirst("username");
    // Because there is no user name, it is filtered directly
    if (username == null) {
      log.info("User name null, unable to log in");
      exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
      return exchange.getResponse().setComplete();
    }
    return chain.filter(exchange);
  }

  @Override
  public int getOrder(a) {
    return 0; }}Copy the code