05 Gateway application practice

Gateway introduction

Background analysis

We know that a large-scale system is often divided into many micro services when it is designed. So how can a client call so many microservices? The client can directly send a request to the microservice. Each microservice has a public URL that can be directly mapped to a specific microservice. If there is no gateway, we can only record the address of each microservice on the client and call it separately. Such an architecture will have many problems. For example, the client requesting different microservices may increase the complexity of client code or configuration. In addition, each service needs independent authentication when calling. And there are cross domain requests, which also improves the complexity of the code to a certain extent. Based on the problems in the design and implementation of microservice architecture, in order to simplify the front-end call logic in the project, simplify the complexity of mutual calls between internal services, and better protect internal services, the concept of gateway is proposed.

Gateway overview

In essence, the gateway should provide an access to various services, and provide services to receive and forward all internal and external client calls, as well as authority authentication, flow restriction control and so on. Spring Cloud Gateway is a gateway component developed by spring company based on Spring 5.0, Spring Boot 2.0 and other technologies. It aims to provide a simple and effective unified API entry for microservice architecture, which is responsible for service request routing, composition and protocol conversion. It also provides functions such as authority authentication, monitoring and flow restriction based on Filter chain.

quick get start

Spring Cloud Gateway Analysis of advantages and disadvantages:

advantage:
Strong performance: 1.6 times that of Zuul, the first generation gateway.
Powerful function: built in many practical functions, such as forwarding, monitoring, current limiting, etc
Elegant design, easy to expand.

Disadvantages:
Relying on Netty and Webflux (spring 5.0) is not the traditional Servlet Programming Model (Spring MVC is implemented based on this model), and the learning cost is high.
Spring boot version 2.0 and above is required to support

Business description

The gateway is used as the service access portal to access the services in the system, for example, to access the SCA provider service through the gateway service

Entry business implementation

Step 1: create an SCA gateway module (if it already exists, there is no need to create it), and its POM The XML file is as follows:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

Step 2: create application YML (if it already exists, it does not need to be created), add relevant configuration, and the code is as follows:

server:
  port: 9000
spring:
  application:
    name: sca-gateway
  cloud:
    gateway:
        routes: #Configure gateway routing rules
          - id: route01  #Routing id, you can specify a unique value by yourself
            uri: http://localhost:8081 / # the url forwarded by the gateway
            predicates: ###Assertions (predicates): matching request rules
              - Path=/nacos/provider/echo/**  #The uri defines the path in the request, which corresponds to the uri
            filters: ##Gateway filter is used to judge, analyze and process the content in the predicate
              - StripPrefix=1 #Remove the first layer path in the path before forwarding, such as nacos

Among them: route is one of the most basic components in gateway, which represents a specific routing information carrier. The following information is mainly defined:

id, Route identifier, which is different from other routes.
uri, the destination uri pointed by the route, that is, the micro service to which the client request is finally forwarded.
Predicate, the function of assertion (predicate) is to judge the condition. The route will be executed only when the assertions return true.
filter, which is used to modify request and response information.

Step 3: create a project startup class, for example:

package com.cy;

@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class,args);
    }
}

Step 4: start the project for access test,

Start the SCA provider and SCA Gateway Services successively, and then open the browser for access test, for example:

Section interview analysis?

(1) What is a gateway? Service access (flow) is an entrance, similar to the "Customs" in life“
(2) Why use a gateway? (service security, unified service entrance management, load balancing, current limiting, authentication)
(3) ) initial construction process of Spring Cloud Gateway application (add dependency, configure)
(4) Who is the bottom layer of Gateway service startup implemented by? (Netty network programming framework ServerSocket)
(5) Must the Gateway service register in the registry when forwarding requests? (not necessarily, you can access the service directly through the remote url)

Load balancing design

Why load balancing?

The gateway is the entrance to service access, and all services will be mapped at the gateway level. Therefore, when accessing services, you should find the corresponding services based on the service ID (service name), and let the requests be evenly forwarded from the gateway layer to balance the processing capacity of service instances.

Implementation of load balancing in Gateway?

Step 1: add service discovery dependency in the project. The code is as follows:

<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

Step 2: modify its configuration file. The code is as follows

server:
  port: 9000
spring:
  application:
    name: sca-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: true  #Enable route creation through serviceId of service registry
      routes:
        - id: route01
          ##uri: http://localhost:8081/
          uri: lb://SCA provider # Lb is the service prefix (the abbreviation of load balancing word), which cannot be written arbitrarily
          predicates: ###Matching rules
              - Path=/nacos/provider/echo/**
          filters:
              - StripPrefix=1 #Remove the first layer path in the path before forwarding, such as nacos

lb refers to getting micro services from nacos by name and following load balancing policy. At the same time, it is suggested to open the gateway log in the development stage. The code is as follows:

logging:
  level:
    org.springframework.cloud.gateway: debug

Step 3: start the service, conduct access test, and refresh the analysis repeatedly, as shown in the figure:

Perform process analysis (important)

According to the official instructions, the specific work flow of the Gateway is shown in the figure:

The client sends a request to the Spring Cloud Gateway. If Gateway Handler Mapping determines that the request matches routes through the collection of predicates, it sends it to Gateway Web Handler. Based on the routing configuration, the Gateway Web Handler calls the Filter in the Filter chain (that is, the so-called responsibility chain mode) to further process the request. The reason why the Filter is separated by a dotted line is that the Filter can perform expansion logic before and after sending the request. Based on the official processing flow, the source code analysis is as follows:

Section interview analysis?

How does the gateway level achieve load balancing? (find the specific service instance through the service name)
How does the gateway layer find service instances by service names? (Ribbon)
What load balancing algorithms do you know about Ribbon? (polling, weight, hash,... Can be viewed and analyzed through IRule interface)
What is the request forwarding process of the gateway and what are the key objects? (XxxHandlerMapping,Handler,. . . )
How are gateway level services mapped? (predicate - path,..., service name / service instance)
How does the gateway layer record the mapping of services? (through the map, and consider the application of read-write lock)

Predicate enhanced analysis (understanding)

Introduction to predict

Predicate is also an appellation term, which is used for condition judgment. Only when the assertion results are true, can the route be truly executed. The essence of assertion is to define the conditions of routing and forwarding.

Predict built-in factory

SpringCloud Gateway includes some built-in predicate factories (all factories directly or indirectly implement the routepredictefactory interface). These predicate or predicate projects are responsible for creating predicate objects and judging the legitimacy of http requests through these predicate objects. Common predicate factories are as follows:

be based on Datetime Assertion factory of type

This type of assertion is judged according to time, mainly in three ways:
1) AfterRoutePredicateFactory: judge whether the request date is later than the specified date
2) BeforeRoutePredicateFactory: determines whether the request date is earlier than the specified date
3) BetweenRoutePredicateFactory: judge whether the request date is within the specified time period

-After=2020-12-31T23:59:59.789+08:00[Asia/Shanghai]

If and only if the time at the time of the request is After the configured time, the request will be forwarded. If the time at the time of the request is not After the configured time, 404 not found will be returned. The time value can be through zoneddatetime Now() get.

be based on header Assertion factory HeaderRoutePredicateFactory

Judge whether the request Header has the given name and the value matches the regular expression. For example:

-Header=X-Request-Id, \d+

be based on Method Assertion factory of the request method,

MethodRoutePredicateFactory receives a parameter to judge whether the request type matches the specified type. For example:

-Method=GET

be based on Query Assertion factory for request parameters, QueryRoutePredicateFactory : 


Receive two parameters, request param and regular expression, and judge whether the request parameter has the given name and the value matches the regular expression. For example:

-Query=pageSize,\d+

Predict application case practice

Built in route assertion factory application cases, such as:

server:
  port: 9000
spring:
  application:
    name: sca-gateway
  cloud:
    nacos:
      server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: true #Enable the function of creating a route through the serviceId of the service center
      routes:
        - id: bd-id
          ##uri: http://localhost:8081/
          uri: lb://sca-provider
          predicates: ###Matching rules
              - Path=/nacos/provider/echo/**
              - Before=2021-01-30T00:00:00.000+08:00
              - Method=GET
          filters:
            -  StripPrefix=1 # Remove layer 1 path before forwarding

Note: when the conditions are not met, routing forwarding cannot be carried out, and 404 exception will appear.

Section interview analysis

What is a predicate? (an object encapsulating the judgment logic in the gateway)
What is the design of predicate logic? (if the return value of predicate judgment logic is true, the request is forwarded)
What predicate logic do you know? (path, request parameter, request mode, request header,...)
Can we define predicate factory objects ourselves? (yes)

Filter enhanced analysis (understanding)

summary

Filter is to process the request and response in the process of request delivery. There are two types of Gateway filters: Gateway filter and GlobalFilter. Of which:

1. Gateway filter: applied to a single route or a packet route.
2.GlobalFilter: applied to all routes (such as load balancing filter, request forwarding filter, etc.).

Design and implementation of local filter

Many different types of gateway routing filters are built in the spring cloud gateway. The details are as follows:
Case study:

be based on AddRequestHeaderGatewayFilterFactory,Add for original request Header. 


For example, add a request header named X-Request-Foo and Bar to the original request:

spring:
  cloud:
    gateway:
      routes:
        - id: add_request_header_route
          uri: https://example.org
          filters:
            - AddRequestHeader=X-Request-Foo, Bar

be based on AddRequestParameterGatewayFilterFactory,Add request parameters and values to the original request,


For example, add a parameter named Foo and the value bar to the original request, that is: foo=bar.

spring:
  cloud:
    gateway:
      routes:
        - id: add_request_parameter_route
          uri: https://example.org
          filters:
            - AddRequestParameter=foo, bar

be based on PrefixPathGatewayFilterFactory,Add a prefix to the original request path


For example, this configuration causes access to ${GATEWAY_URL}/hello to be forwarded to uri/mypath/hello.

spring:
  cloud:
    gateway:
      routes:
        - id: prefixpath_route
          uri: https://example.org
          filters:
            - PrefixPath=/mypath

be based on RequestSizeGatewayFilterFactory,Sets the size of the maximum request packet allowed to be received


Configuration example:

spring:
  cloud:
    gateway:
      routes:
        - id: request_size_route
      uri: http://localhost:8080/upload
      predicates:
        - Path=/upload
      filters:
        - name: RequestSize
          args:
            # In bytes
            maxSize: 5000000

If the request packet size exceeds the set value, 413 Payload Too Large and an errorMessage will be returned

Design and implementation of global filter

Global filter works on all routes without configuration. It is loaded during system initialization and acts on each route. Through the global filter, the functions of unified verification of permissions and security verification can be realized. Generally, the built-in global filter can complete most of the functions, but we still need to write our own filter to process some business functions developed by enterprises. Then we can customize a filter in the form of code to complete the unified permission verification. For example, when the client requests a service for the first time, the server authenticates (logs in) the user's information, encrypts the user's information to form a token, and returns it to the client. After each request as a login credential, the client carries the authenticated token, and the service decrypts the token to determine whether it is valid. Students who have learned weblux technology in spring can try to implement the following code (those who have not learned can be ignored)

package com.cy.filters;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String username=exchange.getRequest()
                .getQueryParams().getFirst("username");
        if (!"admin".equals(username)) {
            System.out.println("Authentication failed");
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        //Call chain The filter continues to execute downstream
        return chain.filter(exchange);

    }

    @Override
    public int getOrder() {
        return 0;
    }
}

When starting the Gateway service, an exception may occur if the url accessed does not contain the parameter "user=admin"

Section interview analysis

What is the function of gateway filter? (preprocess the request and response data)
What are the types of gateway filters? (local filter, global filter)
How to understand local filter? (filters for specific link applications need to be configured)
What local filters do you know?
How to understand global filters? (acting on all requesting links)
How do I define a global filter myself? (implement GlobalFilter interface directly or indirectly)
If you are now allowed to conduct self-development and design of the gateway of the platform, can you? (yes)

Current limiting design and Implementation

Brief description of current limiting

The gateway is the public entrance for all external requests, so the current can be limited in the gateway, and there are many ways to limit the current. We use sentinel component to realize the current limit of the gateway. Sentinel supports current limiting for spring cloud gateway, Zuul and other mainstream gateways. The reference website is as follows:

https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel

Current limiting quick start

Step 1: add dependency
On the basis of the original spring cloud starter gateway dependency, add the following two dependencies, for example:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>

Step 2: add sentinel and routing rules (if they already exist, there is no need to set them)

routes:
  - id: route01
    uri: lb://sca-provider
    predicates: ###Matching rules
      - Path=/provider/echo/**

Step 3: start the gateway project and check the gateway menu of sentinel console.
When starting, add the jvm parameter of sentinel. Through this menu, the gateway service can display a different menu on the sentinel console. The code is as follows.

-Dcsp.sentinel.app.type=1

If it is in idea, you can refer to the following figure for configuration

After Sentinel console is started, the interface is as shown in the figure:

Note: if the request link is not found, API management, close the gateway project, close sentinel, and then restart sentinel and restart the gateway project

Step 4: set the current limiting policy in sentinel panel, as shown in the figure:

Step 5: access through the url to check whether the current limiting operation is realized

Current limiting based on request attributes

Define the attribute based current limiting policy for the specified routeId, as shown in the figure:


Post man test

Custom API dimension current limit (key)

Custom API grouping is a more fine-grained definition of flow restriction rules. It allows us to use the API provided by sentinel to group request paths, and then set flow restriction rules on the group.
Step 1: create a new API Group, as shown in the figure:

Step 2: create a new grouping flow control rule, as shown in the figure:

Step 3: conduct access test, as shown in the figure

Return value of customized flow control gateway

Define the configuration class and design the flow control return value. The code is as follows:

@Configuration
public class GatewayConfig {
    public GatewayConfig(){
        GatewayCallbackManager.setBlockHandler( new BlockRequestHandler() {
            @Override
            public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
                Map<String,Object> map=new HashMap<>();
                map.put("state",429);
                map.put("message","two many request");
                String jsonStr=JSON.toJSONString(map);
                return ServerResponse.ok().body(Mono.just(jsonStr),String.class);
            }
        });
    }
}

Where Mono is a Publisher object that emits 0-1 elements.

Section interview analysis?

The gateway level combines sentinel to realize current limiting. How many types of current limiting are there? (two - route id,api)
Can the gateway level customize the exception handling results after current limiting? (yes)
Do you know the current limiting algorithms at Sentinel bottom? (sliding window, token bucket, funnel

Core knowledge points

Background of API gateway
Market mainstream micro service gateway (Spring Cloud Gateway,zuul,...)
API Gateway realizes service protection and forwarding (key)
Implementation of load balancing at API Gateway level (emphasis, LB: / / SCA provider)
Principle analysis of API Gateway request processing (key points: Official diagram, understanding of key codes and execution process)

Summary

Analysis of key and difficult points

What is the background of the birth of gateway? (first: unified access to microservices; second: protection of system services; third, unified authentication, authorization and current restriction)
Gateway selection? (Netifix Zuul,Spring Cloud Gateway,…)
Entry implementation of Spring Cloud Gateway (add dependency, route configuration, startup class)
Load balancing in Spring Cloud Gateway? (gateway service registration, service discovery, accessing specific service instances based on uri:lb: / / service id)
Assertion configuration in Spring Cloud Gateway? (it's enough to master the common ones. You can check them through the search engine)
Filter configuration in Spring Cloud Gateway? (master the two types of filters - local and global)
Current limiting design in Spring Cloud Gateway? (Sentinel)

FAQ analysis

Where is Gateway in the Internet architecture? (nginx - > Gateway – > microservices – > microservices)
Implementation of Gateway underlying load balancing? (Ribbon)
What are the main concepts of Gateway application design? (routing id, routing uri, assertion, filter)
What assertion configurations have you made in the Gateway? (after,header,path,cookie,…)
What filters do you use in the Gateway? (add prefix, remove prefix, add request header,..., load balancing,...)

BUG analysis

503 abnormal? (if the service is unavailable, check whether the service you call is started ok and whether the routing uri is written correctly)
Resolve at startup yml configuration file is abnormal (the format is not aligned, and the words are written incorrectly)

Keywords: Java Spring Cloud gateway microservice

Added by BTalon on Sun, 20 Feb 2022 09:07:52 +0200