SpringCloud微服务-统一网关Gateway

统一网关Gateway

文章目录

  • 统一网关Gateway
    • 1、为什么需要网关?
    • 2、gateway快速入门
    • 3、路由断言工厂Route Predicate Factory
    • 4、过滤器工厂-路由过滤器GatewayFilter
    • 5、全局过滤器**GlobalFilter**
    • 6、各种过滤器的执行顺序
    • 7、跨域问题的解决

1、为什么需要网关?

网关与各个服务之间的关系:

image-20240229110119243

网关功能:

  • 身份认证和权限校验

  • 服务路由、负载均衡

  • 请求限流

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

  • gateway

  • zuul

Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloud Gateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。

2、gateway快速入门

搭建网关gateway服务:

搭建网关服务的步骤:

  1. 创建新的module,引入SpringCloudGateway的依赖和nacos的服务发现依赖:
<!--   网关依赖     -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency><!--   nacos的服务发现依赖     -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  1. 编写module的启动类

    @SpringBootApplication
    public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class, args);}
    }
    
  2. 编写路由配置及nacos地址

    server:port: 10010
    spring:application:name: gateway #网关名称cloud:nacos:server-addr: localhost:8848 #nacos的地址gateway:routes: #网关路由设置- id: user-service #路由id,自定义,唯一即可# uri: http://127.0.0.1:8081 #路由的目标地址,http是固定地址uri: lb://userservice #路由的目标地址,lb就是负载均衡,后面是服务的名称predicates: #路由断言,也就是判断请求是否符合路由规则的条件- Path=/user/**  #这个是按照路由匹配,只要以/user/开头就符合要求- id: order-serviceuri: lb://orderservicepredicates: #路由断言- Path=/order/**
    

从网关访问数据:

image-20240229113154532

image-20240229113207857

网关服务流程图:

image-20240229113341770

3、路由断言工厂Route Predicate Factory

网关路由可以配置的内容包括:

  • 路由id:路由唯一标示

  • uri:路由目的地,支持lb和http两种

  • predicates:路由断言,判断请求是否符合要求,符合则转发到路由目的地

  • filters:路由过滤器,处理请求或响应

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

例如Path=/user/**是按照路径匹配,这个规则是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理的像这样的断言工厂在SpringCloudGateway还有十几个。

Spring提供了11种基本的Predicate工厂:

名称说明示例
After是某个时间点后的请求- After=2037-01-20T17:42:47.789-07:00[America/Denver]
Before是某个时间点之前的请求- Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
Between是某两个时间点之前的请求- Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]
Cookie请求必须包含某些cookie- Cookie=chocolate, ch.p
Header请求必须包含某些header- Header=X-Request-Id, \d+
Host请求必须是访问某个host(域名)- Host=.somehost.org,.anotherhost.org
Method请求方式必须是指定方式- Method=GET,POST
Path请求路径必须符合指定规则- Path=/red/{segment},/blue/**
Query请求参数必须包含指定参数- Query=name, Jack或者- Query=name
RemoteAddr请求者的ip必须是指定范围- RemoteAddr=192.168.1.1/24
Weight权重处理

可以查看官方文档来进一步学习或者使用:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

image-20240229152115249

4、过滤器工厂-路由过滤器GatewayFilter

GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理:

image-20240229152738630

Spring提供了31种不同的路由过滤器工厂。例如:

名称说明
AddRequestHeader给当前请求添加一个请求头
RemoveRequestHeader移除请求中的一个请求头
AddResponseHeader给响应结果中添加一个响应头
RemoveResponseHeader从响应结果中移除有一个响应头
RequestRateLimiter限制请求的流量

同样参考官方文档进行学习和参考:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

image-20240229153304967

示例:假如我们需要对某个服务添加请求头(路由过滤器中的一个工厂),添加配置:(最后一行,参考官方文档即可)

spring:
application:name: gateway #网关名称
cloud:nacos:server-addr: localhost:8848 #nacos的地址gateway:routes: #网关路由设置- id: user-service #路由id,自定义,唯一即可# uri: http://127.0.0.1:8081 #路由的目标地址,http是固定地址uri: lb://userservice #路由的目标地址,lb就是负载均衡,后面是服务的名称predicates: #路由断言,也就是判断请求是否符合路由规则的条件- Path=/user/**  #这个是按照路由匹配,只要以/user/开头就符合要求filters:  - AddRequestHeader=hello,Mannor Redaz id the greatest man!

修改接口代码:

@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id, @RequestHeader(value = "hello", required = false) String hello) {//@RequestHeader(value = "hello", required = false) String hello//上述代码含义就是获取名为Hello的参数,并且这个参数不是必须的System.out.println("hello:" + hello);return userService.queryById(id);
}

测试:从网关的端口进入http://localhost:10010/user/1

image-20240229154921406

但是有一个问题就是,当我们需要向多个服务添加相同的过滤工厂的时候,每一个过滤条件都加在每一个服务配置后面就显得很不优雅,例如:image-20240229155256052

所以有个默认路由的概念:

image-20240229160110141

这样就减少了代码的复写,增强可读性。

5、全局过滤器GlobalFilter

全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与上一节的GatewayFilter的作用一样。

区别在于GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现

定义方式是实现GlobalFilter接口

代码实现:登录认证逻辑

package cn.pzhu.gateway;import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;/*** 权限认证过滤器(全局过滤器的实现)* <p>* 需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:* 		1.参数中是否有authorization,* 		2.authorization参数值是否为admin* 		3.如果同时满足则放行,否则拦截*/
@Order(-1) //定义优先级,过滤器优先级越高,里面的参数值越低,可以看源码学习(也可以实现Ordered接口实现不再赘述)
@Component //将AuthorizeFilter注入到spring作为一个bean
public class AuthorizeFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//1.获取请求参数ServerHttpRequest request = exchange.getRequest();MultiValueMap<String, String> params = request.getQueryParams();//2.获取参数中的authorization参数String auth = params.getFirst("authorization"); //设置需要过滤的参数//3.判断参数值是否等于adminif ("admin".equals(auth)) {//4.是,放行return chain.filter(exchange);}//5. 否,拦截 (为了让用户体验到返回的结果,这里就设置响应码401,即未登录状态图码)//5.1 设置状态码exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); //UNAUTHORIZED是401状态码的枚举类型//5.2 拦截请求return exchange.getResponse().setComplete(); //设置指示完成或错误}
}

测试:

image-20240229162830651

image-20240229163045659

6、各种过滤器的执行顺序

请求进入网关会碰到三类过滤器:当前路由的过滤器DefaultFilterGlobalFilter

请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器

示意图:

image-20240229164852614

  • 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前

  • GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定

  • 路由过滤器defaultFilter的order由Spring指定,默认是按照声明顺序从1递增。

  • 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。

以上排序原因可以查看源码来推断:

**org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()**方法是先加载defaultFilters,然后再加载某个route的filters,然后合并。

image-20240229170120054

org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法会加载全局过滤器,与前面的过滤器合并后根据order排序,组织过滤器链

image-20240229170341066

7、跨域问题的解决

什么是跨域?

跨域:域名不一致就是跨域,主要包括:

  • 域名不同: www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com

  • 域名相同,端口不同:localhost:8080和localhost8081

跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题

解决方案:CORS

跨源资源共享(CORS,或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的“预检”请求。在预检中,浏览器发送的头中标示有 HTTP 方法和真实请求中会用到的头。内容来自:mdn文档解释

前端发起一个跨域请求之后:

image-20240229172545567

网关处理跨域采用的同样是CORS方案,并且只需要简单配置即可实现:

spring:cloud:gateway:globalcors: # 全局的跨域处理add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题(浏览器询问服务器是否运行跨域)corsConfigurations:'[/**]':  #拦截那些请求,/**表示拦截所以请求allowedOrigins: # 允许哪些网站的跨域请求- "http://localhost:8090"- "http://www.leyou.com"allowedMethods: # 允许的跨域ajax的请求方式- "GET"- "POST"- "DELETE"- "PUT"- "OPTIONS"allowedHeaders: "*" # 允许在请求中携带的头信息allowCredentials: true # 是否允许携带cookiemaxAge: 360000 # 这次跨域检测的有效期,在这个时间内不用再次检测是否允许跨域

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

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

相关文章

模拟队列(数组实现)

题目描述&#xff1a; 代码模板&#xff1a; int q[N],hh,tt -1;//插入操作 void push(int x) {q[tt] x; }//弹出操作 void pop() {hh ; }//判断是否为空 bool empty() {if(hh > tt) return true;else return false; }//返回队首元素 int query() {return q[hh]; }AC代…

【wails】(6):使用wails做桌面应用开发,使用gin+go-chatglm.cpp进行本地模型运行,在windows上运行成功

1&#xff0c;整体架构说明 主要使用&#xff0c;参考的开源项目是&#xff1a; https://github.com/wailsapp/wails 前端项目&#xff1a; https://github.com/Chanzhaoyu/chatgpt-web 运行模型&#xff1a; https://github.com/Weaxs/go-chatglm.cpp 参考代码&#xff1a; h…

React富文本编辑器开发(一)

这是一个系统的完整的教程&#xff0c;每一节文章的内容都很重要。这个教程学完后自己可以开发出一个相当完美的富文本编辑器了。下面就开始我们今天的内容&#xff1a; 安装 是的&#xff0c;我们的开发是基于Slate的开发基础&#xff0c;所以要安装它&#xff1a; yarn ad…

第19章-IPv6基础

1. IPv4的缺陷 2. IPv6的优势 3. 地址格式 3.1 格式 3.2 长度 4. 地址书写压缩 4.1 段内前导0压缩 4.2 全0段压缩 4.3 例子1 4.4 例子 5. 网段划分 5.1 前缀 5.2 接口标识符 5.3 前缀长度 5.4 地址规模分类 6. 地址分类 6.1 单播地址 6.2 组播地址 6.3 任播地址 6.4 例子 …

5GC SBA架构

协议标准&#xff1a;Directory Listing /ftp/Specs/archive/23_series/23.501/ (3gpp.org) NF描述说明NSSFNetwork Slice Selection Function网络切片选择&#xff0c;根据UE的切片选择辅助信息、签约信息等确定UE允许接入的网络切片实例。NEF Network Exposure Function网络开…

在vue2中使用饼状图

1.引入vue2和echarts <script src"https://cdn.jsdelivr.net/npm/vue2.7.14/dist/vue.js"></script> <script src"https://cdn.jsdelivr.net/npm/echarts5.4.0/dist/echarts.min.js"></script> 2.1 补充基本的body内容 <div id…

Vue开发实例(七)Axios的安装与使用

说明&#xff1a; 如果只是在前端&#xff0c;axios常常需要结合mockjs使用&#xff0c;如果是前后端分离&#xff0c;就需要调用对应的接口&#xff0c;获取参数&#xff0c;传递参数&#xff1b;由于此文章只涉及前端&#xff0c;所以我们需要结合mockjs使用&#xff1b;由于…

智慧公厕:让城市更智慧、更环保

在现代社会&#xff0c;智慧公厕作为城市管理的重要一环&#xff0c;是智慧城市的重要组成部分&#xff0c;其建设的价值十出突出&#xff0c;是公共厕所信息化升级改造的核心方案。如智慧公厕源头厂家广州中期科技有限公司&#xff0c;所自主研发的智慧公厕整体解决方案&#…

docker-mysql:5.7安装

1、下载mysql:5.7镜像 [rootlocalhost ~]# docker search mysql (某个XXX镜像名字) [rootlocalhost ~]# docker pull mysql:5.7 按装之前查看一下是否按装过mysql。如果安装过会占用3306端口。 [rootlocalhost ~]# ps -ef | grep mysql 2、安装 # -d&#xff1a;后台运行 #…

VL817-Q7 USB3.0 HUB芯片 适用于扩展坞 工控机 显示器

VL817-Q7 USB3.1 GEN1 HUB芯片 VL817-Q7 USB3.1 GEN1 HUB芯片 VIA Lab的VL817是一款现代USB 3.1 Gen 1集线器控制器&#xff0c;具有优化的成本结构和完全符合USB标准3.1 Gen 1规范&#xff0c;包括ecn和2017年1月的合规性测试更新。VL817提供双端口和双端口4端口配置&…

Go 互斥锁的实现原理?

Go sync包提供了两种锁类型&#xff1a;互斥锁sync.Mutex 和 读写互斥锁sync.RWMutex&#xff0c;都属于悲观锁。 概念 Mutex是互斥锁&#xff0c;当一个 goroutine 获得了锁后&#xff0c;其他 goroutine 不能获取锁&#xff08;只能存在一个写者或读者&#xff0c;不能同时…

数据抽取平台pydatax介绍--实现和项目使用

数据抽取平台pydatax实现过程中&#xff0c;有2个关键点&#xff1a; 1、是否能在python3中调用执行datax任务&#xff0c;自己测试了一下可以&#xff0c;代码如下&#xff1a; 这个str1就是配置的shell文件 try:result os.popen(str1).read() except Exception as …

Vue2:用node+express部署Vue项目

一、编译项目 命令 npm run build执行命令后&#xff0c;我们会在项目文件夹中看到如下生成的文件 二、部署Vue项目 接上一篇&#xff0c;nodeexpress编写轻量级服务 1、在demo中创建static文件夹 2、将dist目录中的文件放入static中 3、修改server.js文件 关键配置&…

【EAI 026】RoboGen: 通过自动数据生成管线实现机器人技能学习

Paper Card 论文标题&#xff1a;RoboGen: Towards Unleashing Infinite Data for Automated Robot Learning via Generative Simulation 论文作者&#xff1a;Yufei Wang, Zhou Xian, Feng Chen, Tsun-Hsuan Wang, Yian Wang, Zackory Erickson, David Held, Chuang Gan 作者单…

2.26 Qt day4+5 纯净窗口移动+绘画事件+Qt实现TCP连接服务+Qt实现连接数据库

思维导图 Qt实现TCP连接 服务器端&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QTcpServer>//服务器端类 #include<QTcpSocket>//客户端类 #include<QMessageBox>//消息对话框类 #include<QList>//链…

笔记72:关于IMU(惯性测量单元)传感器的作用【不涉及公式推导】

一、IMU传感器是什么&#xff1a; 惯性测量单元IMU&#xff08;Inertial Measurement Unit&#xff09;是一种使用【加速度计】和【陀螺仪】来测量【物体三轴姿态角&#xff08;空间姿态&#xff09;】的装置&#xff1b;IMU在坐标系的每个坐标轴上&#xff0c;均安装有1个陀螺…

分销小程序的常见功能

分销小程序是一种非常有前景和潜力的产品形式&#xff0c;可以帮助企业快速拓展销售渠道&#xff0c;增加销售额。下面我将介绍分销小程序的常见功能。 1. **分销商注册与管理**&#xff1a;支持任何用户自动成为分销商&#xff0c;也可以支持有会员等级&#xff08;或付费或审…

计算机网络:IP

引言&#xff1a; IP协议是互联网协议族中的核心协议之一&#xff0c;负责为数据包在网络中传输提供路由寻址。它定义了数据包如何在互联网上从源地址传输到目的地址的规则和流程。IP协议使得各种不同类型的网络设备能够相互通信&#xff0c;实现了全球范围内的信息交换。 目录…

第三百七十八回

文章目录 1. 概念介绍2. 实现方法2.1 maskFilter2.2 shader 3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"两种阴影效果"相关的内容&#xff0c;本章回中将介绍如何绘制阴影效果.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概…

StarRocks实战——携程酒店实时数仓

目录 一、实时数仓 二、实时数仓架构介绍 2.1 Lambda架构 2.2 Kappa架构 三、携程酒店实时数仓架构 3.1 架构选型 3.2 实时计算引擎选型 3.3 OLAP选型 四、携程酒店实时订单 4.1 数据源 4.2 ETL数据处理 4.3 应用效果 4.4 总结 原文大佬的这篇实时数仓建设案例有借…