Preface
Spring Cloud Gateway is based on Spring Boot 2 and is a new project of Spring Cloud. Gateway is designed to provide a simple and efficient way to forward requests and provide cross-cutting concerns for them.
The gateway is equivalent to the portal of all services, which separates client requests from server applications. After client requests pass through the gateway, they are forwarded by defined routes and assertions. The routes represent the addresses to which the requests need to be forwarded. The assertions are equivalent to the requests for these addresses. If the conditions are met, it will be forwarded only if it meets both routing and assertion.
This blog introduces the basic concepts of Spring Cloud Gateway, matters needing attention when introducing dependencies, and solutions; there are also introductory use cases for global gateways.
Table of contents
lead out
1. Basic concepts of Spring Cloud Gateway;
2. Things to note when introducing dependencies, and solutions;
3. Introductory use cases for global gateways;
gatewaygateway
What is a gateway?
API gateway is a service and the only entrance to the system. From an object-oriented design perspective, it is similar to the facade pattern. The API gateway encapsulates the internal architecture of the system and provides a customized API for each client. It may also have other responsibilities such as authentication, monitoring, load balancing, throttling, degradation and application detection.
Spring Cloud Gateway is based on Spring Boot 2 and is a new project of Spring Cloud. Gateway is designed to provide a simple and efficient way to forward requests and provide cross-cutting concerns for them.
The most important concepts in Spring Cloud Gateway:
-
Routing Route: Routing is the most basic part of the gateway. Routing information consists of an ID, a destination URL, a set of assertion factories and a set of Filters. If the route assertion is true, it means that the requested URL matches the configured route.
-
Predicate: Assertion function in Java 8. The input type of the assertion function in Spring Cloud Gateway is ServerWebExchange in the Spring 5.0 framework. The assertion function in Spring Cloud Gateway allows developers to define matches for any information from Http Request, such as request headers and parameters.
-
Filter: A standard Spring Web Filter. Filters in Spring Cloud Gateway are divided into two types: Gateway Filter and Global Filter. Filter Filter will modify the request and response.
zuul---->SpringCloud,gateway---->zuul2.0
Past practice: Eureak + zuul2.0 + config
Current practice: SpringCloud-nacos + gateway, rocketMQ/ RabbitMQ /ActiveMQ
Introducing dependencies and basic operating modes
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
Analysis of configuration file access process
Parameter explanation
If you use springmvc, you need to set it up
Method 1: Configuration file
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.tianju</groupId>
<artifactId>spring-cloud-move</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.tianju.gateway</groupId>
<artifactId>movie-gateway</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 如果需要用web,则需要排除一下tomcat-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 打包成可运行的jar包-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Configuration file solution
spring:
cloud:
# nacos的部分
nacos:
discovery: # 注册中心
server-addr: http://192.168.111.130:8848/
register-enabled: true
# 网关部分
gateway:
discovery:
locator:
enabled: true # 允许定位
routes: # 路由
- id: my-hello-id # id要唯一
uri: lb://movie-cinema/api # 在nacos里根据服务名称找
predicates:
# http://localhost:18888/hello-wx/api/cinema/checkGenreInThisCinema
- Path=/hello-wx/** # 比如输了 ip+端口/hello-wx/** 然后在nacos找真的路径
filters:
- StripPrefix=1 # 替换第一个,内置的filter过滤器
- id: my-hello-baidu # id要唯一
uri: https://www.sohu.com
predicates:
# http://localhost:18888/hello-ly
- Path=/hello-ly/**
# 如要要用spring web,则把tomcat排除一下
main:
web-application-type: reactive
Started is tomcat
Method 2: Exclude tomcat
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
global gateway
package com.tianju.gateway.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class AuthGateway implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.debug("我是全局过滤器>>>>>>>>>>");
return null;
}
@Override
public int getOrder() {
return 0;
}
}
package com.tianju.gateway.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class AuthGateway implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.debug("我是全局过滤器>>>>>>>>>>");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
Gateway related code
1. Import dependencies
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.tianju</groupId>
<artifactId>spring-cloud-move</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.tianju.gateway</groupId>
<artifactId>movie-gateway</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 如果需要用web,则需要排除一下tomcat-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.tianju.common</groupId>
<artifactId>movie-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 打包成可运行的jar包-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.Configure config
bootstrap.yml file
spring:
cloud:
# nacos的部分
nacos:
discovery: # 注册中心
server-addr: http://192.168.111.130:8848/
register-enabled: true
# 网关部分
gateway:
discovery:
locator:
enabled: true # 允许定位
routes: # 路由
- id: my-hello-id # id要唯一
uri: lb://movie-cinema/api # 在nacos里根据服务名称找
predicates:
# http://localhost:18888/hello-wx/api/cinema/checkGenreInThisCinema
- Path=/hello-wx/** # 比如输了 ip+端口/hello-wx/** 然后在nacos找真的路径
filters:
- StripPrefix=1 # 替换第一个,内置的filter过滤器
- id: my-hello-baidu # id要唯一
uri: https://www.sohu.com
predicates:
# http://localhost:18888/hello-ly
- Path=/hello-ly/**
# 如要要用spring web,则把tomcat排除一下
main:
web-application-type: reactive
application.yml
server:
port: 18888
spring:
application:
name: movie-gateway
logging:
level:
com.tianju.gateway: debug
3.Gateway AuthGateway
package com.tianju.gateway.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tianju.common.result.HttpResp;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
@Component
@Slf4j
// http://localhost:18888/hello-wx/api/cinema/checkGenreInThisCinema
public class AuthGateway implements GlobalFilter, Ordered {
@Override
@SneakyThrows
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.debug("我是全局过滤器>>>>>>>>>>");
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
// 请求request 的URL:http://localhost:18888/hello-wx/api/cinema/checkGenreInThisCinema
log.debug("请求request 的URL:"+request.getURI());
log.debug("请求request 数据"+request.getHeaders().get("jwt"));
// String jwt = "请求request 数据" + request.getHeaders().get("jwt").get(0);
if (Objects.isNull(request.getHeaders().get("jwt"))){
// 如果没有携带token
response.setStatusCode(HttpStatus.UNAUTHORIZED);
ObjectMapper objectMapper = new ObjectMapper();
DataBuffer buffer = response.bufferFactory()
.wrap(objectMapper.writeValueAsString(HttpResp.failed("没有jwt"))
.getBytes(StandardCharsets.UTF_8));
return response.writeWith(Mono.just(buffer));
}else {
return chain.filter(exchange);
}
}
@Override
public int getOrder() {
return 0;
}
}
4. Main startup class
package com.tianju.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApp {
public static void main(String[] args) {
SpringApplication.run(GatewayApp.class);
}
}
Summarize
1. Basic concepts of Spring Cloud Gateway;
2. Things to note when introducing dependencies, and solutions;
3. Introductory use cases for global gateways;