SpringCloud(五)——Gateway
前言
Gateway,意为网关。在SpringCloud中,gateway共有两个方面的概念:断言(predicate)、过滤器(filter),二者共同作用完成网关的相关功能。
从大方向来说明,gateway的主要作用不单单是对请求的一些预先处理或对请求的负载均衡转发,它更主要的功能还是在系统安全以及对前后端分离方面的贡献(文中会逐步说明)。
概述
Gateway为我们提供了两种配置方式:Java配置类、配置文件。这两种配置逻辑相同,只不过Java配置类的优先级要高于配置文件;但配置文件的配置方式要比Java配置类简单一些。官方推荐我们使用配置文件的方式来配置Gateway,不过在实际开发的选择中需要按照实际业务需要来进行选择。
Gateway中的断言(predicate)是用来处理规定请求应该转发到哪个服务以及该请求应该具备的规则;过滤器(filter)表示在符合断言的规则后需要执行的filter操作。
断言(predicate)和过滤器(filter)的执行顺序是先断言,后过滤器,而在断言和过滤器中内部的执行顺序有权重来决定。
Gateway使用
Gateway在使用的时候也需要创建一个项目来运行网关的项目,基础准备依旧是在父项目中创建一个Maven项目,在其中引入SpringCloud的相关依赖,尤其要将consul
引入,网关的请求转发需要从注册中心获取服务列表。
基本搭建
- 引入依赖
<!--网关中无法使用SpringMVC模型,所以需要将SpringMVC依赖去掉-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
- 入口类加入注解
@SpringBootApplication
@EnableDiscoveryClient // 网关需要从注册中心中获取服务列表
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class,args);
}
}
- 书写配置(先从配置文件开始说明)
spring:
cloud:
gateway:
# 配置网关路由
routes:
- id: test_router # 路由的唯一标识
# uri: http://localhost:8087
uri: lb://TEST # 实现请求的负载均衡(在consul中根据提供的服务ID获取服务列表)
predicates: # 表示断言(先用来配置路由规则)
- Path=/test
# - Path=/test/**
上述配置中,我们通过断言中配置的Path的值,这个值代表我们在浏览器中访问gateway
项目的时候访问这个路径会直接被转发到Test
服务的集群中,并按照默认的负载均衡的规则来选择对应的服务调用。
需要注意的是,我们的Test
服务中,需要有一个名为请求路径test
的接口,因为predicate
中对于转发的请求的时候会将我们申请的路径拼接在转发路径的后面。所以为了调用服务方便,一般在同一标识符的后面添加/**
来表示任何前缀为/test
的路径都被这个断言(predicate)读取到并执行对应的操作。
断言细节
在断言中还可以添加很多匹配的规则,比如对于该请求的请求头、cookie等要求,具体如下所示:
predicates: # 表示断言(先用来配置路由规则)
- Path=/test
# 指定请求需要加上cookie(win10系统可以使用系统预装的 curl 指令,或者使用postman软件来操作)
- Cookie=name,[A-Za-z0-9]+ # 该正则表达式表示由大小写字母和数字组成
- Header=X-Request-Id,\d+ # \d+ 表示数字
# 规定该请求的请求方式
- Method=GET
上述的断言规则中,表示我们需要在请求中包含cookie
和请求头,并且我们需要保证该请求方式为GET。测试这个配置有两种办法,一下会做介绍:
curl(windows10预装组件)
我们可以使用windows10
中预装的curl
组件来操作,具体步骤如下:
-
打开命令控制符窗口
-
在界面中输入一下规则的语句:
curl http://${网关路径}/${断言中规定的服务路径} --cookie "name=123"
这样我们就可以在命令提示符窗口中接收到请求的借口为我们返回的数据,如果我们不添加cookie到请求中,则会报错。
同理,如果规定了请求头的断言,我们依旧可以使用该组件来操作:
curl http://${网关路径}/${断言中规定的服务路径} --header "X-Request-Id:1"
PostMan使用
postman的基本使用不在这里讲解(熟悉我的人都知道,我懒),大家可以随便找一个教程去学习,很简单。
在这里就不给大家做演示了。
Java配置类
前文说过,gateway的配置除了配置文件以外还可以书写Java配置类,而这两种配置方式逻辑一致,在此不做赘述,大家都看得懂,具体如下:
@Configuration
public class GatewayConfig {
private static String Test1_Path =
"/test1"
;
private static String Test2_Path =
"/test2"
;
// Java代码优先于配置文件
// 官方推荐使用配置文件的方式配置网关
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder){
return builder.routes()
.route("test1_route",r ->r.path(Test1_Path)
.uri("lb://TEST1"))
.route("test2_route",r -> r.path(Test2_Path)
.uri("lb://TEST2"))
.build();
}
}
过滤器
过滤器的主要功能与我们从JavaWeb
开始学习的过滤器没有什么区别,只是官方为我们封装了很多过滤器,基本的业务使用官方为我们封装的过滤器就可以了。过滤器这里采用yml
文件来配置:
predicates: # 表示断言(先用来配置路由规则)
- Path=/product
filters:
# 用来给路由对象的所有请求加入指定请求头信息
- AddRequestHeader=User-Name,RRR
# 用来给请求的参数加上
- AddRequestParameter=User-Id,1001
# 转发路径之前拼接上一个前缀
- PrefixPath=/product
# 表示去掉一级路径
- StripPrefix=1
上面的配置需要依次说明,在说明之前再次重申一遍,所有请求都是通过断言的规则认证:
AddRequestHeader
:表示对所有请求在转发之前都加上对应的请求头,该请求头的key
为User-Name
,值为给定值,我们可以通过在请求中添加请求头来覆盖过滤器中给定的默认值;AddRequestParameter
:表示对所有的请求在转发之前都会被添加请求参数,我们可以通过添加参数覆盖掉过滤器中的参数与;PrefixPath
:表示在转发之前为我们提交的路径前增加一个前缀路径;StripPrefix
:表示在转发前为我们去掉一个前缀路径,该参数的值;表示去掉几级路径。
小结
该小结主要针对gateway中的过滤器进行说明:
-
首先,官方为我们提供了很多个封装好的过滤器,大家可以去官网中查看,本篇笔记中仅仅记录了开发中最常用的几个,这几个过滤器在使用的时候可以为我们开发提供很大的便利;
-
其次,这几个过滤器组合起来使用与很多编程逻辑和官方推荐的一些规矩有很大的关系。比如,在开发过程中,因为业务复杂会出现多个类别的控制器或多种服务。
最开始的时候,我们会在
controller
类上添加@RequestMapping
注解来区分一些同名路径的所属,但是在开发建议中,建议非特殊情况不要添加多级路径,这就在某些情况下使得同名路径无法区分,只能按照对应的断言规则的执行顺序来拦截,这无疑是很不合理的。所以在断言处根据业务需求对请求网关的路径进行二级路径的规定,在被断言拦截后,再将其前缀去除,这样就可以保证各个服务之间的接口隔离性。
-
添加参数的拦截器,是为了避免错误或者恶意的请求对系统的运行状态造成威胁,所以将一些关键参数通过断言进行规定,其余不会造成毁灭性威胁但是却会影响系统运行的关键字使用过滤器进行添加默认值,该默认值可以通过在请求中添加参数来覆盖;
-
最后,负责添加请求路径前缀的拦截器,主要负责一些特殊的请求,一般是处理异常或错误的请求,以便于快速响应。
总结
没什么好总结的了,大家如果感觉东西太少可以去官网详细查看。