Spring Cloud microservice Learning Series 12 Gateway gateway

Posted by soniared2002 on Sat, 25 Dec 2021 11:22:35 +0100

Spring Cloud Gateway

brief introduction

Spring Cloud Gateway is a gateway service developed on the spring official website based on Spring 5.0, Spring Boot 2.0, Project Reactor and other technologies.

Main functions of gateway:

  1. Spring Cloud Gateway provides the basic functions of the gateway based on the Filter chain: security, monitoring / embedding point, current limiting, etc. ***
  2. Spring Cloud Gateway provides a simple, effective and unified API routing management method for microservice architecture.

3.Spring Cloud Gateway is a solution to replace Netflix Zuul.

4. The core of the Spring Cloud Gateway component is a series of filters, Through these filters, the requests sent by the client can be forwarded (routed) to the corresponding microservices. Spring Cloud Gateway is a firewall and agent added at the forefront of the whole microservice, hiding the IP port information of the microservice node, so as to strengthen security protection. Spring Cloud Gateway itself is also a microservice and needs to be registered with Eureka service registry.

**
**The core functions of the gateway are: * * filtering and routing (forwarding client requests to various microservices)

Schema after adding GetWay

Whether it is a request from the client (PC or mobile terminal) or an internal call of the service, all requests for the service can pass through the Gateway, and then the Gateway can realize authentication, dynamic routing and other operations. The Gateway is the unified entrance of our service

Introduction to core concepts

  • The composition of route information: it consists of an ID, a destination URL, a group of assertion factories and a group of filters. If the route assertion is true, it indicates that the request URL matches the configured route.
  • The input type of the assertion function in Spring Cloud Gateway is ServerWebExchange in Spring 5.0 framework. The assertion function of Spring Cloud Gateway allows developers to define and match any information from Http Request, such as request header and parameters.
  • Filter is a standard Spring WebFilter. There are two types of filters in Spring Cloud Gateway: Gateway Filter and Global Filter. The filter will modify requests and responses.

quick get start

Step analysis

1. New construction
2. Write startup class
3. Write configuration
4. Write routing rules
5. Start test

1. Import jar package for new project

<dependencies>
    <!--gateway relevant-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!--eureka relevant-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

2. Write startup class

package com.pjh;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GateWayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GateWayApplication.class);
    }
}

3. Write configuration

server:
  port: 10010 #port
spring:
  application:
    name: gateway-service #Service name registered to eureka
eureka:
  client:
    service-url:
      defaultZone: http://Localhost: address and port of 10086 / Eureka #eureka registry
  instance:
    prefer-ip-address: true

4. Write routing rules

server:
  port: 10010
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # Routing id, which can be any
        - id: user-service-route
          # Service address of agent
          uri: http://127.0.0.1:8088
          # Route assertion: can match mapping path
          predicates:
            - Path=/user/**

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true

5. Start test

The user service method was successfully called to query the database

Service oriented routing

What is service oriented routing

In the routing rule just now, the service address of the path is written to death. If a service has multiple instances, you should go to Eureka registry to find the list of all instances corresponding to the service according to the service name, and then conduct dynamic routing

Modify the configuration file, and obtain it through the configuration name

server:
  port: 10010
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # Routing id, which can be any
        - id: user-service-route
          #lb means to obtain specific services from eureka
          uri: lb://producer-service #http://127.0.0.1:8088
          #Route assertion, you can configure the mapping path
          predicates:
            #Add request path prefix
            - Path=/user/**
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true


test

explain

When the protocol used in the routing configuration is lb (take uri: LB: / / producer service as an example), gateway will use LoadBalance and user service to resolve to the actual host and port through eureka for ribbon load balancing

Routing prefix

Function and purpose of routing prefix:

**

Objectives:

You can add or remove a prefix to the address requested to the gateway service
**

analysis:

Address of service provider: http://127.0.0.1:9091/user/8

  • Add prefix: add a prefix path to the request address and then use it as the service address of the agent;

http://127.0.0.1:10010/8 --> http://127.0.0.1:9091/user/8 Add prefix path / user

  • Remove prefix: remove some prefix paths from the path in the request address, and then serve as the service address of the agent;

http://127.0.0.1:10010/api/user/8 --> http://127.0.0.1:9091/user/8 Remove prefix path / api

effect:

If the request address of the client is inconsistent with the service address of the microservice, you can add and remove the path prefix by configuring the path filter.

add prefix

Concept:

Add a prefix path to the request address and then serve as the service address of the agent;

example

For example, in the browser, you enter http://127.0.0.1:10010/8
If you set the auto prefix content to / user
The gateway will automatically add * * / user when calling the micro service**
That is, the address becomes: http://127.0.0.1:9091/user/8

Profile configuration

server:
  port: 10010
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # Routing id, which can be any
        - id: user-service-route
          #lb means to obtain specific services from eureka
          uri: lb://producer-service #http://127.0.0.1:8088
          #Route assertion, you can configure the mapping path
          predicates:
            #Add the request path prefix. The prefix added automatically cannot be included here. Otherwise, the assertion fails
            - Path=/**
          filters:
            - PrefixPath=/user

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true


Remove prefix

concept

Remove some prefix paths from the path in the request address, and then use it as the service address of the agent

Example:

For example, the address you visit in the browser is: http://127.0.0.1:10010/api/user/8

Set the address of the gateway calling the microservice after removing a prefix as http://127.0.0.1:9091/user/8
**
Take the example above as an example
**
The number of prefixes to be removed from the route is specified by StripPrefix=1. For example, the path / api/user/1 will be proxied to / user/1, that is:

StripPrefix=1 http://localhost:10010/api/user/8 -->http://localhost:9091/user/8

StripPrefix=2 http://localhost:10010/api/user/8 -->http://localhost:9091/8

Profile configuration

server:
  port: 10010
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # Routing id, which can be any
        - id: user-service-route
          #lb means to obtain specific services from eureka
          uri: lb://producer-service #http://127.0.0.1:8088
          #Route assertion, you can configure the mapping path
          predicates:
            #Remove prefix - Path=/api/user / * * the request path here should be set to the path before removing the prefix
            - Path=/**
          filters:
            #Here, 1 means filtering one prefix, and 2 means filtering two prefixes
            - StripPrefix=1

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true


filter

brief introduction

One of the important functions of Gateway is to realize the authentication of request. This action is often implemented through the filter provided by the Gateway. The functions in the previous routing prefix chapter are also implemented using filters. The Gateway has dozens of built-in filters, and the common built-in filters are:

Configure global default filters

These built-in filters can be similar to the usage in the section using route prefix, or they can be configured not only for a route; Instead, it can take effect for all routes, that is, configure the default filter:
Understand the following:

server:
  port: 10010
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # Routing id, which can be any
        - id: user-service-route
          #lb means to obtain specific services from eureka
          uri: lb://producer-service #http://127.0.0.1:8088
          #Route assertion, you can configure the mapping path
          predicates:
            #Add the request path prefix. The prefix added automatically cannot be included here. Otherwise, the assertion fails
            #Remove prefix - Path=/api/user / * * the request path here should be set to the path before removing the prefix
            - Path=/**
          filters:
            - PrefixPath=/user
            #Here, 1 means filtering one prefix, and 2 means filtering two prefixes
            #- StripPrefix=1
      default-filters:
        # The response header filter sets the header attribute name of the output response as X-Response-Default-MyName and the value as test;
        #If there are multiple parameters, override one line to set different parameters
        - AddResponseHeader=X-Response-Default-MyName, test

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true


After configuration, use the developer tool to find an additional key value pair in the response header:

Filter type:

In terms of Gateway implementation, there are two kinds of filters;

1. Local filter:

Through spring cloud. gateway. routes. Filters are configured for specific routes and only work for the current route
On; The built-in filter can be configured or customized according to the built-in filter. If you configure spring cloud. gateway. Default filters are global filters that take effect for all routes; But these filters
The GatewayFilterFactory interface should be implemented in the implementation of.

2. Global filter:

It does not need to be configured in the configuration file and acts on all routes; Just implement the GlobalFilter interface

Execution lifecycle

Basic introduction

The Filter life cycle of Spring Cloud Gateway is similar to that of Spring MVC. There are two interceptors: "pre" and "post". "Pre" and "post" are called separately before and after the request is executed.


The pre and post here can be implemented before and after the filter method is executed by the gateway filterchain of the filter.

Usage scenario

Common application scenarios are as follows:

**Authentication request: * * generally, before the GatewayFilterChain executes the filter method, if it is found that there is no access permission, it will directly return null.

**Exception handling: * * generally, after the GatewayFilterChain executes the filter method, the exception is recorded and returned.

Statistics of service call duration: the gateway filterchain performs statistics according to the time before and after the filter method is executed.

Custom filter

Custom local filter

Objectives:

Write and configure a custom local filter according to the default filter, which can obtain the requested parameter value through the parameter name in the configuration file
**

analysis:

Requirements: in the filter (MyParamGatewayFilterFactory) http://localhost:10010/api/user/8?name=itcast The value of the parameter name in is obtained and output to the console; And the parameter name is variable, that is, it may not always be name; You can configure the parameter name when configuring the filter.

Implementation steps:

  1. Configure filters;
  2. Write filter;
  3. test

1. Configure filter;

server:
  port: 10010
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # Routing id, which can be any
        - id: user-service-route
          #lb means to obtain specific services from eureka
          uri: lb://producer-service #http://127.0.0.1:8088
          #Route assertion, you can configure the mapping path
          predicates:
            #Add the request path prefix. The prefix added automatically cannot be included here. Otherwise, the assertion fails
            #Remove prefix - Path=/api/user / * * the request path here should be set to the path before removing the prefix
            - Path=/**
          filters:
            - PrefixPath=/user
            #FilterTest here is the first half of the configured filter class name FilterTestGatewayFilterFactory
            - FilterTest=age
            #Here, 1 means filtering one prefix, and 2 means filtering two prefixes
            #- StripPrefix=1
      default-filters:
        # The response header filter sets the header attribute name of the output response as X-Response-Default-MyName and the value as test;
        #If there are multiple parameters, override one line to set different parameters
        - AddResponseHeader=X-Response-Default-MyName, test

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true


2. Write filter;

package com.pjh.Filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;

import javax.print.DocFlavor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Component/*Add bean annotation*/
public class FilterTestGatewayFilterFactory extends AbstractGatewayFilterFactory<FilterTestGatewayFilterFactory.Config> {
   /*Construction method*/
    public FilterTestGatewayFilterFactory(){
       super(Config.class);
   }
    /*Specify the corresponding parameter name*/
   static final String PARAM_NAME = "param";
    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            if (request.getQueryParams().containsKey(config.param)){
                request.getQueryParams().get(config.param)
                        .forEach(value -> System.out.printf("----------Local filter-----%s = %s-----",
                                config.param, value));

                     }
            return chain.filter(exchange);
        };
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(PARAM_NAME);
    }

    public static class  Config{
        /*Corresponds to the parameters specified when configuring the filter*/
        private String param;

        public String getParam() {
            return param;
        }

        public void setParam(String param) {
            this.param = param;
        }
    }


}

3. Test

Custom global filter

Objectives:

Define a global filter to check whether the request carries the token parameter
**

analysis:

Requirements:

Write a global filter and check whether the request address carries the token parameter in the filter. If the value of the token parameter exists, it will be released; If the parameter value of token is empty or does not exist, the returned status code is set to: unauthorized and will not be executed again.

Implementation steps:

  1. Write global filter;
  2. test

1. Write global filter;

package com.pjh.Filter;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("Executing global filter");
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        //Judge whether it is empty
        if (StringUtils.isBlank(token)){
            /*Set the status code to unauthorized*/
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        /*When there are multiple filters, the smaller the value, the earlier the execution*/
        return 1;
    }
}

2. Test

When there is no token parameter

With token parameter
**

Load balancing and fusing

By default, Ribbon load balancing and Hystrix fuse mechanism have been integrated in the Gateway. However, all timeout policies are the default values. For example, the fuse timeout is only 1S, which is easy to trigger. Therefore, manual configuration is recommended

server:
  port: 10010
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # Routing id, which can be any
        - id: user-service-route
          #lb means to obtain specific services from eureka
          uri: lb://producer-service #http://127.0.0.1:8088
          #Route assertion, you can configure the mapping path
          predicates:
            #Add the request path prefix. The prefix added automatically cannot be included here. Otherwise, the assertion fails
            #Remove prefix - Path=/api/user / * * the request path here should be set to the path before removing the prefix
            - Path=/**
          filters:
            - PrefixPath=/user
            #FilterTest here is the first half of the configured filter class name FilterTestGatewayFilterFactory
            #- FilterTest=age
            #Here, 1 means filtering one prefix, and 2 means filtering two prefixes
            #- StripPrefix=1
      default-filters:
        # The response header filter sets the header attribute name of the output response as X-Response-Default-MyName and the value as test;
        #If there are multiple parameters, override one line to set different parameters
        - AddResponseHeader=X-Response-Default-MyName, test
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds=2000
ribbon.:
  ConnectTimeout: 1000 # Connection timeout duration
  ReadTimeout: 2000 # Data communication timeout duration
  MaxAutoRetries: 0 # Number of retries for the current server
  MaxAutoRetriesNextServer: 0 # How many service retries
  OkToRetryOnAllOperations: false # Do you want to retry all request methods
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true

Gateway cross domain configuration

General gateway is the unified entrance of all microservices, and cross domain problems will inevitably occur when calling

What is cross domain

In js request access, if the access address is inconsistent with the domain name, ip or port number of the current server, it is called cross domain request. If it is not solved, the return result of the corresponding address cannot be obtained.

For example, from http://localhost:9090 js access in http://localhost:9000 Because the ports are different, the data is also a cross domain request.
If there is a cross domain problem when accessing the Spring Cloud Gateway server; You can configure the gateway server to determine which services can be requested across domains; The specific configuration is as follows:

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]':
           #allowedOrigins: * # This way of writing or the following can be used, * means all
            allowedOrigins:
            - "http://docs.spring.io"
            allowedMethods:
            - GET

The above configuration indicates that it is allowed to http://docs.spring.io Get service data by get request. allowedOrigins specifies the server address allowed to access, such as: http://localhost:10000 It is also possible. " [/ * *] 'indicates the address of all requests to access the gateway server
Specific instructions on the official website: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.1.RELEASE/multi/mul
ti__cors_configuration.html

Gateway high availability

Start multiple Gateway services and automatically register with Eureka to form a cluster. In case of internal service access, access the Gateway and automatic load balancing. No problem.
However, the Gateway is more external access, such as PC terminal, mobile terminal, etc. They can't load balance through Eureka, so what should I do?
At this time, other service gateways can be used to proxy the Gateway. For example: Nginx

Difference between Gateway and Feign

As the entrance of the whole traffic, the Gateway accepts all requests, such as PC, mobile terminal, etc., and sends different requests to different micro service processing modules. Its role is regarded as nginx. In most cases, it is used for permission definition and service terminal traffic control

Fegin exposes some service interfaces of the current microservices and is mainly used for service calls between microservices

Topics: Spring Cloud