SpringCloud-GateWay new generation routing gateway

Tell me about your understanding of the microservice gateway, which one do you choose for your microservice gateway, why you use GateWay, and why GateWay is better than zuul

Gateway: Spring Cloud API gateway component (very detailed)

The difference between nginx gateway and gateway gateway

SpringCloud GateWay official website

Chinese version of SpringCloud GateWay official website

overview

What is Spring Cloud Gateway

A very important component in the Cloud family bucket is the gateway, which was used in the 1.x version as the Zuul gateway;
but in the 2.x version, the upgrade of zuul kept skipping tickets, and SpringCloud finally developed a gateway to replace Zuul. ,
that is a sentence of SpringCloud Gateway: gateway is a replacement for the original zuul1.x version
insert image description here

brief description

Gateway is an API gateway service built on top of the Spring ecosystem, based on technologies such as Spring 5, Spring Boot 2 and Project Reactor.
Gateway aims to provide a simple and effective way to route APIs, and provide some powerful filter functions, such as: fuse, current limit, retry, etc.

SpringCloud Gateway is a brand new project of Spring Cloud, based on Spring 5.0+Spring Boot 2.0 and Project Reactor and other technologies, it aims to provide a simple and effective unified API routing management method for microservice architecture.

As a gateway in the Spring Cloud ecosystem, SpringCloud Gateway aims to replace Zuul. In Spring Cloud 2.0 and above, it does not integrate the latest high-performance versions of Zuul 2.0 and above, and still uses Zuul 1.x non-Reactor mode old version of . In order to improve the performance of the gateway, Spring Cloud Gateway is implemented based on the WebFlux framework, and the bottom layer of the WebFlux framework uses the high-performance Reactor mode communication framework Netty.

The goal of Spring Cloud Gateway is to provide a unified routing method and provide basic functions of the gateway based on the Filter chain, such as: security, monitoring/indicators, and current limiting .

Summary: The reactor-netty responsive programming component in Webflux used by SpringCloud Gateway uses the Netty communication framework at the bottom

Gateway integrates webflux and reactor-netty, both of which are high-performance frameworks for non-blocking responsive programming
insert image description here

Architectural location of the microservice gateway

Among them, the load balancing is Nginx, and the gateway cluster is the entrance of all microservices.

insert image description here

With Zuul, why did the gateway come out again?

1. Neflix is ​​unreliable, zuul2.0 has been skipping tickets, and has not been released for a long time

On the one hand, because Zuul 1.0 has entered the maintenance stage, and the Gateway is developed by the SpringCloud team, it is a pro-son product and is trustworthy.
And many functions Zuul is not used and it is very simple and convenient.

Gateway is developed based on an asynchronous and non-blocking model, so there is no need to worry about performance. Although Netflix has released the latest Zuul 2.x long ago,
Spring Cloud seems to have no integration plan. Moreover, Netflix-related components have announced that they have entered the maintenance period; what is the future?

Considering many aspects, Gateway is an ideal gateway choice.

2. Spring Cloud Gateway has the following features.
It is built based on Spring Framework 5, Project Reactor and Spring Boot 2.0;
dynamic routing: it can match any request attribute;
you can specify Predicate (assertion) and Filter (filter) for routing;
integrated Hystrix circuit breaker Function;
integrated Spring Cloud service discovery function;
easy-to-write Predicate (assertion) and Filter (filter);
request current limiting function;
support path rewriting.
3. The difference between SpringCloud Gateway and Zuul
Before the official version of SpringCloud Finchley, the gateway recommended by Spring Cloud was Zuul provided by Netflix:

1. Zuul 1.x is an API Gateway based on blocking I/O

2. Zuul 1.x is based on Servlet 2.5 and uses blocking architecture. It does not support any long connection (such as WebSocket). The design pattern of Zuul is similar to Nginx. The thread is blocked until the worker thread is completed, but the difference is that Nginx is implemented in C++, Zuul is implemented in Java, and the JVM itself will be loaded slowly for the first time, making Zuul's performance relatively poor.

3. The concept of Zuul 2.x is more advanced. It wants to be based on Netty non-blocking and support long connections, but SpringCloud has not yet been integrated. The performance of Zuul 2.x has been greatly improved compared with Zuul 1.x. In terms of performance, according to the official benchmark test, the RPS (requests per second) of Spring Cloud Gateway is 1.6 times that of Zuul.

4. Spring Cloud Gateway is built on Spring Framework 5, Project Reactor and Spring Boot 2, using non-blocking API.

5. Spring Cloud Gateway also supports WebSocket, and is tightly integrated with Spring to have a better development experience

Zuul1.x model

The Zuul version integrated in Springcloud uses the Tomcat container and uses the traditional Servlet IO processing model.

Everyone who has studied the mid-term course of Silicon Valley web knows a topic, the life cycle of Servlet? Servlet is managed by the life cycle of servlet container.
When the container starts, it constructs a servlet object and calls servlet init() for initialization;
when the container runs, it accepts requests and allocates a thread for each request (generally obtains an idle thread from the thread pool) and then calls service().
When the container is closed, call servlet destroy() to destroy the servlet;

Disadvantages of the above model:
servlet is a simple network IO model. When a request enters the servlet container, the servlet container will bind a thread for it. This model is applicable in scenarios where the concurrency is not high. But once the concurrency is high (such as using jemeter to press the wind), the number of threads will increase, and the cost of thread resources is expensive (online text switching, large memory consumption) which seriously affects the processing time of requests. In some simple business scenarios, it is not desirable to allocate a thread for each request, and only one or a few threads can handle extremely concurrent requests. In this business scenario, the servlet model has no advantage

So Zuul 1.X is a blocking processing model based on servlets, that is, spring implements a servlet (DispatcherServlet) that handles all requests and is processed by the servlet blocking processing. So Springcloud Zuul can't get rid of the disadvantages of servlet model

GateWay model

Traditional web frameworks, such as struts2, springmvc, etc., all run on the basis of Servlet API and Servlet container.
But
after Servlet3.1, there is asynchronous non-blocking support (webflux and reactor-netty) . WebFlux is a typical non-blocking asynchronous framework, and its core is implemented based on Reactor's related APIs. Compared with traditional web frameworks, it can run on containers such as Netty, Undertow and Servlet3.1. Non-blocking + functional programming (Spring5 must let you use java8)

Spring WebFlux is a new responsive framework introduced by Spring 5.0. Different from Spring MVC, it does not need to rely on the Servlet API. It is completely asynchronous and non-blocking, and implements the responsive flow specification based on Reactor.

Three Core Concepts

Route

Routing is the basic module of building a gateway. It consists of ID, target URI, a series of assertions and filters. If the assertion is true, the route will be matched.

Predicate

The reference is Java8's java.util.function.Predicate
Developers can match everything in the HTTP request (such as request headers or request parameters), and route if the request matches the assertion

Filter

Refers to the instance of GatewayFilter in the Spring framework. Using filters, requests can be modified before or after they are routed.

Summarize

insert image description here

The web request is located to the real service node through some matching conditions. And before and after this forwarding process, some fine-grained control is carried out.
The predicate is our matching condition;
and the filter can be understood as an omnipotent interceptor. With these two elements, plus the target uri, a specific route can be realized

Gateway workflow

Core logic : route forwarding + execution filter chain
insert image description here
The client sends a request to Spring Cloud Gateway. Then find the route that matches the request in Gateway Handler Mapping and send it to Gateway Web Handler.

Handler then sends the request to our actual service to execute business logic through the specified filter chain, and then returns.
Filters are separated by dotted lines because filters may perform business logic before ("pre") or after ("post") the proxy request is sent.

Filter in the "pre" type filter can perform parameter verification, authority verification, flow monitoring, log output, protocol conversion, etc.,
in the "post" type filter can modify the response content, response header, log Output, traffic monitoring, etc. play a very important role.

Getting Started Configuration

add dependencies

    <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>
        <!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--一般基础配置类-->
        <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>

configuration file

GateWay is also a service, and it must also be registered in the eureka service management center

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8001          #匹配后提供服务的路由地址(要转发的ip)
          predicates:
            - Path=/payment/get/**         # 断言,路径相匹配的进行路由(接口地址)

        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8001          #匹配后提供服务的路由地址(要转发的ip)
          predicates:
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由(接口地址)

eureka:
  instance:
    hostname: cloud-gateway-service
  client: #服务提供者provider注册进eureka服务列表内
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka7001.com:7001/eureka

Add spring☁️gateway: routes: configuration in the GateWay service module to configure the service to be forwarded.
Access before adding the gateway: http://localhost:8001/payment/get/31
Access after adding the gateway: http://localhost: 9527/payment/get/31 can also access the interface of 8001
insert image description here

There are two ways to configure Gateway routing:

1. Configure in yml as above (usually using yml configuration)
2. Inject the RouteLocator Bean into the code
Example: Access the Baidu News website on the external network through the 9527 gateway just now
Add configuration file: GateWayConfig

Explanation:
path_route_atguigu is a name given by myself
Access: http://localhost:9527guonei will be forwarded to http://news.baidu.com/guonei

package com.atguigu.springcloud.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @auther zzyy
 * @create 2020-02-21 11:42
 */
@Configuration
public class GateWayConfig
{
    
    
    /**
     * 配置了一个id为route-name的路由规则,
     * 当访问地址 http://localhost:9527/guonei时会自动转发到地址:http://news.baidu.com/guonei
     * @param builder
     * @return
     */
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder)
    {
    
    
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();

        routes.route("path_route_atguigu",
                r -> r.path("/guonei")
                        .uri("http://news.baidu.com/guonei")).build();
        return routes.build();
    }
}

Realize dynamic routing through microservice names

By default, Gateway will create a dynamic route based on the service list registered by the registry,
and use the microservice name on the registry to create a dynamic route for forwarding, thereby realizing the function of dynamic routing

Modify the application.yml configuration file
and add the discovery configuration to enable the function of dynamically creating routes from the registry
uri: lb:// Service name of the service provider
insert image description here

server:
 port: 9527

spring:
 application:
   name: cloud-gateway
 cloud:
   gateway:
     discovery:
       locator:
         enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
     routes:
       - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
         # uri: http://localhost:8001          #匹配后提供服务的路由地址
         uri: lb://cloud-payment-service #匹配后提供服务的路由地址(服务提供方的服务名称)
         predicates:
           - Path=/payment/get/**         # 断言,路径相匹配的进行路由

       - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
         # uri: http://localhost:8001          #匹配后提供服务的路由地址
         uri: lb://cloud-payment-service #匹配后提供服务的路由地址
         predicates:
           - Path=/payment/lb/**         # 断言,路径相匹配的进行路由

eureka:
 instance:
   hostname: cloud-gateway-service
 client: #服务提供者provider注册进eureka服务列表内
   service-url:
     register-with-eureka: true
     fetch-registry: true
     defaultZone: http://eureka7001.com:7001/eureka

Predicate (assertion) use

insert image description here

Spring Cloud Gateway uses route matching as part of the Spring WebFlux HandlerMapping infrastructure.
Spring Cloud Gateway includes a number of built-in Route Predicate factories. All of these Predicates match different attributes of the HTTP request. Multiple Route Predicate factories can be combined

When Spring Cloud Gateway creates a Route object, it uses RoutePredicateFactory to create a Predicate object, and the Predicate object can be assigned to Route. Spring Cloud Gateway includes a number of built-in Route Predicate Factories.

All of these predicates match different attributes of the HTTP request. Various predicate factories can be combined and passed a logical and.

In human terms: You can add some filter configurations in yml, if the request comes, if it meets the configuration conditions, it can be forwarded, if it does not meet the filter conditions, access is not allowed

take effect after a certain time

For example, if a certain service forwarding is required to take effect after a certain time, and access is not allowed for a long time before this time, you can use
(- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai])
insert image description here
to pay attention to the following Time format, must be written like this, you can get this time format through the following code

        ZonedDateTime zbj = ZonedDateTime.now(); // 默认时区
        System.out.println(zbj);
        // 亚洲上海
        // 2022-06-03T18:48:23.118+08:00[Asia/Shanghai]
Restrict cookie access

insert image description here

You can use the curl command to simulate request access in cmd

curl http://localhost:9588/paymentInfo --cookie "username=zzyy"

insert image description here

limit request header

insert image description here
insert image description here

Limit request method

insert image description here
insert image description here

The use of Filter filter

Route filters can be used to modify incoming HTTP requests and returned HTTP responses, and route filters can only be used for specified routes.

Spring Cloud Gateway has a variety of built-in routing filters, all of which are generated by the factory class of GatewayFilter

life cycle

  1. pre before business logic
  2. post business logic

type

  1. GatewayFilter single
  2. GlobalFilter global

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#the-addrequestparameter-gatewayfilter-factory

custom filter

What can custom filters be used for?

  1. Global logging
  2. Unified Gateway Authentication

Two main interfaces: implements GlobalFilter,Ordered

package com.atguigu.springcloud.filter;

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;
import java.util.Date;

/**
 * @auther zzyy
 * @create 2020-02-06 18:21
 */
@Component //必须加,必须加,必须加
public class MyLogGateWayFilter implements GlobalFilter,Ordered
{
    
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
    {
    
    
        System.out.println("time:"+new Date()+"\t 执行了自定义的全局过滤器: "+"MyLogGateWayFilter"+"hello");

        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if (uname == null) {
    
    
            System.out.println("****用户名为null,无法登录");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

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

Guess you like

Origin blog.csdn.net/qq_44154912/article/details/125113696