1. 项目介绍

项目地址http://vinehub.cn(使用电脑端Edge、火狐浏览器打开最佳)

项目描述葡萄藤社区(VineHub) 是一个融合了 在线判题系统(Online Judge)博客功能(Blog)微服务项目。用户可以参与管理员创建的 竞赛,挑战自我以提升排名;通过评测 ACM算法题目 来增强算法能力;还可以发布 原创文章,丰富社区内容。VineHub 支持多种判题类型,包括 普通评测测试评测交互评测,并兼容 C++JavaPython 等多种编程语言。此外,用户还可以高度自定义 答题界面,查看 秒级更新 的榜单缓存,以及 高亮弹窗即时反馈 答题结果等特色功能。

项目负责:项目前端、用户微服务(UserStore)、基本微服务(Universal)、题目微服务(QuestionEvaluate)、媒介微服务(Media)、BFF中心化应用(ESB)的实现

2. 使用事宜

  1. 请使用邮箱进行注册和登录,暂不开放密码登录功能。
  2. 部分数据需要登录后才能加载。如果发现某些数据未显示,请先登录。
  3. 初次注册后,系统会自动跳转到中台修改信息界面,请完善您的个人信息。
  4. 部分功能位于导航栏按钮处
  5. 可以尝试拖动题目详情对应界面的卡片标题,提升操作体验。

3. 业务介绍

3.1 BFF应用

  1. 统一请求处理:接收前端请求并转发至相应的微服务进行处理。
  2. WebSocket接口:提供WebSocket接口服务。
  3. 文件上传接口:提供文件上传功能。

3.2 用户微服务

  1. 用户管理
    • 提供用户相关的CRUD操作。
    • 支持用户登录和注册功能。
  2. 后台管理
    • 提供角色、权限、菜单的CRUD操作。

3.3 基本微服务

  1. 标签管理:提供标签(Tag)相关的CRUD操作。
  2. 评论管理:提供评论相关的CRUD操作。
  3. Live2D配置
    • 生成Live2D配置。
    • 获取Live2D列表。

3.4 题目微服务

  1. 题目与竞赛管理
    • 提供题目和竞赛的CRUD操作。
    • 管理判题记录的增删。
  2. 竞赛榜单
    • 保存竞赛结束后的榜单。
    • 通过RabbitMQ实时消费判题数据,更新Redis中的用户-竞赛缓存。
    • 竞赛进行时,每秒计算并排序竞赛榜单,实时反馈至前端。
  3. 榜单接口:提供获取榜单的接口。

3.5 媒介微服务

  1. 博文管理:提供博文的CRUD操作及获取博文详情等功能。

4. 项目架构

4.1 后端架构

4.1.1 数据库

数据库类型 用途
PostgreSQL 业务数据库
MySQL 环境数据库
Redis NoSQL 数据库

4.1.2 中间件

框架名称 描述
SpringBoot Java 后端框架
MybatisPlus 数据访问持久层框架
Dubbo RPC 服务框架
Nacos 分布式注册中心
RabbitMQ 消息队列
Apollo 分布式配置中心
xxl-job 分布式定时任务
Sentinel 限流框架
Seata 分布式事务

4.1.3 使用开源项目

项目名称 描述 链接
GoJudge 代码沙箱 criyle/go-judge

4.1.4 后端工具包

工具名称 描述
AOP 切面编程
WebSocket 全双工通信
Unirest HTTP 客户端库
JavaxMail 邮件收发
fastjson Json 解析库
lombok 简化Java代码
commons-lang3 工具类库
hutool 工具类库
jjwt Jwt
junit 单元测试
easyexcel 暂未使用

4.1.5 外部 API

API名称 描述
小牛翻译 翻译 API

4.2 前端架构

相关框架

框架/库名称 描述
Vite 构建工具
Vue 开发框架
TypeScript TS
Axios HTTP 请求库
WebSocket 全双工通信
FlyonUi 样式库
Vditor Markdown
MonacoEditor 代码编辑器

4.3 部署相关

服务名称 描述
阿里云 ECS 云服务器
七牛云 Kodo 对象存储服务

5. 项目亮点

后端技术描述

  1. 分布式系统:以 Nacos 作为注册中心,使用 Dubbo RPC 构建分布式系统,通过 Kyro序列化 减少微服务之间的传输消耗。
  2. 配置管理:使用 Apollo 分布式配置中心统一管理配置。
  3. 权限管理:用户微服务采用 RBAC 权限模型,实现 接口级权限管理
  4. 统一鉴权:使用 Spring MVC 拦截器 在请求 BFF 应用 之前进行统一鉴权,并将鉴权请求转发到用户微服务。鉴权完成后,通过 RpcContext 隐式传递用户 ID 参数至下游服务。拦截器设计允许登录用户访问无需鉴权的接口时,仍可向下游服务传递用户 ID 参数(未登录时用户 ID 为 -1)。
  5. 接口限时:通过 AOP 自定义注解,限制接口在 x 秒内只能被用户调用 y 次。
  6. 外部接口调用:封装 GoJudge 的实体类和请求逻辑,使用 构造器模式 封装为 SDK,便于调用外部接口。通过 Spring 配置化读取 YML 配置,实现轮询策略等灵活调用 GoJudge 服务。
  7. 判题策略:鉴于判题逻辑复杂(如普通判题和交互判题有不同的策略),采用 策略模式 代替 if...else,独立封装不同语言的判题算法,提高系统可维护性。同时,为未来可能采用的不同判题沙箱,使用 静态工厂模式 实现灵活配置。
  8. 多线程判题:从七牛云读取题目样例后,使用 线程池 + CompletableFuture 实现判题等多个接口的性能优化。判题时先保存题目,再通过 RabbitMQ 转发消费题目,实现判题与保存判题记录、算榜计算之间的解耦合,调用时间降低了 92%
  9. 榜单计算:将传统的扫表式静态算榜改为通过 RabbitMQ 消费 的动态算榜,并使用 Redis 中的 sorted set 保存竞赛中用户的所有题目得分状态,同时实现接口缓存。
  10. 实时通信:通过 WebSocket 实现前后端全双工通信,使后端能够主动向前端发送消息。

前端技术描述

  1. UI 与主题:使用 FlyonUI 样式库作为项目主题风格,并通过 TypeScript 实现切换主题的动画效果。
  2. 消息通知:将后端通过 WebSocket 发送的数据通过 FlyonUI 的 notyf弹窗统一显示,支持渲染 HTML 字符串。
  3. WebSocket 动态连接:实现 WebSocket 动态连接(用户登录时连接,掉线时重连),登录过期时根据返回的 op 值清空 Pinia 中的用户信息并自动过期登出。
  4. Markdown 渲染:根据 Vditor 官方文档配置代码高亮和 KaTeX 公式;自定义了部分渲染器(如代码块),渲染为联调代码块(多个代码块在一起自动聚合)。
  5. 中控台弹窗:支持调整参数及查看答题记录。
  6. 高自由度答题界面:使用拖动API 以及 n 叉树数据结构作为缓存,实现高自由度答题界面(支持调整卡片宽高、拖动卡片),并通过 Pinia 持久化答题页面。
  7. Live2d 组件:实现通用 Live2d 组件,请求后端获取模型文件并渲染,支持自适应缩放、自由调整位置、大小和画质。
  8. 跨页面通信:基于 SharedWorker 实现跨页面通信,通过共享线程与后端 WebSocket 通信,确保多个页面接收后端数据。
  9. 拖动选题:竞赛添加题目可以自由的拖动要选择的题目。
  10. 路由复用:通过自定义 RouterKey 算法,在子路由变化时复用父路由组件。

6. 重要技术展示

6.1 项目架构图

未命名文件.png