至此微服务网关系列文章已出:
- 【云原生&微服务>SCG网关篇一】为什么要有网关、生产环境如何选择网关
- 云原生&微服务>SCG网关篇二】生产上那些灰度发布方式
聊了以下问题:
- 为什么要有网关?网关的作用是什么?
- 网关的分类?
- 网关的技术选型?
- 使用网关时常用的灰度发布方式有哪些?
本文接着聊SpringCloud生态中的SpringCloudGateway是什么?并给出详细使用案例?
官方文档:https://docs.spring.io/spring-cloud-gateway/docs/3.0.1/reference/html/。
Spring Cloud Gateway 是Spring Cloud的第二代网关,用于替换Zuul;基于Netty、Reactor以及WebFlux构建。
1> 优点:
2> 缺点:
路由(Route):路由是⽹关最基础的部分,路由信息由⼀个ID、⼀个目标URL、⼀组断⾔Predicate
和⼀组Filter组成。如果断⾔路由为真,则说明请求的URL和配置匹配;也可以吧路由理解为一条请求转发规则。
- ID:编号,路由的唯⼀标识;
- URI:路由指向的⽬标 URI,即请求最终被转发的⽬的地。
- Predicate:断言 / 谓语,作为路由的匹配条件。
- Filter:过滤器,对请求和响应进⾏拦截,实现⾃定义的功能。
断⾔/谓词(Predicate):Spring Cloud Gateway使用Predicate
作为路由的匹配条件;Gateway 内置了多种 Predicate 的实现,提供了多种请求的匹配条件,⽐如说基于请求的 Path、Method 等等。
即java.util.function.Predicate
过滤器(Filter):过滤器Filter会对请求和响应进行拦截处理,实现自定义的功能;Gateway 内置了多种 Filter 的实现,提供了多种请求的处理逻辑,⽐如说限流、熔断等等。
此外,Spring Cloud Gateway启动时基于Netty Server 监听一个指定的端口(可以通过server.port属性自定义),Client的请求都会先打到Netty Server,然后再走到Predicates、Filters,最后走一层Netty proxy将请求转发到指定的微服务。
整体项目目录包括两个Module,分别为:gateway-center、simple-service。
其中gateway-center作为路由网关、simple-service作为一个普通的微服务被整合到Gateway中。
spring-cloud-alibaba-center项目下只保留一个跟pom,用于做整体项目的maven依赖管理
<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">
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.4.2version>
<relativePath/>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>spring-cloud-alibaba-centerartifactId>
<groupId>com.saintgroupId>
<version>0.0.1-SNAPSHOTversion>
<name>spring-cloud-alibaba-centername>
<packaging>pompackaging>
<modules>
<module>gateway-centermodule>
<module>simple-servicemodule>
modules>
<properties>
<java.version>1.8java.version>
<spring-boot.version>2.4.2spring-boot.version>
<spring-cloud.version>2020.0.1spring-cloud.version>
<spring-cloud-alibaba.version>2021.1spring-cloud-alibaba.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>${spring-boot.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring-cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-dependenciesartifactId>
<version>${spring-cloud-alibaba.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<configuration>
<source>1.8source>
<target>1.8target>
<encoding>UTF-8encoding>
configuration>
plugin>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
其整体很简单、仅仅包含一个pom.xml文件、一个application.yml配置文件、一个启动类、一个Controller。
<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">
<parent>
<artifactId>spring-cloud-alibaba-centerartifactId>
<groupId>com.saintgroupId>
<version>0.0.1-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>simple-serviceartifactId>
<version>0.0.1-SNAPSHOTversion>
<description>gateway-simple-servicedescription>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
project>
这里仅仅是设置服务的端口和程序名称。
server:
port: 9001
spring:
application:
name: simple-service
package com.saint.simple;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Saint
*/
@SpringBootApplication
public class SimpleServiceApplication {
public static void main(String[] args) {
SpringApplication.run(SimpleServiceApplication.class, args);
}
}
就一个很普通的启动类。
其中包含一个pom.xml文件、一个application.yml配置文件、一个启动类;
<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">
<parent>
<artifactId>spring-cloud-alibaba-centerartifactId>
<groupId>com.saintgroupId>
<version>0.0.1-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>gateway-centerartifactId>
<version>0.0.1-SNAPSHOTversion>
<description>gateway-centerdescription>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
dependencies>
project>
server:
port: 9999
spring:
application:
name: gateway-center
cloud:
gateway:
routes:
- id: simple_service_route
uri: http://127.0.0.1:9001
predicates:
# 路径匹配规则,向http://localhost:9999/gateway/simple-service/路径发送请求时,将会被转发到http://localhost:9001
- Path=/gateway/simple-service/**
filters:
# StripPrefix参数表示在将请求发送到下游之前从请求中剥离的路径个数。
# 如果设置StripPrefix=2,则当通过网关向/gateway/simple-service/hello发出请求时,对simple-service的请求将类似于/hello。
- StripPrefix=2
application.yml配置文件中配置了一个Filter(StripPrefix
),其表示在将请求发送到下游之前从请求路径(Predicate中的配置的Path)中剥离的路径个数;
以当前配置为例,Predicate中配置的Path为/gateway/simple-service/**
,StripePrefix的值为2,当我们要通过gateway接收一个请求时,请求为:http://127.0.0.1:9999/gateway/simple-service/hello/sayHello
,则转发到http://127.0.0.1:9001
上的请求地址为:http://127.0.0.1:9001/hello/sayHello
。
package com.saint.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Saint
*/
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
启动成功后,控制台输出如下:
可以看到Gateway对外提供服务的Netty Server端口号为我们自定义的9999;
上述步骤中,我们已经依次启动了simple-service、gateway-center;有两种方式可以访问到simple-service。
1> 直接访问simple-service:
2> 通过Gateway访问simple-service:
目前一般SpringCloud生态都会选择使用Spring Cloud Gateway,当然也存在一些老项目至今仍在使用Zuul;Spring Cloud Gateway由WebFlux + Netty + Reactor组成,旨在为微服务架构提供⼀种简单且有效的API路由管理⽅式,并基于Filter的⽅式提供⽹关的基本功能,例如说安全认证、监控、限流。
另外:Spring Cloud Gateway是一个基于响应式的API业务⽹关。
后续博文我们继续聊Spring Cloud Gateway Predicate的使用