详解SpringCloud微服务技术栈:Gateway网关(断言、过滤器、跨域问题)

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习
🌌上期文章:详解SpringCloud微服务技术栈:Feign远程调用、最佳实践、错误排查
📚订阅专栏:微服务技术全家桶
希望文章对你们有所帮助

现在集群中会有很多的微服务,且都对应自己的一个数据库,同时每个微服务还需要在Nacos中做注册和配置管理,当微服务之间有相互调用的时候,直接通过Feign来做远程调用,而当外部要访问的时候,直接发请求就可以了。

但,外部可以随意访问微服务,并不是很安全,有些东西只有相应的专业人员才能访问,而网关就是负责解决这类问题的,一切请求都要先通过了网关才能去访问微服务。

Gateway网关(断言、过滤器、跨域问题)

  • 网关的作用介绍
  • 网关快速入门
  • 路由断言工厂
  • 路由的过滤器配置
  • 全局过滤器GlobalFilter
  • 过滤器链执行顺序
  • 网关的cors跨域配置

网关的作用介绍

身份认证和权限校验:通过才能去访问微服务
服务路由:当通过网关后,还需要根据请求的类型,将请求转发到对应的微服务中
负载均衡:确定了转发的微服务之后,微服务中的多个实例之间还应该做负载均衡
请求限流:限制访问的请求量

在SpringCloud中网关的实现包括2种:

gateway
zuul

zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的webFlux,属于响应式编程的实现,具备更好的性能。
因此,我们会使用SpringCloudGateway。

网关快速入门

需要先搭建一下网关,步骤:
1、创新新的module,引入SpringCloudGateway的依赖和Nacos的服务注册发现依赖:

		<!--Nacos服务发现依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--网关gateway依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>

2、搭建一下启动类,位置cn.itcast.gateway.GatewayApplication:

@SpringBootApplication
public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class, args);}
}

2、编写网关的路由配置及Nacos地址:

server:port: 10010
spring:application:name: gatewaycloud:nacos:server-addr: localhost:8848 # Nacos地址gateway:routes:- id: user-service # 路由的标识,必须唯一# uri: http://localhost:8081 # 固定的路由目标地址uri: lb://userservice # lb表示负载均衡,后面跟上服务的名称predicates: # 路由的断言,也就是判断请求能不能符合路由规则的条件- Path=/user/** # 路径满足/user/开头的就符合要求,托管给userservice服务- id: order-serviceuri: lb://orderservicepredicates:- Path=/order/**

访问:
在这里插入图片描述
可以看到我们的网关本身并没有做什么操作,但是可以访问到相应信息,也就是说网关只是把请求转发给微服务。
流程图:
在这里插入图片描述

路由断言工厂

网关路由可以配置的信息包括:

路由id:路由唯一标识
uri:路由目的地,支持lb与http两种
predicates:路由断言,判断请求是否复杂要求,符合则转发到路由目的地
filters:路由过滤器,用于处理请求或者响应

我们在配置文件中写的断言规则只是字符串,这些字符串会被断言工厂(Predicate
Factory)读取并处理,转变为路由判断的条件。

Spring提供了11种基本的Predicate工厂:
在这里插入图片描述
如果不会写的话,就去Spring官网上面看实例,上面提供了11种断言工厂的演示。
在这里进行After的演示:

- After=2030-04-13T15:14:34.433+08:00[Asia/Shanghai]

只有在这个时间之后的请求才会符合这一条要求,显然这里是无法访问到的:
在这里插入图片描述
总结:

路由工厂的作用:读取用户的断言条件,对请求做出判断
Path=/user/**的作用:路径是以/user开头的就认为是符合的

路由的过滤器配置

GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理。
之前已经知道了,当用户发起请求的时候,要通过网关中的路由,基于断言工厂来确定将要去哪个微服务,但在这之间,网关可以给通过路由的请求再增加过滤器链,请求要经过这些过滤器链才能到达微服务,同样微服务返还数据给用户的时候也需要经过这些东西:
在这里插入图片描述
Spring提供了30多种不同的路由过滤工厂,这当然不是全部去学的,当有这方面的需求的时候就直接去看Spring官方文档就行了。
在这里进行一个简单的演示:给所有进入userservice的请求添加一个请求头。

实现方式:在gateway中修改application.yml文件,给userservice的路由添加过滤器
在这里插入图片描述
验证是否增加了这个请求头,只需要在UserController中获取请求头并且打印即可:

	@GetMapping("/{id}")public User queryById(@PathVariable("id") Long id, @RequestHeader(value = "Truth", required = false) String truth) {System.out.println("truth = " + truth);return userService.queryById(id);}

访问user网址后在控制台中可以看到输出:
在这里插入图片描述
而如果我们希望全局都可以增加这个过滤器,也就是全局都会增加这个请求头,只需要:
在这里插入图片描述
总结:

过滤器的作用:
(1)对路由的请求或响应做加工处理,比如添加请求头
(2)配置在路由下的过滤器只对当前路由的请求生效
defaultFilters的作用:对所有的路由都生效

全局过滤器GlobalFilter

全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。
区别在于GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现,而不是全部交给Spring容器,而且更灵活。
定义方式是实现GlobalFilter接口。
在这里插入图片描述
在这里定义定义一个全局过滤器,判断请求的参数是否满足:

1、参数中是否有authorization
2、authorization参数值是否为admin

如果是,则放行,否则拦截。
代码的编写还是比较麻烦的,因为这里面涉及了不少基于响应式编程的API,需要多花点时间敲才能更好的掌握。

//@Order(-1) //可以注解设置过滤器的优先级,越小则优先级越高,-1表示最高优先级
@Component //需要将实现设置为Spring的组件
public class AuthorizeFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//获取请求参数(通过上下文获取)ServerHttpRequest request = exchange.getRequest();MultiValueMap<String, String> params = request.getQueryParams();//获取参数中的authorization参数String auth = params.getFirst("authorization");//判断参数值是否等于adminif("admin".equals(auth)){//相等,放行//chain会直接找这个过滤器的下一个过滤器return chain.filter(exchange);}//不相等,拦截exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);//设置状态码,401表示未登录return exchange.getResponse().setComplete();}@Overridepublic int getOrder() {//也可以用接口指定优先级return -1;}
}

在这里插入图片描述
总结:

全局过滤器的作用:对所有路由都生效,并且可以自定义处理逻辑
实现全局过滤器的步骤:
(1)实现GlobalFilter接口
(2)添加@Order接口或实现Ordered接口用于设定优先级
(3)编写处理逻辑

过滤器链执行顺序

请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter。
请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter合并到一个过滤器链中,排序后依次执行每个过滤器。

排序的规则:

每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前
(1)GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由自己决定
(2)路由过滤器和defaultFilter的order是由Spring指定的,是按照配置文件中的声明顺序来递增的
当过滤器的order值一样时,会按照defaultFilter>路由过滤器>GlobalFilter的顺序执行。

记一下结论就行了,源码暂时还没去读。

网关的cors跨域配置

在web的时候已经解决过了跨域问题,而微服务里面也有这样的问题,因为所有的请求都要经过网关,也就是说,跨域请求不需要在微服务这里做处理,只需要在网关这里处理就行了。
而网关这里的实现不太一样,它没有Servlet相关的API,是响应式编程。

先重新分析一下跨域问题。

跨域,即域名不一致的就是跨域,主要包括:
(1)域名不同: www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com
(2)域名相同,端口不同:localhost:8080和localhost8081
跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题
解决方案:CORS

在网关其实已经做好了CORS相关的底层逻辑了,只需要做相应的配置就可以解决问题了。

cloud:gateway:globalcors: # 全局跨域处理add-to-simple-url-handler-mapping: true # 解决options请求被拦截的问题corsConfiguration:'[/**]':allowedOrigins: # 允许哪些网站的跨域请求- "http://localhost:8090"- "http://www.leyou.com"allowedMethods: # 允许的跨域Ajax的请求方式- "GET"- "POST"- "DELETE"- "PUT"- "OPTIONS"allowedHeaders: "*" # 允许在请求中携带的头信息allowCredentials: true # 是否允许携带cookiemaxAge: 360000 # 这次跨域检测的有效期

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/630464.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PuTTY的ppk密钥与OpenSSH密钥之间的相互转换

几个概念说明&#xff1a;id_rsa、id_rsa.pub、ppk、pem 目前有两个主流的密钥格式&#xff1a;OpenSSH格式的密钥 和 PuTTY格式的密钥。 id_rsa和id_rsa.pub 都是OpenSSH格式的密钥。 id_rsa是OpenSSH格式的SSH私钥。 id_rsa.pub是OpenSSH格式的SSH公钥。ppk文件 ppk文件是P…

c++基础2

一、c的引用 引用和指针的的区别&#xff1f; 引用是一种更安全的指针&#xff1a; 1. 引用必须初始化&#xff0c;指针可以不用初始化 int a 10; int *p; // 指针可能是野指针 int &b a;//引用赋值"&#xff0c;通常指的是直接修改引用所引用的对象的值&#xff0…

Qt/QML编程之路:小键盘keyboard(36)

小键盘对于qml应用是经常用到的,在qml里面,就如一个fileDialog也要自己画一样,小键盘keyboard也是要自己画的,对于相应的每个按键的clicked都要一一实现的。 这里有一个示例: 代码如下: import QtQuick 2.5 import QtQuick.Controls 1.4 import QtQuick.Window 2.0 im…

yum仓库以及NFS共享

yum实现过程 1.光驱里自带yum 2.网络下载到本地 3.直接通过网络 如何实现安装服务 yum客户端找到yum服务端&#xff0c;找到yum的仓库位置&#xff0c;下载元信息&#xff0c;因为里面有软件的位置&#xff0c;因此可以找到软件包的位置&#xff0c;然后下载到本地 仓库的类…

25考研英语复习计划

Hello各位小伙伴大家好&#xff0c;今天要给大家分享的是英语备考计划&#xff0c;大家可以作为参考&#xff0c;制定适合自己的备考计划。 【英一/二】 英语分为英一、英二&#xff0c;一般学硕英一&#xff0c;专硕英二。 英一要比英二难度大。 【复习计划】 1-2月&#xf…

图深度网络浅层理解

图神经网络 1.输入&#xff1a; 图网络 2.输出&#xff1a; 节点类别、某两个节点的新连接、产生新的图或子图 3.端到端表示学习&#xff08;Representation Learning&#xff09;/图嵌入&#xff1a; 将节点映射为d维的向量&#xff0c;d维向量就包含了这个节点的连接关系…

H5小游戏如何提升APP变现收益?

在当前用户规模稳定但变现压力增加的背景下&#xff0c;开发者需要挖掘用户价值&#xff0c;提高营收&#xff0c;这成为开发者关注的重点话题。对于那些“用户用完即走”的APP产品来说&#xff0c;接入H5游戏能够吸引停留&#xff0c;为其带来收入上的增长。 一、什么是H5游戏…

小程序学习-17

attached最常用 推荐使用 lilfetimes 这种方法

springcloud Eureka服务注册与发现

文章目录 代码地址Eureka基础知识什么是服务治理什么是服务注册与发现 单机版eurekaServerIDEA生成eurekaServer端服务注册中心类似物业公司EurekaClient端cloud-provider-payment8001修改EurekaClient端cloud-consumer-order80 集群Eureka构建步骤新建cloud-eureka-server7002…

计算机找不到iutils.dll的5种有效的解决方法,一分钟教会修复dll问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中最常见的就是“某某文件丢失”或“某某文件损坏”&#xff0c;找不到iutils.dll就是其中之一。iutils.dll是一个系统级的动态链接库文件&#xff08;DLL&#xff09;&#xff0c;它是Windows操作系统…

grep 在运维中的常用可选项

一、对比两个文件 vim -d <filename1> <filename2> 演示&#xff1a; 需求&#xff1a;&#xff5e;目录下有两个文件一个test.txt 以及 text2.txt,需求对比两个文件的内容。 执行后会显示如图&#xff0c;不同会高亮。 二、两次过滤 场景&#xff1a;当需要多…

(一)ROS的安装

&#xff08;一&#xff09;安装ubuntu18.04 系统&#xff08;虚拟机或者是物理机&#xff0c;在此不再介绍&#xff09; &#xff08;二&#xff09;添加ROS镜像源 apt 列表中没有ROS源&#xff0c;所以要手动添加 sudo sh -c . /etc/lsb-release && echo "deb…

在vite5和vue3开发环境中使用jodit4富文本编辑器,并添加自定义插件和使用highlight.js实现代码块高亮(附其他自定义配置项和全部代码)

最近富文本编辑器jodit终于更新发布到了4.0版本&#xff0c;加入了css变量、有更好的typescript支持&#xff0c;截止发文时的版本是&#xff1a;4.0.5&#xff0c;看到有了新版本于是便想着将本地项目中的jodit版本也进行升级&#xff0c;琢磨着再丰富和添加一些功能&#xff…

掌握Python 99 个实用实例,其中精选算法高频题目以及答案,助力求职Python工程师面试不慌拿offer

掌握Python 99 个实用实例&#xff0c;其中精选算法高频题目以及答案&#xff0c;助力求职Python工程师面试不慌拿offer。 Python由荷兰国家数学与计算机科学研究中心的吉多范罗苏姆于1990年代初设计&#xff0c;作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构&…

给机器人开发个功能让它帮我照看宝宝

本文首发于古月居 这篇博客主要讲述了如何通过OriginBot来看护宝宝&#xff0c;当宝宝的脸不在摄像头的范围之内时&#xff0c;发送消息到钉钉群组&#xff0c;通知家人及时查看。 前言 我在上个月有了宝宝&#xff0c;为了方便照看宝宝&#xff0c;就买了一个带有宝宝看护功能…

OpenLayers实战,OpenLayers点聚合有相同经纬度坐标时无法展开问题解决办法,当缩放级别达到一定等级后强行展开聚合为单个点

专栏目录: OpenLayers实战进阶专栏目录 前言 本章用于解决OpenLayers使用Cluster点聚合情况下,要素(Feature)出现有相同经纬度坐标时无法展开成单独图标的问题解决办法以及当缩放级别达到一定等级后强行展开聚合为单个点的功能。 本章展开后由于经纬度坐标还是同一个点,…

SAP 销售订单审批状态(查询/修改)

销售订单审批状态启用后&#xff0c;前端显示界面如下图 销售订单审批状态读取&#xff1a;STATUS_READ 销售订单审批状态修改&#xff1a;I_CHANGE_STATUS 销售订单审批状态读取 代码样例如下&#xff1a; DATA: lv_objnr TYPE vbak-objnr,lv_objnr_t TYPE jsto-objnr,l…

难道说 IT行业的下一个风口是鸿蒙开发吗?

按往年的习俗&#xff0c;在年底之季有很多HC都会缩减&#xff0c;尤其当下各种裁员的情况下&#xff0c;不管你是在哪个传统开发行业&#xff0c; 如&#xff1a;C/C、Java、前端、后端……等多少都会一股互联网寒流的影响。而今年却出现了一个怪现象&#xff0c;有个岗位在这…

【欢迎您的到来】这里是开源库get_local_info作者的付费专栏

您好&#xff0c; 我是带剑书生&#xff0c;开源库get_local_info的作者&#xff0c;欢迎您的到来&#xff0c;这里是我的付费专栏&#xff0c;会用更简洁的语言&#xff0c;更通俗的话语&#xff0c;来帮助您更好的学习rust&#xff0c;这里不仅仅讲解Rust在某些应用功能实现上…

Java可视化物联网智慧工地综合云平台源码 私有化部署

智慧工地平台围绕建筑施工人、物、事的安全管理为核心&#xff0c;对应研发了劳务实名制、视频监控、扬尘监测、起重机械安全监测、安全帽监测等功能一体化管理的解决方案。 智慧工地是聚焦工程施工现场&#xff0c;紧紧围绕人、机、料、法、环等关键要素&#xff0c;综合运用…