文章目录
依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
- 1
- 2
- 3
- 4
三大组件
-
路由
-
断言
-
过滤器
路由
定制化开发的基本组成,它由ID,目标URL,定制化开发断言和过滤器组成.定制化开发如果断言为true,定制化开发将匹配路由
断言
定制化开发只有断言成功的请求才定制化开发会匹配路由
过滤器
定制化开发可以对请求或响应进行处理
小Demo Gateway初次使用
定制化开发新建服务模块,提供 @GetMapping(“/say”) @GetMapping(“/say/one”) 定制化开发两个请求映射
@RestControllerpublic class HelloController { @GetMapping("/say") public String say() { return "HelloWord"; } @GetMapping("/say/one") public String sayOne() { return "HelloWord one"; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
定制化开发新建一个网关模块
定制化开发设置如下配置
server: port: 81spring: cloud: gateway: routes: # 配置路由,定制化开发是一个集合 - id: apptest # 路由的ID, 定制化开发没有固定规则但要求唯一,定制化开发建议配合服务名 uri: http://localhost:8080 # 定制化开发匹配后提供服务的路由地址 predicates: - Path=/say/**
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
定制化开发启动两个服务
定制化开发我们先不经过网关访问服务 定制化开发测试是否能正常访问
定制化开发然后测试通过网关路由服务
至此 通过网关路由服务的一个demo完成了
工作原理
下图提供了Spring网关工作原理的高级概述:
客户端向网关发送请求,如果网关处理的映射请求与路由匹配,则将映射请求交给 GateWay Web Handler处理. Handler再通过相关的过滤器链将请求交给实际服务执行,最后返回
过滤器可以发送代理请求前执行,也可以在代理请求后执行
配置路由断言和过滤器
有两种方式可以来配置网关
1.快捷方式配置网关
快捷配置由过滤器名称,后跟一个等号=,用逗号(,)分隔的参数值来识别。
spring: cloud: gateway: routes: - id: after_route uri: https://example.org predicates: - Cookie=mycookie,mycookievalue
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.将参数全部展开
完全展开的参数看起来更像带有名称/值对的标准yaml配置。 通常,会有一个name键和一个args键。 args键是配置断言或过滤器的键值对的映射
spring: cloud: gateway: routes: - id: after_route uri: https://example.org predicates: - name: Cookie args: name: mycookie regexp: mycookievalue
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
路由断言规则
1.时间作为匹配路由规则 After Before Between
1.1 The After Route Factory 时间之后
spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - After=2022-03-20T21:02:47.789-07:00[Asia/Shanghai]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
当请求的时间在断言时间之后,将匹配路由
我们配置的时间时 2022-03-20T21:02:47.789 在当前时间2022-03-20 21:07之前
也就是当前请求时间在我们断言的时间之后 此时能匹配路由
spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - After=2022-03-21T21:02:47.789-07:00[Asia/Shanghai]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
当前时间是 03-20 我们断言的时间时 03-21 则请求不能匹配当前路由
1.2 The Before Route Predicate Factory 时间之前
看了上面时间之后的例子 对于时间之前的你肯定立马就能明白是怎么回事
与After正好相反
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - Before=2022-03-20T21:02:47.789-07:00[Asia/Shanghai]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
请求的时间在断言设置的时间之后,不能匹配到当前请求,所有无法匹配路由
把断言时间设置为当前时间之后 再来测试下
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - Before=2022-03-22T21:02:47.789-07:00[Asia/Shanghai]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
1.3.After和Before两者比较
1.4 The Between Route Predicate Factory 两个时间之间
指定两个时间,用逗号分割,如果请求时间在这两个时间之间,将匹配路由
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - Between=2022-03-19T21:02:47.789-07:00[Asia/Shanghai],2022-03-22T21:02:47.789-07:00[Asia/Shanghai]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
此时请求时间为
能正常路由 如果请求时间不在设置的时间范围内
则不能匹配路由
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - Between=2022-03-22T21:02:47.789-07:00[Asia/Shanghai],2022-03-23T21:02:47.789-07:00[Asia/Shanghai]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
2.Cook作为匹配路由规则 Cookie
2.1 The Cookie Route Predicate Factory
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - Cookie=token,123
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如果请求cookie中有name为token,且值为123将匹配当前路由
name和value有一个不一样都不能成功路由
name和value都相同 则能成功路由
3.请求头作为匹配路由规则 Header
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - Header=token,123
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
请求对象的请求头中 如果有name为token,且值为123,将匹配当前路由
改用postman测试
如图 测试请求头没有name为token value为123 的请求头信息 则不能匹配路由
当请求头中有 name为token 值为 123的请求头信息时,能匹配到当前路由
4.Host作为匹配路由规则 Host
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - Host=**.haha.com:81
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
先修改本机host文件
127.0.0.1 qq.haha.com127.0.0.1 qq.haha.cn
- 1
- 2
访问 http://qq.haha.com:81/say 能匹配到路由
改成 cn 则不能匹配到路由
5.请求方法作为匹配路由规则 Method
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - Method=GET,POST
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
GET和PUT请求都能匹配到路由
如果我们换成PUT请求则不能匹配到路由
6.路径作为匹配路由规则 Path
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - Path=/say
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
访问 /say 能匹配到路由
多加一级路径则不能匹配到路由
可以正则 改成 /say/**
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - Path=/say/**
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
此时无论访问 /say 还是 /say/one都能匹配到路由
7.查询参数作为匹配路由规则 Query
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - Query=skuID
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如果只写一个参数 则意思为 查询参数有skuID则匹配当前路由
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8080 # 匹配后提供服务的路由地址 predicates: - Query=skuID,11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如果两个参数,用逗号分割 则意思为 查询参数为skuID ,且值为11 匹配当前路由
注意 两个条件都必须满足 且请求方式与服务请求映射的方式一致
如果skuID 不为 11 也不能匹配到当前路由
8.权重作为匹配路由规则 Weight
server: port: 81spring: cloud: gateway: routes: # 配置路由,是一个集合 - id: apptest1 # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:80 # 匹配后提供服务的路由地址 predicates: - Path=/say/** - Weight=group,5 - id: apptest2 # 路由的ID, 没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8081 # 匹配后提供服务的路由地址 predicates: - Path=/say/** - Weight=group,5
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
有两个路由ID 二者根据权重匹配路由 都在一个权重分组中 且权重都为5 这样匹配到/say/** 的百分之五十 请求交给80端口,另外的交给8081端口
复制一个服务,并输出打印当前服务的端口号
package gateway.controller;import lombok.Data;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * @author sz * @DATE 2022/3/20 20:15 */@Data@RestControllerpublic class HelloController { @Value("${server.port}") public String serverPort; @GetMapping("/say") public String say() { return "HelloWord "+serverPort; } @GetMapping("/say/one") public String sayOne() { return "HelloWord one"; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34