What is a gateway

Let’s say you want to make an e-commerce application, with a mobile APP at the front end and various micro-services at the back end. Then you might need to call data from multiple services to display a page. Without a gateway, your system would look like this:

If you add gateways, your system looks like this:

Spring Cloud Gateway

Spring Cloud Gateway is a new Project of Spring Cloud, which is based on Spring 5.0, Spring Boot 2.0 and Project Reactor technology development Gateway. It aims to provide a simple and effective unified API route management approach for microservices architecture.

As a Gateway in the Spring Cloud ecosystem, Spring Cloud Gateway aims to replace Netflix Zuul. It not only provides a unified routing mode, but also provides basic Gateway functions based on Filter chain, such as: Security, monitoring/metrics, and flow limiting.

Relevant concepts

  • Route: This is the basic building block of a gateway. It is defined by an ID, a target URI, a set of assertions, and a set of filters. If the assertion is true, the route matches.
  • Predicate: This is a Java 8 Predicate. The input type is a ServerWebExchange. We can use it to match anything from an HTTP request, such as headers or parameters.
  • Filter (Filter) : this is org. Springframework. Cloud. Gateway. Filter. GatewayFilter instance, we can use it to modify the request and response.

The working process

(PS: If this looks familiar, yes, it looks like SpringMVC’s request processing)

  • Requests are sent to the gateway and the DispatcherHandler is the central dispatcher for HTTP requests, taking over the requests and matching them to the appropriate HandlerMapping.

  • Request and there is a mapping relationship between the processor and the gateway will be routed to request, handler will match to RoutePredicateHandlerMapping here, matching request corresponding to the Route.

  • This WebHandler then reaches the gateway’s Web processor, which proxies a number of instances of gateway filters and global filters, such as Header processing (adding or removing a Header) for requests or responses.

  • Finally, forward to the specific proxy service.

In short:

Quick start

1. Create a project, gatewayTest, and add three modules to the projecteureka,producer,gateway

The project structure

2.rureka

The new module

Add eureka dependencies

 <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
 </dependency>
Copy the code

Complete the pom

<? 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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> < modelVersion > 4.0.0 < / modelVersion > < groupId > com. Example. Eureka < / groupId > < artifactId > eureka < / artifactId > <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name> Eureka </name> <description>Demo projectforSpring Boot</description> <parent> <groupId>com.gateway.test</groupId> <artifactId>gatewayTest</artifactId> < version > 1.0 - the SNAPSHOT < / version > < relativePath >). </relativePath> <! -- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>Copy the code

The configuration file

spring:
  application:
    name: eureka

server:
  port: 8761
eureka:
  instance:
    hostname: localhost
  client:
    fetch-registry: false
    register-with-eureka: false
    service-url:
      defaultZone: http://localhost:8761/eureka/

Copy the code

Start the class

package com.example.eureka.eureka; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer @SpringBootApplication public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); }}Copy the code

To launch the program, visit http://localhost:8761/

3.producer

Creating a Module from Producer is the same as creating a Rureka, as shown below.

Complete the pom

<? 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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> < modelVersion > 4.0.0 < / modelVersion > < groupId > com. Example. Producer < / groupId > < artifactId > producer < / artifactId > < version > 0.0.1 - the SNAPSHOT < / version > < name > producer < / name > < description > Demo projectforSpring Boot</description> <parent> <groupId>com.gateway.test</groupId> <artifactId>gatewayTest</artifactId> < version > 1.0 - the SNAPSHOT < / version > < relativePath >). </relativePath> <! -- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>Copy the code

The configuration file

spring:
  application:
    name: producer
server:
  port: 8081

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
Copy the code

Start the class

package com.example.producer.producer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @EnableEurekaClient @SpringBootApplication public class ProducerApplication { public static void main(String[] args) { SpringApplication.run(ProducerApplication.class, args); }}Copy the code

Create two class controllers

HelloController

@RestController
@RequestMapping("/hello")
public class HelloController {

    @RequestMapping("say")
    public String say() {
        return "Hello Every Buddy"; }}Copy the code

GoodByeController

@RestController
@RequestMapping("/goodbye")
public class GoodByeController {

    @RequestMapping("say")
    public String say() {
        return "Bye Bye"; }}Copy the code

To launch the program, visit http://localhost:8761/

4.gateway

The creation process is the same as eureka complete POM

<? 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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> < modelVersion > 4.0.0 < / modelVersion > < groupId > com. The example. The gateway < / groupId > < artifactId > gateway < / artifactId > < version > 0.0.1 - the SNAPSHOT < / version > < name > gateway < / name > < description > Demo projectforSpring Boot</description> <parent> <groupId>com.gateway.test</groupId> <artifactId>gatewayTest</artifactId> < version > 1.0 - the SNAPSHOT < / version > < relativePath >). </relativePath> <! -- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</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-netflix-hystrix</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>Copy the code

The configuration file

test:
  uri: lb://producer

spring:
  application:
    name: gateway
# cloud:
# gateway:
# routes:
# - id: route_producer_hello
# uri: ${test.uri} # URI starts with lb:// (lb stands for service from the registry), followed by the name of the service you need to forward to
# predicates:
# - Path=/api-hello/**
# filters:
# -stripprefix =1 # indicates that the API is removed when forwarding
#
# - id: route_producer_goodbye
# uri: ${test.uri}
# predicates:
# - Path=/api-goodbye/**
# filters:
# - StripPrefix=1
# - name: Hystrix
# args:
# name: myfallbackcmd
# fallbackUri: forward:/user/fallback


server:
  port: 8080

logging:
  level:
    org.springframework.cloud.gateway: TRACE
    org.springframework.http.server.reactive: DEBUG
    org.springframework.web.reactive: DEBUG
    reactor.ipc.netty: DEBUG
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
    enabled: true The default value is true, and false is not enabled
  instance:
    prefer-ip-address: true

Copy the code

Start the class

package com.example.gateway.gateway;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class GatewayApplication {

    @Value("${test.uri}")
    private String uri;

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder){
        return builder.routes()
                .route(r ->r.path("/hello/**").uri(uri))
                .route(r ->r.path("/goodbye/**").uri(uri)).build(); } public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); }}Copy the code

To launch the program, visit http://localhost:8761/

5. Test

Services are registered with Reureka. We define that requests starting with hello and Goodbye will be forwarded to LB :// Producer service. We define port 8080 for gateway. Producer of the port is 8081 direct request producer service http://localhost:8081/hello/say

http://localhost:8081/goodbye/say

Through the gateway request at http://localhost:8080/hello/say

http://localhost:8080/goodbye/say

Load balancing of the gateway

Then there is only one gateway for all micro services. What if the amount of concurrency goes up and the gateway cannot bear it? The Spring Cloud Gateway is based on Netty, and it can handle a lot of concurrency. If you still can’t handle the concurrency, register multiple Gateway instances and put an Nginx or F5 load balancer in front of you. Here’s the rough picture:

Personal blog

Tencent Cloud Community

CSDN

Jane’s book

The public no. :