参考文章
个人笔记,不同意见,望有交流
直接可以点击跳转连接
尚硅谷
一、Gateway概述
网关API
说白了就相当于你服务加了一个路由器,你的所有服务的服务和调用都通过gateway这个路由器进行交换,你可以在这个路由器上设置很多的规则,比如某个时间之前怎么怎么样,或者之前怎么怎么
当下主流的Java,web程序的网关框架中间件,能够完成路由转发、权限校验、限流控制,白名单和黑名单等
1、工作原理概述
客户端向 Spring Cloud Gateway 发出请求。
如果Gateway处理程序映射确定一个请求与路由相匹配,它将被发送到Gateway Web处理程序。
这个处理程序通过一个特定于该请求的过滤器链来运行该请求。
过滤器被虚线分割的原因是,过滤器可以在代理请求发送之前和之后运行逻辑。
所有的 “pre” (前)过滤器逻辑都被执行。然后发出代理请求。
在代理请求发出后,“post” (后)过滤器逻辑被运行。
2、gateway特点 (官方描述)
- 这个项目是基于Spring Framework和Spring Boot构建的。
- 能够匹配任何请求属性的路由。
- 谓词和过滤器是特定于路由的。
- 集成了断路器。
- 集成了Spring Cloud DiscoveryClient。
- 易于编写谓词和过滤器。
- 请求速率限制。
- 路径重写。
3、网关的重要性(来自尚硅谷)
API网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部
客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服
务通信,会有以下的问题:
- 客户端会多次请求不同的微服务,增加了客户端的复杂性。
- 存在跨域请求,在一定场景下处理相对复杂。
- 认证复杂,每个服务都需要独立认证。
- 难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合
并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将
会很难实施。 - 某些微服务可能使用了防火墙/浏览器不友好的协议,直接访问会有一定的困难。
以上这些问题可以借助API网关解决。API网关是介于客户端和服务器端之间的中间层,
所有的外部请求都会先经过API网关这一层。也就是说,API的实现方面更多的考虑业务
逻辑,而安全、性能、监控可以交由API网关来做,这样既提高业务灵活性又不缺安全性:
使用API网关后的优点如下
- 易于监控。可以在网关收集监控数据并将其推送到外部系统进行分析。
- 易于认证。可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在
每个微服务中进行认证。 - 减少了客户端与各个微服务之间的交互次数。
4、基础配置
有两种方式来配置谓词和过滤器:
快捷方式和完全展开的参数。
下面的大多数例子都使用快捷方式。
名称和参数名称作为 code 列在每一节的第一或第二句中。
参数通常按照快捷方式配置所需的顺序列出。
基础
spring:
cloud:
gateway:
routes: #规则组
- id: test # 规则名称
uri: #断言成功后的路劲指向
predicates: # 断言
快捷方式的配置
名称=参数1,参数2
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Cookie=mycookie,mycookievalue # 名称=参数1,参数2
完全展开的参数
一个 name key和一个 args key。
args key是一个键值对的映射,用于配置谓词或过滤器。
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- name: Cookie # 名称
args:
name: mycookie # 参数
regexp: mycookievalue # 参数
注意:
各种Predicates同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配
一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发
。
二、简单实现+SpringCloud+nacos
http://localhost:88/test?url=jd
1、新建Spring项目
,选择一个gatway包导入,
或者直接pom文件导入jar包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
2、添加基础的配置文件
服务注册
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.application.name=gulimall-getWay
server.port=88
配置注册
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.application.name=gulimall-getWay
spring.cloud.nacos.config.namespace=
3、添加gateway配置断言规则
测试
配置的路由规则,在spring官网上有很多规则
spring:
cloud:
gateway:
routes:
- id: test
uri: https://www.baidu.com
predicates:
- Query=bd
- id: test2
uri: https://www.jd.com
predicates:
- Query=url,jd
输入 http://localhost:88/hello?url=jd 就直接访问京东了
三、网关断言规则(基础)
After(在什么时间之前)
类似 ZonedDateTime
指定日期时间之后的请求
测试
- id: after
uri: https://www.baidu.com
predicates:
- After= 1710211823186 # 52分之后 1710212063186 # 54分
设置时间为54分时,当前时间为51分无法访问
设置为52分时,当时时间为53分可以访问
Before(在什么时间之后 )
这个和上面相反 就不测试了
Between(在什么时间之间)
也和上边差不多都是时间规则
这个是在两个时间中间
- id: between
uri: https://www.baidu.com
predicates:
- Between= 1710211823186,1710212483186 # 10.50分到11.1分之间
Cookie(设置cookie值)
设置Cookie里面必须包含某一个值
- id: cookie
uri: https://www.baidu.com
predicates:
- Cookie=token,123
token=12 = 404
token = 123 = 200
Header (设置Header参数)
设置,当header里面有 X-Request-Id这个参数的时候,这个参数的值必须符合后面一个正则表达式
- id: header
uri: https://www.baidu.com
predicates:
- Header=X-Request-Id, \d+
host(设置Header 上的host参数模糊匹配)
- id: host
uri: https://www.baidu.com
predicates:
- Host=**.baidu.com
一种匹配规则,**相当于是模糊匹配
测试
sdfaf.baidu.com 符合**.baidu.com
sdfaf.baidu 无法匹配 **.baidu.com的后面 故404
Method(请求方式限制)
这个就比较简单了,就是设置请求方式
- id: method
uri: https://www.baidu.com
predicates:
- Method=GET
设置get请求
,也可以设置同事支持两个请求
- id: method
uri: https://www.baidu.com
predicates:
- Method=GET,post
这个谓词提取URI模板变量(比如前面例子中定义的 sub)作为名称和值的映射,并将其放在 ServerWebExchange.getAttributes() 中,key值定义在 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE。然后这些值就可以被 GatewayFilter 工厂使用了。
Path
Path 路由谓词工厂需要两个参数:一个Spring PathMatcher patterns 的list和一个可选的flag
matchTrailingSlash(默认为 true)。
简单的理解的话就是路劲的模糊匹配,但是也有不同的方式
先看简单的的,这个就是当路径为/foo/时 注意foo后面只能跟1个参数
还可以设置成 - Path=/red/{segment},/blue/{segment}
如果请求路径是 /red/1 或 /red/1/ 或 /red/blue 或 /blue/green,则该路由匹配
- id: path
uri: https://www.baidu.com
predicates:
- Path=/foo/**
Query
Query 路由谓词工厂需要两个参数:一个必需的 param 和一个可选的 regexp(这是一个Java正则表达式)。下面的例子配置了一个query 路由谓词。
项目这个就是 当这个路径上的url=jd时成立
# Query=bd 代表请求参数中必须包含bd
- id: test
uri: https://www.baidu.com
predicates:
- Query=bd
- id: test2
uri: https://www.jd.com
predicates:
- Query=url,jd
RemoteAddr(远程地址)
RemoteAddr 路由谓词工厂接受一个 sources 集合(最小长度为1),它是CIDR注解(IPv4或IPv6)字符串,如 192.168.0.1/16(其中 192.168.0.1 是一个IP地址,16 是一个子网掩码)。下面的例子配置了一个RemoteAddr路由谓词。
这个没测试好
- id: remoteAddr
uri: https://www.baidu.com
predicates:
- RemoteAddr=
- 有点复杂后面再查
Weight
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
此路由将转发~80%的流量到 weighthigh.org,~20%的流量到 weighlow.org。
他这个相当于是访问的权重,有随机性,大概意思就是,来10个请求,8个到high,2个到low
- 干我怎么测试都测试不成功,先暂时流个坑
XForwarded Remote Addr
XForwarded Remote Addr 路由谓语工厂接受一个 sources 集合(最长度为 1),这些 sources 是 CIDR注解(IPv4 或 IPv6)字符串,如 192.168.0.1/16(其中 192.168.0.1 是一个 IP 地址,16 是子网掩码)。
这个路由谓词允许根据 X-Forwarded-For 的 HTTP Header 对请求进行过滤。
spring:
cloud:
gateway:
routes:
- id: xforwarded_remoteaddr_route
uri: https://example.org
predicates:
- XForwardedRemoteAddr=192.168.1.1/24
例如,如果 X-Forwarded-For Header 包含 192.168.1.10,则该路由匹配。
REMOTE_ADDR
x_forwarded_for
X-Real-IP
这三个内容起看参考文章:23云恋49枫: HTTP 请求头中的 Remote_Addr,X-Forwarded-For,X-Real-IP https://www.cnblogs.com/luxiaojun/p/10451860.html