微服务的网关配置

news/2025/3/19 0:13:52/文章来源:https://www.cnblogs.com/Abner-rudolf/p/18780127

微服务的网关配置

1. 网关路由

1.1 网关

1.1.1 存在问题

单体架构时我们只需要完成一次用户登录、身份校验,就可以在所有业务中获取到用户信息。而微服务拆分后,每个微服务都独立部署,这就存在一些问题:每个微服务都需要编写身份校验、用户信息获取的接口,非常麻烦

用户身份校验最好放在一个统一的地方,例如:网关。

1.1.2 认识网关

顾明思议,网关就是络的口。数据在网络间传输,从一个网络传输到另一网络时就需要经过网关来做数据的路由和转发以及数据安全的校验

实现 java 微服务网关的技术:

  • Netflix Zuul:早期实现,目前已经淘汰

  • Spring Cloud Gateway:基于 Spring 的 WebFlux 技术,完全支持响应式编程,吞吐能力更强

Spring Cloud Gateway 使用参考官网

使用 Spring Cloud Gateway 实现网关,如下图:

前端请求网关根据请求路径路由到微服务,网关从 nacos 获取微服务实例地址将请求转发到具体的微服务实例上。

生产环境中网关也是集群部署,在网关前边通过 nginx 进行负载均衡,如下图:

1.2 实现网关路由

1.2.1 配置

创建网关工程;

引入依赖

<properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies><!-- common:通用工具服务,有则添加 --><dependency><groupId>com.hmall</groupId><artifactId>hm-common</artifactId><version>1.0.0</version></dependency><!-- 网关 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- nacos discovery --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- 负载均衡 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
</dependencies>

创建启动类

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

修改配置文件

server:port: 8080
spring:application:name: gatewaycloud:nacos:server-addr: 192.168.101.68:8848gateway:routes:- id: item # 以 item-service 举例,根据实际修改uri: lb://item-servicepredicates:- Path=/items/**

路由规则 routes 包括四个属性,定义语法如下:

  • id:路由的唯一标示

  • predicates:路由断言,Predicates 是用于判断请求是否满足特定条件的组件。

  • filters:路由过滤条件,稍后讲解。

  • uri:路由目标地址,lb://代表负载均衡,从注册中心获取目标微服务的实例列表,并且负载均衡选择一个访问。

  • -:用于表示数组

1.2.2 配置项

predicates 属性,也就是路由断言。Spring Cloud Gateway 中支持的断言类型有很多:

名称 说明
Cookie 请求必须包含某些 cookie
Header 请求必须包含某些 header
Host 请求必须是访问某个host(域名)
Method 请求方式必须是指定方式
Path 请求路径必须符合指定规则
weight 权重处理

常用的类型就是 Header、Path,Header 的使用如 - Header=X-Request-Id, \d+,说明请求头中包含属性 X-Request-Id,且对应的值为数字。

2. 网关鉴权

2.1 认识网关鉴权

单体架构时我们只需要完成一次用户登录、身份校验,就可以在所有业务中获取到用户信息。而微服务拆分后,每个微服务都独立部署,不再共享数据。也就意味着每个微服务都需要做身份校验,这显然不可取。

我们的登录是基于 JWT 来实现的,校验 JWT 的算法复杂,而且需要用到密钥。如果每个微服务都去做身份校验,这就存在着两大问题:

  1. 每个微服务都需要知道 JWT 的密钥,不安全。

  2. 每个微服务重复编写身份校验代码、权限校验代码,代码重复不易维护。

网关鉴权是指在网关对请求进行身份验证的过程。这个过程确保只有经过授权的用户或设备才能访问特定的服务或资源。

流程如下:

  1. 用户登录成功生成 token 并存储在前端

  2. 前端携带 token 访问网关

  3. 网关解析 token 中的用户信息,网关将请求转发到微服务,转发时携带用户信息

  4. 微服务从 http 头信息获取用户信息

  5. 微服务之间远程调用使用内部接口(无状态接口

2.2 网关内置过滤器

网关过滤器链中的过滤器有两种:

  1. GatewayFilter:路由过滤器,作用范围比较灵活,可以是任意指定的路由 Route
  2. GlobalFilter:全局过滤器,作用范围是所有路由,不可配置。

FilteringWebHandler 在处理请求时,会将 GlobalFilter 装饰为 GatewayFilter,然后放到过滤器链中,排序以后依次执行。

Gateway 中内置了很多的 GatewayFilter,详情可以参考官方文档:

常用的过滤器:StripPrefix

router- id: producturi: lb://item-servicepredicates:- Path=/product/**filters:- StripPrefix=1

StripPrefix=1 表示去除一级路径前缀,使用 StripPrefix=1

请求:http://localhost:8080/product/items

经过网关转换后,实际请求路径:http://localhost:8081/items

2.3 自定义过滤器

2.3.1 GlobalFilter 过滤器

package com.hmall.gateway.filter;@Component
@Slf4j
public class PrintAnyGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 编写过滤器逻辑log.info("打印全局过滤器");// 放行return chain.filter(exchange);// 拦截// ServerHttpResponse response = exchange.getResponse();// 修改状态码// response.setRawStatusCode(401);// return response.setComplete();}@Overridepublic int getOrder() {// 过滤器执行顺序,值越小,优先级越高return 0;}
}

全局过滤器不用在路由中配置。

package com.hmall.gateway.config;// 配置拦截路径
@Data
@ConfigurationProperties(prefix = "hm.auth")
public class AuthProperties {private List<String> includePaths;private List<String> excludePaths;
}

2.3.2 GatewayFilter 过滤器

自定义 GatewayFilter 不是直接实现 GatewayFilter,而是继承 AbstractGatewayFilterFactory

注意:该类的名称一定要以 GatewayFilterFactory 为后缀!

package com.hmall.gateway.filter;@Component
@Slf4j
public class FirstFilterGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {@Overridepublic GatewayFilter apply(Object config) {return new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange,GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();log.info("请求路径:{}",request.getPath());log.info("网关过滤器FirstFilterGatewayFilterFactory执行啦...");// 放行return chain.filter(exchange);// 拦截 返回401状态码// exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);// return exchange.getResponse().setComplete();}};}
}

路由过滤器需要在配置中配置过滤器:

- id: producturi: lb://item-servicepredicates:- Path=/product/**filters:- StripPrefix=1- FirstFilter # 此处直接以自定义的 GatewayFilterFactory 类名称前缀类声明过滤器

2.3.3 总结

两种自定义过滤器的方式:

  1. GatewayFilter:路由过滤器

    作用范围比较灵活,可以是任意指定的路由 Route.

    继承 AbstractGatewayFilterFactory ,并在路由配置中指定过滤器。

    过滤器的名称规则:以 GatewayFilterFactory 作为后缀。

  2. GlobalFilter:全局过滤器

    作用范围是所有路由,不可配置。

    实现 GlobalFilter 接口。

    实现 Ordered 接口可以指定过滤器顺序,实现 getOrder() 方法,返回值越小优先级越好。

2.4 身份校验过滤器

2.4.1 引入 JWT 工具类

参考资料

./
│
├── com.*.gateway/
│    │
│    ├── config/
│    │    ├── AuthProperties.java   # 配置身份校验需要拦截的路径
│    │    ├── JwtProperties.java   # 定义与JWT工具有关的属性,比如秘钥文件位置
│    │    └── SecurityConfig.java   # 工具的自动装配
│    │
│    └── util/
│         └── JwtTool.java   # JWT工具,其中包含了校验和解析 token 的功能
│
└── resources/│└── hmall.jks   # 秘钥文件

2.4.2 配置白名单

其中 AuthPropertiesJwtProperties 所需的属性要在 application.yaml 中配置

hm:jwt:location: classpath:hmall.jks # 秘钥地址alias: hmall # 秘钥别名password: hmall123 # 秘钥文件密码tokenTTL: 30m # 登录有效期auth:excludePaths: # 无需身份校验的路径- /search/**- /users/login- /items/**

excludePaths 配置白名单地址,即无需身份校验的路径。

2.4.3 身份校验过滤器

./
│
└── com.*.gateway/└── filter/└── AuthGlobalFilter.java

2.5 总结

网关身份校验过滤器怎么实现?

我们项目中网关身份校验过滤器使用 Spring cloud Gateway 的 GlobalFilter 实现,GlobalFilter 是一种全局过滤器。实现过程如下:

  1. 配置密钥、白名单 等相关信息。

  2. 编写身份校验过滤器,实现 GlobalFilter 接口。

  3. 首先判断请求地址是否是白名单地址,如果是则放行

  4. 取出 http 头中的 token,然后校验 token 的合法性

  5. 如果 token 合法则将 token 中的用户信息向下传给微服务

  6. 如果 token 不合法则拒绝访问。


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

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

相关文章

博客图床 VsCode + PigGo + 阿里云OSS方案

关键字 写博客,图床,VsCode,PigGo,阿里云OSS 背景环境 我想把我在本地写的markdown文档直接搬到CSDN上和博客园上,但是图片上传遇到了问题。我需要手动到不同平台上传文件,非常耗费时间和经历。 为了解决这个问题,我想到了图床方案,我只需要把图片链接放到我本地写好的…

20244203张晨曦 实验一《Python程序设计》实验报告

20244203张晨曦《Python程序设计》实验一报告 课程:《Python程序设计》 班级: 2442 姓名: 张晨曦 学号:20244203 实验教师:王志强 实验日期:2025年3月18日 必修/选修: 专选课 1.实验内容 1.熟悉Python开发环境; 2.练习Python运行、调试技能; 3.编写程序,练习变量和…

Cobalt Strike基础

Cobalt Strike基础 Staged(有阶段) 在有阶段的执行方式中,分为Stager和Stage两个阶段Stager(初始执行载荷):​ 定义:Stager是Stage 1,是一个较小的、轻量级的初始执行载荷 ​ 作用:与服务端建立初始连接,并从服务器下载更大的Payload,也就是Stage2Stage(更大、…

OP222柔性振动白色料盘污染会引发的问题

下图为污损的料盘料盘污损会导致以下问题: 1.料盘里面缺料但是后面料仓就是不送料 柔性振动系统里面设置了加料个数,下图里面设置为15,表示如果相机识别区域里面的总阴影面积<15个零件面积,料仓加一次料。下图红框是识别区域,里面一道道横杠就是污损导致的阴影,这些阴…

鸿蒙特效教程05-鸿蒙很开门特效

鸿蒙特效教程05-鸿蒙很开门特效本教程适合HarmonyOS初学者,通过简单到复杂的步骤,通过层叠布局 + 动画,一步步实现这个"鸿蒙很开门"特效。本教程能收获Stack 层叠布局 animate、animateTo 动画 @State 状态管理最终效果预览 屏幕上有一个双开门,点击中间的按钮后…

An Elder Brother Is Like a Father :My True Story

![](https://img2024.cnblogs.com/blog/3617180/202503/3617180-20250318230914275-242579668.jpg)An Elder Brother Is Like a Father :My True Story In your life, do you have a very important person? Who is he/she? Why is he/she significant for you and whats you…

element-plus学习 -2025/3/18

{ ...this.form } 是 JavaScript 中的 ​扩展运算符(Spread Operator)​,它的作用是将 this.form 对象的所有属性“展开”到一个新的对象中 例如 form :{ name : , score: } 简易学生分数管理系统 element-plus实现 <!DOCTYPE html> <html lang="en">…

web161笔记(getimagesize()图片文件头检测)

这次上传失败了,尝试在头部加了图片文件头,就过去了,所以这里应该是用了getimagesize()进行检测getimagesize(): 会对目标文件的16进制去进行一个读取,去读取头几个字符串是不是符合图片的要求所以在上题的基础上都加个GIF89a图片头就可以了 GIF89a加个图⽚的头欺骗检测 .u…

MIT6.5840 2024 Spring Lab1

MIT6.5840 2024 Spring Lab1 前言本文主要作为笔记使用,这次实验基本是边查GO的语法边做的,所以代码写的不够优雅,无法充分发挥GO的一些特性,因此本文的代码实现有很大的优化空间,欢迎各位大佬指正,希望本文能给一些正在学习的小伙伴提供一些思路。最后希望小伙伴们不要抄代码,…

OP222机器人与柔性振动盘交互逻辑

1.机器人运行逻辑主体逻辑就是PLC发送取料指令后,机器人向柔性振动系统索要OK件的坐标-->柔性振动系统接收到指令后拍照,识别出OK件就发送其坐标,找不到OK件就振动一下再拍照-->机器人通过获取到的坐标去取料-->取料后检查真空吸盘负压信号,如果吸住了即取料成功,…

web157-web159笔记(+分号;过滤+()过滤)

web157 .user.ini正常上传了,但是在传mumuzi.png的时候出错看来⼜过滤了什么不知名的东⻄,测试删掉system报错,tac报错,然后发现是分号的问题。这⾥ 使⽤反引号(相当于shell_exec() )<?=`tac ../f*`?> (后来发现短标签可以不要分号…

20244213 实验一《Python程序设计》实验报告

实验一 课程:《Python程序设计》 班级: 2442 姓名: 孙爱宣 学号:20244213 实验教师:王志强 实验日期:2025年3月18日 必修/选修: 公选课 1.实验内容 1.熟悉Python开发环境; 2.练习Python运行、调试技能; 3.编写程序,练习变量和类型、字符串、对象、缩进和注释等;编…