当前位置: 首页 > news >正文

第33周JavaSpringCloud微服务 电商进阶开发

一、课程介绍

1. 定时任务

  • 课程主题 :Spring Cloud 电商进阶开发
  • 定时任务定义 :学习什么是定时任务。
  • 定时任务学习内容 :定时任务实现方法、cron 表达式。
  • 定时任务实践 :在 Spring 中使用 schedule 注解,定期关闭过期订单。

2. 性能与安全性提升

  • 项目性能与安全性提升概述 :对整个项目的性能和安全性进行提升。
  • 性能提升方法 :应用线程池优化发送邮件速度。
  • 安全性提升策略 :使用特定技术(如 “福”)解决安全隐患,增强入网关安全性。

3. 新技术

  • 新技术介绍 :Spring Cloud Gateway。
  • Spring Cloud Gateway 内容 :相对新颖。
  • Spring Cloud Gateway 用途 :开发网关、实现之前路由的能力。
  • Spring Cloud Gateway 重要部分 :定时任务。

4. 项目面试

  • 项目面试辅导内容概述 :包括介绍开发项目的思路、回答相关问题的方法。
  • 课程常见问题解决 :课程中常见问题的解答。

课程总结与重点提炼 :Spring Cloud 电商进阶开发课程梳理、重点提炼,尤其是定时任务部分。

一、定时任务

1. 定时任务的内容

  • 定时任务内容概述 :介绍定时任务的相关内容。
  • 使用场景 :介绍定时任务的应用场景。
  • cron 表达式 :详细介绍 cron 表达式的原理与写法。
  • 代码实操 :使用 schedule 注解结合 cron 表达式实现定期取消超时订单的功能。

2. 定时任务的使用场景

  • 定时任务典型场景一 :更新和处理数据。

    • 每日更新用户使用情况。
    • 批量处理脏数据。
    • 适合凌晨进行数据维护。
    • 金融领域常见。
  • 定时任务典型场景二 :定时更新天气数据。

    • 每 15 分钟更新一次。
    • 天气数据变化不快,无需每秒更新。
    • 定时更新有必要。

3. CRON 表达式

1)CRON 表达式的介绍

  • CRON 表达式定义 :它是一个以五个空格隔开的字符串,分为六个域。
  • CRON 表达式各域含义
    • 第一位:秒(0 - 59)
    • 第二位:分(0 - 59)
    • 第三位:小时(0 - 23)
    • 第四位:日期(1 - 31)
    • 第五位:月份(1 - 12)
    • 第六位:星期(0 - 6)

2)CRON 表达式的符号

  • 星号

    • 星号含义 :代表每。
    • 秒位星号 :每秒钟都要去做某事。
    • 日位星号 :每天的某时刻去做某事。
  • 问号

    • 问号的含义 :代表值不确定。
    • 问号使用场景 :不关心具体值时的替代符号。
    • 问号示例 :定 1 月 10 号不关心星期几时用问号代替。
  • 减号 / 逗号

    • 减号(横杠)的定义 :代表一个范围。
    • 减号(横杠)的用法 :用减号表示时间段的区间,如 “十到十二点” 写成 “10 - 12”。
    • 逗号的定义 :代表一个列表的值,相当于枚举。
    • 逗号的用法 :在日期选择中,用逗号分隔不同的日期,如 “1,2,4” 代表一号、二号、四号。
  • 斜杠

    • 斜杠定义 :x 杠 y 中 x 代表开始值,y 代表步长。
    • 斜杠用法示例 :零杠 15 表示从零秒开始,每 15 秒做一次事情。
    • 斜杠执行时间 :按步长依次执行,如零秒、十五秒、三十秒等。

3)应用案例

  • 例题 :CRON 表达式示例。
  • CRON 表达式含义 :00 03 * * ? 代表每天三点执行。
  • CRON 表达式时间位 :秒、分钟、小时。
  • CRON 表达式日期位 :用星号表示每天。
  • CRON 表达式星期位 :问号代表不确定。
  • 升级表达式 :05 03 * * ? 代表每天 3 点 5 分执行。
  • 步长表示法 :在分钟位置用五杠十表示每隔十分钟执行。

二、总结

  • 本小节内容概述 :介绍括号表达式及 CLR on 表达式符号含义。
  • 括号表达式 :了解每一位的含义。
  • CLR on 表达式 :掌握星号、问号、减号、逗号、斜杠等符号含义。
  • 下一小节预告 :进入 Spring 中定时任务的实操部分。

一、定时任务类

1. 定时任务功能

  • 功能介绍 :实现查询并取消超时未付款订单。
  • 多实例问题 :多集群多实例同时运行定时任务可能导致资源浪费或数据出错。
  • 分布式锁应用 :在定时任务中使用分布式锁,确保任务执行实例只有一台,防止数据错误和资源浪费。

2. 订单取消

  • 订单取消主题 :长期不付款订单处理。
  • 实现目标 :定时捞出长期不付款订单。
  • 实现方法 :编写方法于 service 中。

3. 写定时任务方法

  • 方法目标 :编写定时任务方法以处理订单。
  • 订单获取 :通过方法 getUnpaidOrders() 获取未付款订单列表。
  • 时间范围设定
    • 获取当前时间 currentTime。
    • 设定查询起始时间 beginTime 为 currentTime 减一天,使用 DateUtility 的 atDays 方法,传入 - 1 实现时间减法。
    • 订单筛选:以 beginTime 和 currentTime 为时间范围限制,筛选订单。

4. 写订单取消方法

  • 方法名称 :select on paid orders。
  • 返回参数 :list,里面是一个 order。
  • 参数详情 :begin time(日期类型)、current time(改为 cur,即 current 的前三个字母)。

5. 定义捞取订单方法

  • 实现查询语句 :复制并替换方法名。
  • 修改实现细节 :select base column list,加 where 条件。
  • 设置 where 条件 :create time 在两者之间,用 between,参数为 beginTime 和 currentTime。
  • 添加订单状态条件 :未付款订单,order status 等于 10。
  • 在服务中使用 map 方法 :orderMap.selectUnpaid,传入 beginTime 和 currentTime。
  • 获取返回值 :命名为 unpaidOrders。
  • 方法命名与返回 :方法名为 getUnpaidOrders,返回 unpaidOrders。
  • 方法提炼与接口 :加 override,提炼到接口中,接口中增加该方法。

6. 写定时任务类

1)定义定时任务类

  • 定义定时任务类 :在 cut order 中新建类,类名为 job configuration,代表任务,类的修饰加上 component。

2)定时任务方法 1

  • 定时任务方法概述 :介绍了两种写定时任务的方法。
  • 第一种定时任务方法 :创建一个 logger;使用 log 打印任务开始和结束;设置线程休眠时间;使用 @Scheduled 注解;设置 fixed rate 为三秒钟。
  • 任务执行验证 :通过日志输出验证任务是否按照预期时间间隔执行,间隔时间与设定的三秒保持一致。

3)定时任务方法 2

  • 重点内容 :cron 表达式。
  • cron 表达式赋值 :使用括号表达式。
  • 执行频率设置 :如每隔三秒执行一次,使用 “零杠三后面星号,最后经期问号” 表示。
  • cron 表达式生效验证 :通过日志检查执行时间间隔是否符合预期。
  • 后续步骤 :实现自己的业务逻辑。

4)应用案例

  • 例题 1 :订单取消功能实现。

    • 实现目标 :批量取消未付款订单。
    • 核心方法 :使用 order service 的 get unpaid orders 方法获取未付款订单,然后遍历每个订单,使用 cancel 方法传入 order number 进行取消。
    • 用户身份校验逻辑调整 :为了支持系统批量取消订单,对 cancel 方法进行升级,增加布尔参数 is from system。如果参数为 true,表示来自系统,跳过用户身份校验;如果为 false,进行用户身份校验。
  • 例题 2 :任务执行时间设定。

    • 与业务逻辑关系 :息息相关。
    • 执行时间示例 :每五分钟执行一次。
    • 时间范围设定 :起始时间与截止时间。
    • 起始时间设定 :当前时间往前推 24 小时再往前推执行周期的时间。
    • 截止时间设定 :当前时间往前推 24 小时。
    • 配合执行周期 :每五分钟执行一次,捞取并取消未付款订单。
  • 例题 3 :订单捞取功能实现。

    • 项目重启与定时任务 :每五分钟执行一次 job,用于订单捞取。
    • 时间运算与断点调试 :利用时间运算方法,查看 begin time 和 end time 以理解时间处理;设置断点检查时间是否符合预期。
    • 订单捞取逻辑 :end time 为当前时刻(昨天),begin time 为当前时刻再减五分钟;服务稳定运行,确保订单正确捞取。
    • 分布式锁计划 :在订单捞取基础上,计划添加分布式锁以增强功能。

5)加上分布式锁

  • 回顾分布式锁写法 :查看之前分布式锁的写法。
  • 引入 red client :在 job 中引入 red client。
  • 复制加锁方法 :把之前的加锁方法复制到当前 job 中。

二、使用 @Scheduled 注解实现定时任务

  • 定时任务改造 :替换业务逻辑,增加分布式锁能力。
  • 分布式锁执行流程 :先抢锁,成功则执行任务并释放锁,失败则打印语句。
  • 分布式锁的作用 :避免资源浪费,避免数据出错。

三、内容总结

  • 小节内容概述 :回顾本小节知识点。
  • 代码实操内容 :使用 schedule 实现定时任务。
  • 定时任务细节 :使用 cron 表达式,每五分钟捞取未付款订单并自动取消。
  • 程序功能扩展 :区分系统调用与用户调用。
  • 程序优化措施 :加入分布式锁,提升程序稳定性。

一、线程池和 ThreadLocal 在项目中的应用

1. ThreadLocal 的应用

1)问题发现及分析

  • ThreadLocal 应用背景 :在项目中生成订单号,订单号生成方式为时间(年月日时分秒) + 五位随机数。
  • SimpleDateFormat 类问题 :订单量大时,频繁创建和销毁对象。
  • 优化方案 :每个线程保存一个 SimpleDateFormat 对象,节省创建和销毁时间。

2)问题升级及实现

  • 升级过程概述 :使用 public static 和 thread local。
  • 类类型定义 :simple data format。
  • 类命名 :simple data format three local。
  • 方法重写 :重写 initial value 方法,目的为每个线程第一次获取时创建新对象,线程间对象不共享,保证线程安全。
  • 使用方式 :通过 three local 的 get 方法获取对象。
  • 升级效果 :提高性能,避免重复创建和销毁过程。

2. 电商项目中发邮件过程的异步处理

1)问题发现及分析

  • 问题背景 :spring boot 电商项目发邮件过程。
  • 当前实现方式 :使用 email service 的 send simple message 方法。
  • 当前实现问题 :用户需等待邮件发送完成才能得到成功返回,效率低。
  • 优化方向 :对邮件发送进行异步化处理。

2)配置线程池

  • 配置线程池基本步骤 :在 config 中新建 thread pool config 类。
  • 配置描述 :添加 configuration 注解。
  • 线程池配置详情 :定义 public executor service,return 新线程池,指定核心线程数 10、最大线程数 20、keep a lifetime 为 0 毫秒,新建 linked blocking q。
  • 应用配置 :在 user controller 中使用配置好的线程池。

3)用户控制器的升级

  • 引入与关联 service :使用 out 和 execute service,关联 xq 的 service。
  • 升级发邮件功能 :使用 submit 方法将任务提交到线程池进行后台处理,避免前台等待。
  • 升级改造总结 :第一个升级优化 three local 性能和内存,第二个升级解决发邮件接口慢的问题。

二、Zuul 安全性增强

1. 屏蔽接口转发

  • 屏蔽接口转发背景 :为了增强 zoo 的安全能力,需屏蔽不希望被外部访问的接口。
  • 需屏蔽的接口类型 :内部使用接口,如更新库存、获取用户信息等。
  • 屏蔽接口的配置方法 :在 zoo 的配置文件中设置 “zoo ignore patterns”,以数组形式添加需屏蔽的接口 URL。
  • 验证屏蔽效果 :先注释屏蔽规则,确认接口可访问;启用屏蔽规则后,接口无法访问。

2. 异常统一处理

  • Spring Boot 中的异常处理 :使用 global exception handler 进行统一处理。
  • Spring Cloud 中的异常处理问题 :订单服务未纳入 global exception handler。
  • 解决方法 :通过 components can 将异常处理 handler 纳入服务,需要指定当前包路径和异常处理所在包路径。
  • 效果展示 :重启项目后,异常返回格式统一。
  • 其他模块改造 :user application 和 product application 同样需要添加 components can 配置。
  • 配置要点 :必须同时指定当前包路径和异常处理所在包路径,否则无法统一处理异常。

三、新技术介绍

1. Spring Cloud Gateway 介绍

1)Spring Cloud Gateway 与 Zuul 对比

  • 社区与资料 :Spring Cloud Gateway 作为较新的组件,社区活跃度和资料丰富程度相对较低,但仍在快速发展中。
  • 性能 :Spring Cloud Gateway 与 Zuul 2.x 在性能上相当,没有明显优劣。
  • 结合性 :Spring Cloud Gateway 与 Spring Cloud 生态结合更紧密,而 Zuul 2.x 的结合性可能不如 1.x 版本。
  • 升级成本 :从 Zuul 迁移到 Spring Cloud Gateway 存在升级成本,且可能遇到新问题,但对于新项目,可以考虑使用 Spring Cloud Gateway。

2)开发 Spring Cloud Gateway

  • 开发流程

    • 初始化项目 :由于 Spring Cloud Gateway 与 Spring MVC 框架不同,需新建一个独立项目而非作为子模块开发。选择 Java 8 版本,Spring Boot 版本(如 2.3.10.RELEASE),并引入相关依赖,包括 spring-cloud-starter-gateway 和 spring-boot-starter-test 等。
    • 完善过滤器
      • 过滤器作用 :实现 API 路由、请求过滤等功能,如身份验证、URL 拦截等。
      • 实现过滤器 :继承 AbstractGatewayFilterFactory 类,并重写 apply 方法。
      • 拦截逻辑 :对于不需对外公开的接口(如 /getUser、/checkAdminRole 等),直接返回 403 Forbidden 状态码;对于不需鉴权的接口(如 /image、/pay 等),放行请求;对于需要鉴权的接口,从请求头中获取 JWT token,进行验证。
  • 代码示例 :Spring Cloud Gateway 与 Zuul 在过滤器实现方式上有较大差异,需适应新的编程模型。

四、知识小结

知识点核心内容考试重点 / 易混淆点难度系数 Spring Cloud Gateway 介绍是一个基于 Spring 生态的网关工具,用于 API 路由和提供过滤器功能

  • 区分 Spring Cloud Gateway 与其他网关(如 Zuul)的区别
  • 理解 Spring Cloud Gateway 的作用和核心功能★★★☆☆ Spring Cloud Gateway 与 Zuul 的对比
    • 社区成熟度与活跃度
    • 性能对比
    • 与 Spring Cloud 体系的结合紧密程度
    • Spring Cloud Gateway 是较新的组件,社区资料相对不丰富
    • 性能与 Zuul 不相上下
    • 与 Spring Cloud 体系结合更密切★★★★☆ Spring Cloud Gateway 的开发流程
    • 初始化项目
    • 实现转发
    • 自定义前缀配置
    • 开发过滤器
    • 升级 user frame
    • 整体测试
    • 初始化项目时需注意不能与 Spring MVC 兼容,需新建 project
    • 过滤器开发是核心,需实现身份验证和地址排除★★★★★过滤器的实现
    • 继承 AbstractGatewayFilterFactory 类
    • 重写 apply 方法
    • 对不想公开的接口进行拦截
    • 对不需要验证的接口进行放行
    • 对需要验证的接口进行 JWT token 解析
    • 拦截和放行的逻辑实现
    • JWT token 的获取和解析★★★★★ JWT token 的健全方式
    • 从 header 中获取 token
    • 检查 token 是否存在
    • 解析 token 并获取用户信息
    • 理解 token 在微服务架构中的使用
    • 掌握 token 的获取和解析方法★★★★☆

注:难度系数以五角星表示,最高为五颗星,表示该知识点难度较大,需要深入理解;最低为一颗星,表示该知识点相对简单,只需基本了解。

五、网管鉴权过滤器编写

1. 获取 token 并校验

1)重写 apply 方法

  • 校验 jwt :使用 jwt 的 algorithm 进行校验。
  • 定义常量 :定义 key 及其它相关常量,如 public static final string JW_TK。
  • 处理解析内容 :解析 jwt 后得到 user ID、username、user row。
  • 解码 token :使用 try 语句和 verify 方法传入 token 进行解码,获取 decode jwt。
  • 获取 jwt 内容 :通过 jwt.getClaim 方法获取 user ID,并将其转换为 int 类型。
  • 信息中转 :将解析后的信息放到请求头中,通过 current user 作为中转承载用户信息。

2)用户类的创建

  • 创建 user 类 :在网关中新建 model 包,复制 user 类到其中。
  • user 类引入与赋值 :指定 user 类来源,使用 jwt 解析内容对 current user 进行赋值。
  • 用户角色判断 :根据接口是否包含 admin,判断用户身份,非管理员不能访问管理员接口,需返回 need admin 方法。
  • need admin 方法 :定义返回内容,结束请求,告知用户被拦截原因。

3)needAdmin 方法的编写

  • 定义 server http response :从 exchange 中获取 response。
  • 设置 response 参数 :设定 status code 为 okay,添加 header(content - type 为 application/json,charset 为 utf - 8),定义返回信息(状态码、提示将 admin 的 jwt token 放到 header、返回的 data 为 null)。
  • 返回 message 和 response :使用 spring cloud gateway 相关语句,涉及流式编程,将 message 转化为 bytes,结合 response 生成 body data buffer,作为结果传递。
  • 处理 current user 属性 :赋值 row 和 user name(从 jwt 中获取)。
  • 异常处理 :解析过程中发生问题则进行 catch,返回 need login 提示用户进行登录。
  • 完成 jwt 内容解析 :最后添加注释说明。

4)把用户信息传递给后端服务

  • 传递方法 :将用户信息放到 header。
  • 具体实现步骤 :通过 exchange 获取 request,使用 mutate 方法选择 header,指定要放入的 key 和 value。
  • 需要放入 header 的信息 :user ID、user row、username。
  • 生成新的 server http request :使用 build 方法生成,并构造 server web exchange。
  • 对于普通接口的处理方法 :直接使用 train.filter 传入 exchange。

5)网关编写完成

  • 网关功能一 :拦截不想公开的接口。
  • 网关功能二 :放行不应拦截的接口。
  • 网关功能三 :健全接口并解析 JWT token。
  • 健全接口时的工作 :从 header 取 JWT token 并解析。
  • 解析后的处理 :判断是否有管理员权限要求,管理员权限校验:URL 带 admin 需管理员权限,校验不通过的处理:打回请求,校验通过的处理:信息放 paddle 传下游服务。

六、网关配置

  • 网关配置概述 :网关需要配置,主要涉及一些配置内容。
  • 微服务配置内容 :包括 ID、名字、路径。
  • 过滤器配置作用 :过滤掉转发时不需要的前缀。
  • 过滤器配置实例 :以 category product 为例,过滤掉前缀实现正常转发。
  • 网关其他配置 :配置自定义的过滤器,如 authorization filter。
  • 网关配置完成 :完成上述步骤后,网关配置完毕。

七、网关启动

  • 网关启动验证 :尝试启动网关以确认编写完成。
  • 网关类型说明 :当前网关采用 jwt 类型验证。
  • 下一步计划 :对 spring cloud 进行升级改造以适配新网关。

八、用户模块改造

1. user 模块改造

1)去掉 session 配置

  • 改造目标 :去掉和 session 相关的配置。
  • 改造模块 :user 模块。
  • 具体操作 :注释掉 spring session 的依赖。

2)改造 UserInfoFilter

  • 架构演进讨论内容 :网关升级过程与问题。
  • 处理思路和流程 :关注升级中的思考与实践落地。
  • home 和配置文件修改后操作 :注释启动类注释,不引入相应内容。
  • 需要注意的接口 :user update 接口。
  • user update 接口功能 :更新用户个人信息,要求登录。
  • 原处理方案 :从 session 中直接获取登录信息。
  • 现处理方案 :通过网关传递用户属性,添加过滤器获取。

3)添加 filter 配置类

  • 任务目标 :添加 filter 配置类。
  • 操作相似点 :与 spring boot 拦截思路相似。
  • 配置内容 :在包中添加两个过滤器配置对象。

4)复制 UserInfoFilter 代码

  • 复制代码 :直接复制 UserInfoFilter 类的代码。
  • 引入 user :在代码中引入 user 对象。
  • 添加属性 :在 common 包的 constant 中添加 username、ID、row、admin row 四个属性。

5)分析 UserInfoFilter

  • 过滤器作用 :配置 userinfo filter 使其生效。
  • 配置方式 :在配置类中引入 userinfo filter。
  • 拦截接口 :在配置中指定所拦截的接口。
  • 过滤器类型 :spring 的 filter。
  • 请求处理 :服务相关请求会经过过滤器。
  • 执行过程 :在 doFilter 方法中执行过滤逻辑。
  • 代码熟悉度 :观众应熟悉之前写过的相关代码。

6)分析 requestInterceptor

  • requestInterceptor 的作用 :处理请求中的 header 信息。
  • 处理逻辑 :先判断请求 attributes 是否为 null,为 null 则直接返回,不为 null 则获取 request 对象。
  • 获取 header 信息 :通过 getHeaderNames 方法获取 header,并赋值用户相关信息。
  • 异常情况处理 :如果 header 为空,则 currentUser 不会被赋值,后期也取不到用户相关内容。
  • 正常流程 :网关会通过后,把相关内容传过来,进行用户信息赋值。

7)分析 UserInfoFilter

  • UserInfoFilter 功能 :遍历 header 并处理。
  • 处理流程 :获取 header 名字和值、根据名字进行不同处理。
  • 具体处理 :user ID 赋值给 current user、username 设值、user row 设值。
  • currentUser 定义 :类中定义的新 user 对象,承载用户信息。
  • 校验流程 :检查 ID、name、row 是否都不为空。
  • 校验通过操作 :认为 current user 有效,存入 user thread local。
  • userThreadLocal 作用 :给每个线程存储当前 user 对象。

8)使用 ThreeLocal 获取用户信息

  • 过滤器处理后的信息 :可获取用户相关信息。
  • 用户信息处理 :将解析后的用户信息存储到 ThreeLocal。
  • 用户信息使用 :后续可通过 ThreeLocal 获取用户信息。

9)应用案例

  • 例题 :userController 改造。
  • userController 改造背景 :没有 session,原获取当前用户语句需替换。
  • 解决方案 :使用 user in for filter,创建 three local 并 get 出 user。
  • 新用户命名 :get 出的 user 命名为 current user,可全局获取。
  • current user 作用 :可获取用户 ID,进行用户信息更新。
  • spring cloud 与 jwt 逻辑升级 :验证逻辑升级为 jwt 后,服务需配合改动。
  • 其他服务改动 :card order 和 category product 服务也需按相同原理和步骤改动。

2. categoryProduct 模块改造

1)配置文件改造

  • 去除 category product 相关依赖 :在 category product 中去掉和筛选相关的依赖。
  • 注释启动类注解 :在启动类中注释掉不再需要的注解。
  • 注释配置文件中筛选相关项 :在配置文件中注释掉和筛选相关的项。

2)添加 UserInfoFilter

  • 过滤器情况说明 :每个服务独立,user 过滤器不能直接应用到 category product。
  • 处理办法 :复制 user 过滤器并粘贴。
  • 复制粘贴结果 :两个过滤器直接生效,工作相同。

3)改造 CategoryController

  • 处理目标 :改造 CategoryController。
  • 检查内容 :之前用到 session 的地方。
  • 检查结果 :ctrl 和 admin 中未使用 session。
  • CategoryController 现状 :请求参数中有 session,但未实际使用。
  • 处理结果 :CategoryController 无需额外处理 session。
  • 关联处理 :CategoryProduct 已处理完毕。

3. cartOrder 模块改造

1)改造过程概述

  • 改造过程概述 :处理 card order 主要分三步。
  • 具体步骤 :删除 session,去掉配置依赖,改造使用 session 的地方。
  • 实际操作难点 :代码多,易漏掉,考验耐心和细心。

2)改造 CartController

  • cut order 的特殊之处 :存在特殊处理。
  • 特殊处理方式 :use rf in。

3)改造 UserFeignClient

  • 类原用途 :获取用户信息。
  • 改造方式 :注释掉获取用户信息的类。
  • 用户信息新来源 :header。
  • 处理连锁反应 :需处理之前用到该类的地方。
  • 具体处理 :cut controller 中删除 use rf in,升级为 user in for filter。
  • 改造原因 :减小服务间耦合关系,使包相互独立。

4)改造 CategoryController

  • 注释 category 相关对 :避免多个 filter 情况。
  • API response 缺失问题 :缺少 common 包,需补回并核对版本。
  • 处理 userinfo filter :确认只有一个 filter,使用 three local 的 get 方法获取 ID。
  • 标红问题排查 :需要查看 spring local 以确定原因。

5)user 类移除问题

  • 问题提出 :user 类未识别到。
  • 问题原因 :user 类已从依赖中移除。
  • 解决策略 :需重新添加 user 类。

4. user 类和 product 类添加

  • 添加 user 和 product 类 :在包中添加 user 和 product。
  • 指定 user 路径 :在 ctrl 中 ID 不爆红。
  • 批量搜索和替换 :使用全局搜索 get user,在 order service 和 cart controller 中;替换为 user in for filter.user three local.get;使用 replace all 批量替换。

5. 改造 CartOrderApplication

  • 处理标红部分 :去除无用代码行。
  • 处理标红部分 :自动引入并检查。
  • 处理返回类型未找到问题 :重新引入 product。

九、产品升级

  • 升级内容概述 :完成产品升级和替换。
  • 升级具体操作 :将 session 和 use rf inclined 相关升级为 thread local,从 header 取数据。
  • 升级后续调整 :注释掉类,对之前用到的地方进行替换。
  • 升级验证 :启动程序验证改动是否 OK。

十、初始化并跑通项目

  • 运行内容 :三个业务模块和一个尤瑞卡。
  • 额外启动 :spring cloud gateway。
  • 启动后操作 :对接口进行验证。

十一、接口测试

1. 用户模块接口测试

  • 测试用户相关接口 :接口理论不被拦截。

  • 注册接口测试 :可成功注册,重名会提示。

  • 登录接口测试 :登录功能正常。

  • 个性签名更新测试

    • 不加 jwt token:会被拦住,返回 403 forbidden。
    • 加上 jwt token:可成功更新。
    • 网关及 header 信息传递:均正常工作。
  • 断点调试个性签名更新

    • 打断点位置:更新个性签名时。
    • 调试结果:能获取到 current user 里的属性。
    • jwt 内容验证:current user 属性包含 jwt 内容。

2. 商品目录和商品接口测试

  • JWT Token 获取 :作为小作业留给小伙伴,在 spring cloud 用户模块增加获取 JWT 接口。
  • 目录相关接口测试 :包括新增、更新、删除目录及目录列表呈现,需管理员登录并携带 JWT Token。
  • 商品相关接口测试 :新增、更新商品成功,删除商品需携带 JWT Token,否则提示 forbidden。

3. 订单详情接口测试

  • 订单详情接口测试 :成功进行。
  • Spring Cloud 服务测试 :已通过网关。
  • 服务承载确认 :Spring Cloud Gateway 成功承载。

十二、内容梳理

  • 项目初始化与跑通 :实现 spring cloud gateway 的首要步骤。
  • 转发实现 :包含排除不需要转发的地址、放行不需要拦截的地址、实现需要认证地址的身份认证。
  • 配置内容 :自定义前缀配置、过滤器配置(包括自定义过滤器)。
  • 微服务改造 :升级微服务、添加过滤器、删除 session、进行全流程测试。

相关文章:

第33周JavaSpringCloud微服务 电商进阶开发

一、课程介绍 1. 定时任务 课程主题 :Spring Cloud 电商进阶开发定时任务定义 :学习什么是定时任务。定时任务学习内容 :定时任务实现方法、cron 表达式。定时任务实践 :在 Spring 中使用 schedule 注解,定期关闭过期…...

基于cubeMX的hal库STM32实现硬件IIC通信控制OLED屏

1、通常的方法是使用软件模拟IIC来实现OLED屏的显示控制,这里用STM32单片机的硬件IIC来实现OLED屏的显示,主控芯片为STM32F103RCT6,正点原子mini开发板。 2、cubemx配置过程 (1)配置时钟和下载 (2&#x…...

游戏工作室为何要更换IP进行多开?工作室使用代理IP要注意什么?

在当今的游戏产业中,游戏工作室为了提升效率、规避风险或突破平台限制,常常需要通过更换IP进行多开操作。这一现象背后涉及技术、商业规则和网络安全等多重因素,而代理IP的选择与使用也成为工作室运营中的关键环节。以下是关于游戏工作室为何…...

postgreSQL 如何使用 dblink

SELECT b.id, flow_name, user_id,u.name FROM bpm_form_info b JOIN vrms_user u on b.user_idu.id dblink SELECT b.id, flow_name, user_id,u.name FROM bpm_form_info b – vrms_user u on b.user_idu.id JOIN dblink( ‘dbnameuser_db userpostgres passwordWs199612’,…...

121.在 Vue3 中使用 OpenLayers 实现去掉鼠标右键默认菜单并显示 Feature 信息

🎯 实现效果 👇 本文最终实现的效果如下: ✅ 地图初始化时绘制一个多边形; ✅ 鼠标 右键点击地图任意位置; ✅ 若命中 Feature,则弹出该图形的详细信息; ✅ 移除浏览器默认的右键菜单,保留地图交互的完整控制。 💡 整个功能基于 Vue3 + OpenLayers 完成,采用 Com…...

复盘20250422

深度分析及个股推荐 1. 行业前景与个股逻辑梳理 从提供的股票信息来看,主要涉及以下行业:合成尼古丁(电子烟)、化工、跨境支付、跨境电商、农药、食品饮料、光刻机、电子商务、造纸等。需结合行业景气度、政策支持、公司核心竞争…...

MQ底层原理

RabbitMQ 概述 RabbitMQ 是⼀个开源的⾼性能、可扩展、消息中间件(Message Broker),实现了 Advanced Message Queuing Protocol(AMQP)协议,可以帮助不同应⽤程序之间进⾏通信和数据交换。RabbitMQ 是由 E…...

30分钟编写十大排序算法完成

import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List;//排序算法 public class test_04_22 {public static void swap(int[] nums, int i, int j){int temp nums[i];nums[i] nums[j];nums[j] temp;}//冒泡排序-稳定…...

为什么家电主板采用GND走线而不是整面铺GND铜

不管什么接地方式,本质是为了使得电流的回流路径最短。只要电流的回流路径最短,怎么都可以! 如下图的芯片的一个信号的回流路径,是一个很糟糕的接地!!!!!!&a…...

NVIDIA 自动驾驶技术见解

前言 参与 NVIDIA自动驾驶开发者实验室 活动,以及解读了 NVIDIA 安全报告 自动驾驶 白皮书,本文是我的一些思考和见解。自动驾驶技术的目标是为了改善道理安全、减少交通堵塞,重塑更安全、高效、包容的交通生态。在这一领域,NVI…...

真我推出首款 AI 翻译耳机,支持 32 种语言翻译

2025 年 4 月 22 日,真我手机官微宣布,其首款 AI 翻译耳机 Buds Air7 Pro 将于 4 月 23 日 16 时正式上市1。这款耳机接入了讯飞星火认知大模型 4.0 Ultra,支持中文与 32 种语言面对面翻译,以及同声传译功能。 除了 AI 翻译功能&a…...

如何简化复杂流程提升执行效率

简化复杂流程、提升执行效率的关键在于:聚焦核心目标、减少冗余环节、推动系统自动化、赋能一线决策、流程分级设计。其中,聚焦核心目标 是流程优化的第一步。流程不该为了“流程而流程”,而应服务于业务目标。Gartner在《数字化运营报告》中…...

动态规划算法:完全背包类问题

前言 现在我们考虑下面的问题: (1)小明有一个背包,背包容积为v,有m种物品,其中第i种物品的价值为val[i],体积为t[i],每样物品有无限个,请问背包内物品总价值最大为多少?…...

数据存储方式补码原码反码

1. 关于数据存储(补码、原码、反码) 有符号类型(Signed Types) 存储方式:现代计算机普遍采用 补码(Two’s Complement) 存储有符号整数。 原码:最高位为符号位(0正&…...

【AAudio】A2dp sink创建音频轨道的源码流程分析

一、AAudio概述 AAudio 是 Android 8.0(API 级别 26)引入的 C/C++ 原生音频 API,专为需要低延迟、高性能音频处理的应用设计,尤其适用于实时音频应用(如音频合成器、音乐制作工具、游戏音效等)。 1.1 主要特点 低延迟:通过减少音频数据在内核与用户空间之间的拷贝,直…...

黑马点评之Feed流技术实现关注推送与滚动分页查询

Feed流 关注推送也叫做Feed流,直译为“投喂”。为用户持续的提供“沉浸式体验”,通过无限下拉刷新获取新的信息。 Feed流(信息流)是一种常见的内容分发形式,通过动态更新的内容列表向用户展示个性化或实时信息。典型应…...

vue3+canvas裁剪框样式【前端】

目录 canvas绘制裁剪框:拖拽改变框的大小:圆圈样式:方块样式: canvas绘制裁剪框: // 绘制裁剪框 const drawCropRect (ctx: CanvasRenderingContext2D): void > {if (cropRect.value.width > 0 && crop…...

Python 设计模式:模板模式

1. 什么是模板模式? 模板模式是一种行为设计模式,它定义了一个操作的算法的骨架,而将一些步骤延迟到子类中。模板模式允许子类在不改变算法结构的情况下,重新定义算法的某些特定步骤。 模板模式的核心思想是将算法的固定部分提取…...

usb2.0的硬件知识(一)

一、USB2.0的硬件知识 1.1 USB2.0速率 USB 2.0协议支持3种速率:低速(Low Speed,1.5Mbps)、全速(Full Speed, 12Mbps)、高速(High Speed, 480Mbps);USB Hub、USB设备,也分为低速、全速、高速三种类型。 1.2 USB2.0硬件线序组成 U…...

LangGraph(二)——QuickStart样例中的第二步

目录 1. 添加依赖2. 官网QuickStart——第二步:用工具增强聊天机器人2.1 Tavily Search2.2 简单测试Tavily Search2.3 添加带工具的ChatBot node2.4 添加tool node2.5 添加条件边2.6 可视化StateGraph2.7 构建聊天循环 参考 1. 添加依赖 LangGraph(一)——QuickStar…...

机器学习第二篇 多变量线性回归

数据集:世界幸福指数数据集中的变量有幸福指数排名、国家/地区、幸福指数得分、人均国内生产总值、健康预期寿命、自由权、社会支持、慷慨程度、清廉指数。我们选择GDP per Capita和Freedom,来预测幸福指数得分。 文件一:linear,…...

【MCP Node.js SDK 全栈进阶指南】中级篇(3):MCP高级资源设计

前言 在MCP TypeScript-SDK的初级篇中,我们介绍了资源开发的基础知识,包括静态资源与动态资源的创建、资源模板设计与参数提取,以及基本的资源列表与发现机制。随着应用规模的扩大和复杂性的提高,我们需要更加高级的资源设计方案来应对各种挑战。 本文作为中级篇的第三篇…...

PostgreSQL 常用日志

PostgreSQL 常用日志详解 PostgreSQL 提供了多种日志类型&#xff0c;用于监控数据库活动、排查问题和优化性能。以下是 PostgreSQL 中最常用的日志类型及其配置和使用方法。 一、主要日志类型 日志类型文件位置主要内容用途服务器日志postgresql-<日期>.log服务器运行…...

PostgreSQL认证培训推荐机构

首先来看一张2025年4月份db-engines上的数据库排行情况&#xff0c;前三名是雷打不动的Oracle、MySQL、Microsoft SQL Server&#xff0c;排名第四的就是我们今天的主角 - PostgreSQL数据库&#xff0c;从这张图上可以看出&#xff0c;PostgreSQL数据库的上升超非常明显&#x…...

2025年NISP一级题库试题

NISP一级考试只考50道单选题&#xff0c;难度不算大&#xff0c;话不多说&#xff0c;直接上硬菜&#xff01; 1、物理销毁的方式不包括&#xff08;&#xff09; .消磁 B.焚化炉烧毀 C.反复覆写数据 &#xff24;.机器硏磨粉碎 2、信息安全应该建立贯穿信息系统的整个生命周期…...

pip install pymysql报错

python安装pymysql报错解决 【现象】 很多时候会出现安装pip包报错的问题&#xff0c;看过很多网上教程以及ai都是如下说法&#xff1a; 镜像问题pip版本问题ssh证书问题网络问题… 在遇见这些情况时&#xff0c;上述的各种解决方法都一一实验过但最后都是ERROR。 【解决办…...

达梦官方管理工具 SQLark 更新--不仅支持达梦、Oracle、MySQL,还新增 PostgreSQL 数据库!

SQLark 是一款面向信创应用开发者的数据库开发和管理工具&#xff0c;用于快速查询、创建和管理不同类型的数据库系统&#xff0c;已支持达梦、Oracle、MySQL数据库&#xff1b;在最新的 V3.4 版本中&#xff0c;SQLark 新增了对 PostgreSQL 的支持&#xff0c;兼容 PostgreSQL…...

Windows 同步-互锁变量访问

互锁变量访问 应用程序必须同步对多个线程共享的变量的访问。 应用程序还必须确保对这些变量的作以原子方式执行&#xff08;完全或根本不执行&#xff09;。 对正确对齐的 32 位变量的简单读取和写入是原子作。 换句话说&#xff0c;你最终不会只更新变量的一部分;所有位都以…...

前端学习笔记

文章目录 前端主要内容基于脚手架创建前端工程vue的基本使用axios 路由Vue-Router路由组成嵌套路由 状态管理 vuex心得 前端主要内容 HTML、CSS JavaScript axios Vue基础语法&#xff08;router、vuex、typescript&#xff09; Element UI 基于脚手架创建前端工程 node.js …...

2025-04-22| Docker: --privileged参数详解

在 Docker 中&#xff0c;--privileged 是一个运行容器时的标志&#xff0c;它赋予容器特权模式&#xff0c;大幅提升容器对宿主机资源的访问权限。以下是 --privileged 的作用和相关细节&#xff1a; 作用 完全访问宿主机的设备&#xff1a; 容器可以访问宿主机的所有设备&am…...

Java八股 深入理解Spring的AOP 面向切面编程 底层 保姆级教程 手写例子

目录 概念 AOP 术语 1. 连接点&#xff08;Jointpoint&#xff09;&#xff1a; 2. 切入点&#xff08;Pointcut&#xff09;&#xff1a; 3. 通知&#xff08;Advice&#xff09;&#xff1a; 4. 方面/切面&#xff08;Aspect&#xff09;&#xff1a; 5. 引入&#xff…...

macOS安全隐私最佳实践分析

1. 引言 随着数字世界的不断扩展&#xff0c;个人和组织面临的安全与隐私威胁也日益增加。作为专业的安全合规与隐私保护研究团队&#xff0c;Kaamel 对 macOS 系统的安全隐私现状进行了全面分析&#xff0c;并提出了一系列最佳实践建议&#xff0c;旨在帮助用户更好地保护自己…...

WeakSet:JavaScript 中容易被忽视的“弱集合”

目录 WeakSet 详解 基本概念 创建 WeakSet WeakSet 的主要方法 WeakSet 的特性 WeakSet 的使用场景 1. 避免内存泄漏&#xff08;DOM 元素管理&#xff09; 2. 临时缓存系统 3. 私有属性模拟 4. 防止循环引用 与其他数据结构的对比 1. WeakSet 没有实例属性 2. We…...

Discuz!+DeepSeek:传统论坛的智能化蜕变之路

在数字化浪潮中&#xff0c;社区论坛作为互联网早期的产物&#xff0c;面临着功能单一、用户体验滞后的发展瓶颈。虎跃办公&#xff08;https://www.huyueapp.com&#xff09;通过Discuz!搭建的网址导航网站&#xff0c;在集成DeepSeek的AI能力后&#xff0c;成功实现了从工具导…...

vs2017中,将CMake构建目录设置在项目目录下

修改CMake构建目录位置 在Visual Studio 2017中&#xff0c;可以通过以下方法将CMake构建目录设置在项目目录下&#xff1a; 修改CMakeSettings.json文件‌&#xff1a; 在VS中生成CMakeSettings.json文件&#xff08;通过点击编译平台按钮如x64-Debug或x64-Release&#xf…...

跨平台.NET 版本 使用率排名

截至2025年4月&#xff0c;跨平台.NET版本的安装使用率排名主要基于版本支持状态、性能优化和企业迁移趋势。以下是结合微软官方政策、行业动态及开发者行为分析的综合结论&#xff1a; 1. .NET 8 (LTS) 占据主导地位 支持周期&#xff1a;作为2023年11月发布的长期支持&…...

基于无障碍跳过广告-基于节点跳过广告

2025-04-22 一些广告的关闭是叉图标&#xff0c;获取到的信息也没什么特征&#xff0c;这种广告怎么跳过 用autojs无障碍的节点定位ui控件位置&#xff0c;点击...

STM32提高篇: WIFI通讯

STM32提高篇: WIFI通讯 一.WIFI通讯介绍1.WiFi的频段5G和2.4G2.WiFi的信道二.ESP32固件烧录及驱动1.一个AT指令响应的完成2.测试其他指令三.Wifi功能初始化和TCP通讯四.volatile关键字一.WIFI通讯介绍 Wi-Fi,又称“无线网路”,是Wi-Fi联盟的商标,一个基于IEEE 802.11标准的…...

资本怪兽贝莱德投资数据分析报告-独家

贝莱德概述 贝莱德集团是全球最大的资产管理公司&#xff0c;其管理的资产规模达到了11.6万亿美元(约合人民币84.18万亿元)&#xff0c;这个数字相当于中国2024年GDP的62%。贝莱德通过收购李嘉诚旗下的43个全球港口资产&#xff0c;将在全球运营约100个港口。此外&#xff0c;…...

操作系统-用户级-内核级线程

一、先明确几个基本概念&#xff1a; 用户级线程&#xff08;ULT&#xff09;&#xff1a; 完全由用户空间的线程库&#xff08;如 pthread 或 green threads&#xff09;管理。 操作系统内核对此一无所知。 切换线程时&#xff0c;不需要进入内核&#xff0c;效率高&#xf…...

【深度学习】LoRA:低秩适应性微调技术详解

LoRA&#xff1a;低秩适应性微调技术详解 文章目录 LoRA&#xff1a;低秩适应性微调技术详解1. 引言2. LoRA原理解析2.1 核心思想2.2 数学表达 3. LoRA实现细节3.1 适用层选择3.2 缩放因子3.3 初始化策略 4. 代码实现示例5. LoRA在实际应用中的优势5.1 内存效率5.2 训练速度5.3…...

研发效率破局之道阅读总结(3)工程优化

研发效率破局之道阅读总结(3)工程优化 Author: Once Day Date: 2025年4月22日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: 程序的艺术_Once-Day…...

树莓派超全系列教程文档--(40)树莓派config.txt旧版GPIO控制、超频及条件过滤器

树莓派config.txt旧版GPIO控制、超频及条件过滤器 传统GPIO控制enable_jtag_gpio 传统超频选项超频never_over_voltagedisable_auto_turbo 遗留条件过滤器The [HDMI:*] 过滤器 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 传统GPIO控制 &…...

网络基础概念(下)

网络基础概念&#xff08;上&#xff09;https://blog.csdn.net/Small_entreprene/article/details/147261091?sharetypeblogdetail&sharerId147261091&sharereferPC&sharesourceSmall_entreprene&sharefrommp_from_link 网络传输的基本流程 局域网网络传输流…...

DES、3DES、SM4 加密算法简介

1. DES&#xff08;Data Encryption Standard&#xff09; 设计时间&#xff1a;1975 年&#xff08;IBM 开发&#xff0c;1977 年被 NIST 采纳为美国联邦标准&#xff09;。 密钥长度&#xff1a;64 位&#xff08;实际有效 56 位 8 位校验&#xff09;。 分组长度&#xf…...

如何在 Ansys Icepak AEDT 中设置多个流程以加快仿真速度?

您将学习如何进行正确的设置&#xff0c;以通过增加进程数量来加快仿真速度。 Ansys Icepak AEDT 需要与 Icepak Classic 不同的设置。 要设置要在 Ansys Icepak AEDT 中使用的进程数&#xff0c;您需要按照以下步骤作&#xff1a; 首先&#xff0c;转到“工具 - >选项 - …...

【MCP Node.js SDK 全栈进阶指南】初级篇(2):MCP基础服务器开发

引言 在上一篇文章中,我们详细介绍了MCP开发环境的搭建。本文作为MCP TypeScript-SDK系列的第二篇,将深入探讨MCP基础服务器开发的核心内容,包括服务器创建与生命周期管理、McpServer与Server的区别与选择、各种配置选项的详解,以及基本启动与调试技巧。通过本文学习,你将…...

客户端 AI 与服务器端 AI 的深度比较及实践建议?

1. 性能与延迟 ​​客户端AI&#xff08;In-Browser AI&#xff09;​​&#xff1a; // 使用TensorFlow.js在浏览器中进行图像分类 const model await tf.loadLayersModel(local-model/model.json);// 实时摄像头处理 const video document.getElementById(webcam); const…...

【(保姆级教程)Ubuntu24.10下部署Dify】

目录 一、下载Ubuntu二、安装Ubuntu三、在 Ubuntu 上安装 Docker Engine1、设置Docker的apt仓库2、安装 Docker 包 四、在 Ubuntu 上安装 Docker Desktop1、先决条件2、下载最新 DEB 包3、安装软件包4、启动 Docker Desktop5、检查版本 五、克隆 Dify 代码仓库六、启动 Dify1、…...

计算机组成原理---总线系统的详细概述

1.数据传输的两个方式 串行传输和并行传输&#xff1a;串行传输和并行传输 串行&#xff1a;适合的就是传输的距离比较远&#xff0c;这个对应的成本也是比较低的&#xff1b; 并行&#xff1a;传输的效率很高&#xff0c;因为分成了不同的线路&#xff0c;这个适合的就是短距离…...