网关是前端访问通过的一个中间件
根据请求url确定请求的微服务(多了个这个步骤,所以和RPC有所不同,RPC是直接指定微服务名,直接从注册中心获取地址)
再我们的注册中心获取各个微服务的地址
将对应的请求负载均衡转到微服务
网关有两个核心作用第一个是路由作用,第二个是登录校验(防止我们每个服务都要写JWT校验)
功能1:路由配置
快速入门
需求
创建网关
在服务模块外
新建一个gateway模块
导入依赖,nacos、gateway、负载均衡
配置一下
这里网关默认占8080端口,我们改为80端口,你输入url时候
如果只写localhsot没写端口默认走80
所以以后写url只写localhost/api/order和localhost:80/api/order效果一样
网关本身算一个服务在nacos中所以要开启服务发现注解,才可以发现其他微服务
接下来启动项目它就是一个网关了
配置路由规则
两种方式,一种配置文件方式,一种编码方式
配置方式
predicates是断言,下面会具体讲解,这里是断言了请求路径
在我们的服务模块也要加上断言路径的前缀
因为gateway根据前缀转发对应服务,http请求不变还是api/order开头,你如果不加的话,服务就会找不到对应请求的url
工作原理
id作为表示路由唯一标识
路由下可以配置断言和过滤器和URL
断言和过滤器下面会介绍
URL就是我们最终发送的地址
断言
简介
断言是在我们gateway的routes里面配置的一系列规则
只有符合断言规则的url才可以跳转到我们的微服务,进行服务的请求
断言种类
这里建议找一下官方文档看一下
断言可以限制的有很多,比如限制参数,Cookie,路径等等
匹配顺序
断言匹配顺序默认从上到下依次匹配
如果有order,则order越小越先匹配,比如这里你输api/order/**就会到我们的service-order
但是如果没有order的话,会到我们的https://***.bing.***/
路由过滤器
简介
路由过滤器的作用就是给我们的请求和响应
做一些处理
规则
路径重写过滤器常用
后面用的是正则表达式
可使用ai辅助
下面这个过滤器会给所以请求添加请求头
X-Response-Abc = 123
默认filter
配置默认filiter就会在每一个路由规则都会应用(不管有无)
GlobalFilter
也是全局都生效的filter
这个和默认filiter不同的是,GlobalFilter是要我们自己建一个类实现GlobalFiliter和Orderd接口
实现方法里面写我们自己的逻辑,Orderd指定执行顺序(越小越先执行)
然后这个定义好后直接生效,放入容器,不用加在配置文件中
自定义过滤器工厂
视频教程
gateway设置全局跨域
前后端端口不一样跨域
在网关设置跨域解决
一般都是配置这个允许全局跨域
谷粒商城跨域实践
需要注意的就是,你如果所有请求都是通过gateway的话,网关设置跨域就行(设置filiter)如果其他的也设置的话就会设置两遍响应头,就会报错!
自定义路由过滤器
功能2:登录校验
分析
这里其实和我们上面的工作原理流程一样哈,只是这里介绍更细致
所以我们如果进行登录校验的话
自定义过滤器,pre中进行登录校验和拦截
添加到需要登录拦截的路由就可以
我们传递用户信息,不能用threadloca了,因为我们网关本身是一个服务,它会去建立新请求去请求其他服务
用户的请求和网关发送请求不是一个请求,自然不是一个线程
我们一般将用户信息放在请求头中,可能微服务之间也有调用,也要将之前的请求头中的用户数据保存在微服务发送请求的请求头
(微服务请求用Openfegin发送,gateway自己发送,两套添加请求头逻辑不同)
自定义过滤器
自定义过滤器分两种
我们之前的过滤器都是gatewayFilter,比如RewitePath重写过滤器,要放在指定路由盛小平
而globalFilter全局过滤器,作用方位是所有路由
实现GlobalFilter接口和Order接口
业务处理阶段实现我们的登录验证功能即可
getOrder方法指定filter执行顺序,返回值越小,优先级越高,这里只需要设置小于***tyRoutingFilter(其对应Oredr返回值为Integer最大值),所以其实随便设置一个就行
实现
这块实现肯定根据具体项目
可以看下面视频实现
视频教程
这里就是实现了登录校验的过程,但是没实现用户数据传输过程
接下来我们实现用户数据传输
实现用户数据传递
网关发送到微服务
首先先在拦截器的请求头加上这个信息
这里请求到微服务的请求就会有这个请求头,可以获取
我们一个微服务可能很多controller都需要获取用户
这样我们可以定义拦截器,保存在ThreadLocal中
但每个微服务都用这么个拦截器又要写很多遍,我们可以将其写入一个新模块,然后让我们服务模块依赖就行
这样拦截器也会自动配置
先在hm-***mon模块建立拦截器
将拦截器注入MVC配置类
注:这里就算让我们其他服务依赖hm-***mon模块也不会生效
其他项目的扫描包是人家自己的包,就算依赖了,这个扫描不到,也不会注册为bean,也不会生效
所以我们要让其自动装配到我们的子项目IOC,需要进行自动装配设置
详见SpringBoot自动装配原理
再spring.factories里面把我们这个的全类名也加上即可
小bug
我们gate-way服务也引用我们***mon,它也会自动配置这个
但是gateway没有webmvc的依赖会报错,我们可以用自动装配的条件注解来实现
所有有webmvc都有dispatherServlet,gateway没有就不会配置了,解决报错
OpenFegin传递用户信息
上面操作只是保证
gateway传递的请求有user-ifno信息
但如果我们order服务模块调用cart模块,cart需要user-info数据时就没有那个数据
只有服务会用到Openfegin,OpenFegin又引用了api
所以在api里面设置一个公共OpenFegin拦截器即可
这里可以从usercontext(threadlocal)取,因为无论是从网关来的请求还是RPC都会设置这个threadlocal了
然后我们在api的DefaultFeginConfig里面设置的bean
子项目依赖,可以获取到这个类
每个服务直接指定这个配置类,会把我们的拦截器一同注册为Bean
总结
很多微服务数据传递问题都可以通过这套思路解决