Skip to content
This repository was archived by the owner on Mar 17, 2026. It is now read-only.

organwalk/training-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

127 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

training-server

training-server 是一个面向企业培训场景的微服务后端项目,覆盖账号权限、部门组织、培训计划、课程资源、学习互动、学习进度和站内通知等核心能力。

项目当前采用 Spring Boot 3 + Spring Cloud Alibaba 的多模块结构,围绕“创建计划 -> 组织课程 -> 上传资源 -> 学员学习 -> 记录进度 -> 推送通知”这条主链路展开实现。

项目模块

模块 说明
training-gateway 网关入口,负责统一路由和基于请求头的鉴权校验
training-user-service 用户账号、登录认证、权限信息维护
training-department-service 部门管理、负责人维护、成员归属关系维护
training-resource 普通资料、课程资源、Markdown 笔记的上传、查询、删除和文件输出
training-plan-service 培训计划、课程、章节、测试题以及计划状态流转
training-learn-service 学习答题、评论、回复、点赞等互动行为
training-progress-service 章节完成记录、课程进度统计、计划维度进度聚合
training-push-service 站内通知持久化、消息消费、WebSocket 实时推送
common 通用响应模型、HTTP 客户端、JSON 编解码、链路透传、幂等组件

技术栈

  • Java 17
  • Spring Boot 3
  • Spring Cloud Gateway
  • Spring Cloud Alibaba Nacos
  • MyBatis-Plus
  • MySQL
  • Redis
  • RabbitMQ
  • WebSocket
  • Springdoc OpenAPI

目录结构

training-server
├─ common
├─ config
│  └─ nacos
├─ scripts
├─ training-gateway
├─ training-user-service
├─ training-department-service
├─ training-resource
├─ training-plan-service
├─ training-learn-service
├─ training-progress-service
└─ training-push-service

运行环境

本地启动建议准备以下依赖:

  • JDK 17
  • MySQL
  • Redis
  • RabbitMQ
  • Nacos
  • Python 3
  • PowerShell 7 或 Windows PowerShell
  • mp4box

说明:

  • mp4box 仅在上传 .mp4 课程资源并执行视频处理时需要。
  • 项目使用 Maven Wrapper,无需单独安装 Maven。

配置说明

项目已将模块配置收敛到 Nacos。各服务自身只保留最小 application.properties,通过 spring.config.import 从配置中心拉取共享配置和模块配置。

Nacos Data ID 约定如下:

  • training-common.yaml
  • ${spring.application.name}.yaml

仓库内已提供配置模板:

  • config/nacos/training-common.yaml
  • config/nacos/training-gateway.yaml
  • config/nacos/training-user-service.yaml
  • config/nacos/training-department-service.yaml
  • config/nacos/training-resource.yaml
  • config/nacos/training-plan-service.yaml
  • config/nacos/training-learn-service.yaml
  • config/nacos/training-progress-service.yaml
  • config/nacos/training-push-service.yaml

常用环境变量:

  • NACOS_SERVER_ADDR
  • NACOS_GROUP
  • NACOS_NAMESPACE
  • NACOS_USERNAME
  • NACOS_PASSWORD
  • RABBITMQ_HOST
  • RABBITMQ_PORT
  • RABBITMQ_USERNAME
  • RABBITMQ_PASSWORD
  • REDIS_HOST
  • REDIS_PORT
  • REDIS_DATABASE

快速开始

1. 导入 Nacos 配置

config/nacos 下的模板导入 Nacos,默认使用 DEFAULT_GROUP

2. 启动基础设施

先启动:

  • Nacos
  • MySQL
  • Redis
  • RabbitMQ

3. 编译项目

Linux / macOS:

./mvnw -DskipTests compile

Windows:

.\mvnw.cmd -DskipTests compile

4. 启动服务

可以按下面顺序逐个启动:

  1. training-user-service
  2. training-department-service
  3. training-resource
  4. training-plan-service
  5. training-progress-service
  6. training-learn-service
  7. training-push-service
  8. training-gateway

示例:

./mvnw -pl training-user-service -am spring-boot:run
./mvnw -pl training-department-service -am spring-boot:run
./mvnw -pl training-resource -am spring-boot:run
./mvnw -pl training-plan-service -am spring-boot:run
./mvnw -pl training-progress-service -am spring-boot:run
./mvnw -pl training-learn-service -am spring-boot:run
./mvnw -pl training-push-service -am spring-boot:run
./mvnw -pl training-gateway -am spring-boot:run

开发校验

编译校验:

./mvnw -DskipTests compile

依赖守卫与编码检查:

powershell -ExecutionPolicy Bypass -File .\scripts\check-no-fastjson.ps1 -VerboseOutput
python .\scripts\check-source-encoding.py

CI 说明

仓库包含 GitHub Actions 工作流 openapi-contract-check,用于做两类检查:

  • 源码守卫:检查 JSON 依赖禁用规则和源码 UTF-8 编码完整性
  • OpenAPI 合同检查:启动各微服务并校验 /v3/api-docs

CI 使用仓库根目录的 application-openapi-ci.properties 作为统一测试配置。在该场景下会关闭 Nacos 配置拉取、关闭消息监听、关闭网关服务发现,并切换到 H2 内存库,以保证每个服务都能独立启动并输出接口文档。

核心功能模块与设计实现

1. 文件上传

资源服务将普通资料和课程资源都设计成“按块上传 + 按哈希去重”的模式:

  • 上传请求携带 fileHash、总分片数、当前分片序号、文件大小等信息
  • 服务端通过 RandomAccessFile 按偏移量写入临时分片文件
  • 最后一个分片到达后,将临时文件原子移动到正式目录
  • 如果数据库里已经存在相同 fileHash 的物理文件,则直接复用原路径,不重复落盘
  • 上传阶段用 Redis 幂等锁限制同一个文件并发合并,避免重复写入和脏数据

普通资料和课程资源采用不同的目录组织方式:

  • 普通资料:按日期和上传者分目录保存
  • 课程资源:按教师、课程、章节三级目录保存

2. 视频资源处理

课程资源在合并完成后,如果文件扩展名为 .mp4,会继续调用 mp4box 做一次处理:

  • 使用 MP4BoxUtil 启动外部进程
  • 将原始 MP4 转成更适合分段加载的 fMP4 结果
  • 处理成功后替换原文件,处理失败则记录日志并回滚临时产物

资源读取时会根据文件类型输出不同内容:

  • Markdown 资源直接按文本返回
  • 视频资源通过 Range 请求按字节范围输出,支持前端边播边加载

3. Markdown 笔记

笔记资源与普通资料分开建模,单独限制为 .md 文件:

  • 上传前先校验课程和章节是否存在
  • 文件按 lessonId/chapterId/upId-uuid.md 方式落盘
  • 删除章节或课程时,会同步清理对应目录和笔记记录

这样可以把课程正文资料和学员、教师补充说明分开管理,避免资源目录混杂。

4. 消息队列使用方式

项目中的 RabbitMQ 主要有两种用法。

第一种是异步事件投递:

  • 学习服务提交试卷后投递判卷消息
  • 学习服务的点赞、回复、考试发布等行为会投递通知消息
  • 进度服务会消费章节完成消息并更新课程完成数
  • 推送服务会消费通知消息,再转成站内通知和 WebSocket 推送

第二种是请求-回调协作:

  • 学习服务在创建评论前,会向用户服务和计划服务发送校验消息
  • 用户服务校验用户是否存在,计划服务校验课程章节是否存在
  • 两边都将结果写回同一个回调队列
  • 学习服务按 requestId 聚合回调结果,只有都成功才继续写评论

这类设计把跨服务前置校验从同步 HTTP 依赖改成了消息协作,同时保留了结果可追踪能力。

5. 幂等与重复消费控制

所有核心消费者都复用了 IdempotencyGuard

  • 消费前按 consumerName + msgId 生成 Redis 幂等键
  • 重复消息直接丢弃
  • 处理异常时释放幂等键,允许后续重试

这个模式已经应用在评论校验、章节完成、点赞通知、回复通知、试卷处理等多个链路中。

6. 培训计划与进度联动

培训计划模块负责计划、课程、章节和测试题的主数据维护,进度模块负责学习结果落地:

  • 计划服务维护计划状态,并在启动时和每日定时任务中更新过期计划状态
  • 学习行为完成后,通过消息把章节完成事件发送给进度服务
  • 进度服务在章节完成表落库成功后,再更新课程已完成章节数

这样把“计划定义”和“学习结果统计”拆到了两个模块里,职责更清晰,后续扩展统计口径也更容易。

7. 通知持久化与实时推送

推送模块不是单纯的 WebSocket 转发,而是先落库再推送:

  • NotificationServiceImpl 先写通知主表和接收表
  • 同事务内补写一条 outbox 事件记录,保留后续补偿和扩展空间
  • 在线用户通过 /push/{uid}/{username} 建立 WebSocket 连接
  • 消费到通知消息后,服务会把消息写入数据库并向在线会话推送文本内容

这种做法保证了通知既能实时触达,也能在用户离线时保留站内信记录。

8. 服务间调用

项目内部的同步调用通过 common 模块统一封装:

  • 使用 WebClientProxyFactory 生成声明式 HTTP 客户端
  • 自动透传 traceIdrequestId
  • 对慢调用做统一日志记录

这样每个服务只需要定义自己的 Client 接口,不需要重复写大量样板 WebClient 代码。

About

企业培训场景的微服务后端系统,覆盖权限、部门、培训计划、资源管理、学习互动、进度统计和通知推送。

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages