本文作者:admin

gateway

gateway摘要: gateway核心概念 1. 路由(route)         路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filt...

gateway核心概念

1. 路由(route)
        路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。如果断言为真,则说明请求的URL 和 配置的路由匹配。
2. 断言(predicates)
     断言函数允许开发者去定义匹配Http request中的任何信息,比如请求头和参数等
3.过滤器(Filter)
     Filter分为Gateway FilIer和Global Filter。Filter可以对请求和响应进行处理。


gateway快速开始

1. 引入依赖
注意:会和spring-webmvc的依赖冲突,需要排除spring-webmvc
2.编写yml配置文件
server.port = 8088是 网关的访问端口
spring.application.name 是 当前网关服务的服务名称
gateway.routes下面定义路由规则:
id是这个路由规则的名称,gateway.routes下面可以有很多的路由规则
url:把访问当前网关的这个服务, 转发到哪个url去,首先,我不能什么请求到网关都去转发,需要满足一定的条件,predicates断言,就是起到这个作用
predicates:当 请求到了当前这个网关(那么 这个请求就必须带了当前网关的 ip+端口号 的信息,后面紧跟着 斜杠 / ,所以网关可以默认这些信息是有的, predicates中不用考虑这些信息), 如果 端口号后面的url,以 /order-serv/** 开头,那么 就转发到 上面url的 ip + 端口。 并且斜杠 / 后面的所有路径都不会去掉,那么就转发到了http://localhost:8020/order-serv/order/add 这个地址
(order-serv是服务名称,防止订单服务里有/order/add开头的地址,库存服务里也有/order/add开头的地址,所以 发到gateway的请求,都带上需要转发到的服务的名称),但是 订单服务 里 接收的请求里 是 没有 /order-serv/的,只有发来的请求是 http://localhost:8020/order/add ,才能进行接收, 所以 让网关把 第一层路径给去掉,通过 filters 过滤前缀
如果不满足断言,就会报 404 的 错误 


这里我们在配置里把转发的url地址都写死,当服务器发生迁移,ip地址会变动 或者 服务器是以集群的形式部署的,还需要通过nginx来进行反向代理和负载均衡,很麻烦。

我们通过把gateway和nacos集成起来,就可以轻松解决这些问题

集成Nacos

1. 继续引入nacos的依赖
2. 继续编写yml配置文件
(1)集成nacos,只需将当前的gateway服务,注册到nacos上即可,写上nacos服务地址和账号密码
(2)将路由规则中的,转发到哪个服务的地址,改成服务名称 "order-service" 即可(url: order-service),又因为需要使用nacos自带的ribbon的负载均衡策略,所以前面加上  lb://   , lb的意思是loadbalance负载均衡。
gateway网关会将 “order-service” 整体 替换成 其中一个 订单服务的 ip 地址(因为网关会定时拉取各种nacos上注册上去的服务的ip地址列表)
这样就解决了当服务器发生迁移,ip地址变动 或者 服务器是以集群的形式部署的,还需要通过nginx来进行反向代理和负载均衡的问题
简写路由规则:约定大于配置
(1)开启自动识别nacos服务的功能后,就不需要写断言规则了
(2)将发送到网关的请求  ,以注册到nacos上的服务名称开头时,会自动转发到那个服务的某个服务器上,并自动过滤掉第一层路径(缺点:路由规则不够灵活)
这时候,只要按照网关地址/微服务/接口的格式去访问,就可以得到成功响应。


断言工厂

根据url来进行断言,是gateway内置的断言工厂



自定义路由断言工厂

这里假设自定义一个基于Query请求参数的断言工厂,复制源码里面的内容,然后根据需要进行修改

自定义 一个基于Query请求参数的断言工厂, 需要继承 AbstractRoutePredicateFactory 类,重写 apply 方法的逻辑。在 apply 方法中可以通过 exchange.getRequest() 拿到 ServerHttpRequest 对象,从而可以获取到请求的参数、请求方式、请求头等信息。
1. 必须是spring组件 ,即是一个bean
2. 类必须加上 RoutePredicateFactory 作为结尾
3. 必须继承  AbstractRoutePredicateFactory
4. 必须声明静态内部类,声明属性来接收 配置文件中对应的断言的信息
5. 需要结合 shortcutFieldOrder 进行绑定
6. 通过apply进行逻辑判断 true就是匹配成功 false匹配失败


过滤器(先过滤再路由)

(1)先经过 过滤器 把请求的url地址处理后,或者添加删除修改一些请求头、cookie等的信息,

(2)再通过nacos的服务列表进行路由到 对应的服务器上

过滤器的作用:当一个请求来到gateway网关时,我们可以对这个请求进行一个业务逻辑的处理。

比如:

(1)前面通过 过滤器 去把第一层路径给去掉

(2)可以给来到网关的所有请求添加一个请求头,再设置里面的内容。

(3)可以给来到网关的所有请求设置一个cookie等等处理

具体全部内置的过滤器有哪些可以访问官网

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

下面是一些代码示例:

测试地址是发送给gateway网关的

通过routes路由到下面的@GetMapping的地址,下面的代码来接收请求和进行响应

例1:

例2
例3
前一个url地址是发送到网关的,经过过滤器,加上了前缀/mall-order。这时,服务端要能接收响应,必须设置,发送来的请求,都带上/mall-order。这样服务器才能进行正常的接收网关路由来的请求
例4
发送到当前网关的请求,都会被路由到百度网站
302是重定向之后的响应状态码


自定义过滤器



全局过滤器

局部过滤器和全局过滤器区别:
局部:局部针对某个路由, 需要在路由中进行配置
全局:针对所有路由请求, 不需要在配置文件中配置, 一旦定义就会投入使用
内置的全局过滤器:
路由地址中带了lb的话,就会自动采用负载均衡策略,和上面第一个的全局过滤器对应
这些全局过滤器 会自动判断,自动处理,不用我们管理


自定义全局过滤器(重点)

记录所有访问过来的请求,保存成日志的形式,可以用自定义全局过滤器

或者判断用户登录、权限方面也可以自定义全局过滤器

自定义全局过滤器非常简单
1. 定义一个类,交给springIOC容器管理,即加上spring的注解 @Compenent
2. 继承GlobalFilter接口,重写里面的filter方法,只需要写里面的方法体就行
3. 参数exchange 里面 包含了 进入网关的 这个 请求的所有信息,取出url地址,header头、cookies,路径参数等等所有信息都可以,然后进行相应的 业务处理
4. return chain.filter(exchange) 将请求进行放行


请求日志记录

在网关微服务里,在这个地方加上这个命令,可以开启日志记录,将所有通过网关的请求,都记录下来,不过只是输出到控制台



gateway跨域配置

跨域:当http请求 不在 同一个ip+同一个端口时,就叫做跨域

(只有同一个ip+同一个端口才叫 同域,两个都满足才同域)

1. 通过yml配置的方式 ,配置在gateway的下一级

配置的内容可以自己修改跨域
2. 通过配置类的方式设置


sentinel结合gateway网关

结合sentinel对发送到gateway网关的请求,进行流控降级

sentinel分为两个部分
前提:远程服务器下载sentinel客户端,安装、运行后
gateway服务只需:
gateway服务的配置文件加上sentinel客户端的ip+端口、账号密码
这样就整合好了sentinel的流控降级
sentinel针对gateway网关服务有特殊的规则,它的界面和  对于controller中方法(服务入口)的流控降级界面不太一样
可以针对断言工厂里面的这些规则进行限流
可以针对某个ip、远程域名、请求头、url中的参数、cookie值进行限流


自定义sentinel结合网关 后的响应内容

网关层被sentinel流控降级或者熔断后,会响应下面的内容给发送请求者

这样的内容如果不是我们想要的,就需要自定义响应异常的方式。有两种方式

方式1:(简单)

 

在yml配置中,分层写上面的内容,

spring . cloud . sentinel . scg . fallback . response body = '{"code":403,"mes":" 限流了 "}'
response‐body后面的内容就是我们自定义的响应内容(json格式的) ,写的内容就是响应的内容
方式2:

设置响应状态码、响应类型(json格式的)、响应内容(“降级了!”)



网关高可用

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享

发表评论

快捷回复:

评论列表 (暂无评论,29人围观)参与讨论

还没有评论,来说两句吧...