Skip to content
/ stml Public

新项目,基于 Next.js + Spring Boot + Redis + MySQL + Elasticsearch 的面试刷题平台,运用 Druid + HotKey + Sa-Token + Sentinel 提高了系统的性能和安全性。管理员可以创建题库、题目和题解;用户可以注册登录、分词检索题目、在线刷题并查看刷题记录日历图。 此外,系统使用数据库连接池、热 Key 探测、缓存、高级数据结构等来提升性能。通过流量控制、熔断、动态 IP 黑白名单过滤、同端登录冲突检测、分级反爬虫策略来提升系统和内容的安全性。

Notifications You must be signed in to change notification settings

banalord/stml

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

刷题吗喽!

深入业务场景的企业级实战项目,基于 Next.js 服务端渲染 + Spring Boot + Redis + MySQL + Elasticsearch 的 面试刷题平台。

管理员可以创建题库、题目和题解,并批量关联题目到题库;用户可以注册登录、分词检索题目、在线刷题并查看刷题记录日历等。

项目涉及大量企业级新技术的讲解,比如使用数据库连接池、热 Key 探测、缓存、高级数据结构来提升性能。通过流量控制、熔断、动态 IP 黑白名单过滤、同端登录冲突检测、分级反爬虫策略来提升系统和内容的安全性。

项目展示

http://banalord.icu

项目三大开发阶段

1)第一阶段,开发刷题平台的基础,熟悉项目开发流程,实战 Spring Boot 应用的快速开发。

2)第二阶段,对项目功能进行扩展,实战企业主流后端技术如 Redis 缓存和高级数据结构、Elasticsearch 搜索引擎、Druid 连接池、并发编程、热 key 探测的应用。

3)第三阶段,对项目安全性进行优化,比如基于 Sentinel 进行网站流量控制和熔断、基于 Nacos 实现动态的 IP 黑白名单、基于 Sa-Token 实现同端登录冲突检测、基于 Redis 实现分级反爬虫策略等。最终将项目上线。

核心业务流程

项目架构

项目亮点

  1. 刷题记录:基于 Redis BitMap + Redisson 实现用户年度刷题记录的统计,相比数据库存储节约几百倍空间。并通过本地缓存 + 返回值优化 + 位运算进一步提升接口性能。
  2. 分词搜索:自主搭建 ES 代替 MySQL 模糊查询,并为索引绑定 ik 分词器实现了更灵活的分词搜索。
  3. 使用 Spring Scheduler 定时同步近期发生更新的 MySQL 题目到 ES ,并通过唯一id保证每条数据同步的准确性。
  4. 基于 MyBatis 的batch操作实现题目批量管理,并通过任务拆分 + CompletableFuture 并发编程提升批处理性能。
  5. 使用 Caffeine 本地缓存提升题库查询性能,并通过接入 HotKey 并配置热 Key 探测规则来自动缓存热门题目,防止瞬时流量击垮数据库。
  6. 为限制恶意用户访问,基于 WebFilter + BloomFilter 实现 IP 黑名单拦截,并通过 Nacos 配置中心动态更新黑名单,便于维护。
  7. 为保护系统,基于 Sentinel 的热点参数限流机制对单 IP 获取题目进行流控,并通过拉模式配置将规则持久化到本地文件。
  8. 为防止账号共享,通过 UserAgent 识别用户设备,并基于 Sa-Token 快速实现同端登录冲突检测。
  9. 设计分级反爬虫策略:基于Redis实现用户访问题目频率统计,并通过Lua脚本保证原子更新,超限时自动给管理员发送告警和封禁用户,有效防止内容盗取

数据库按如下设计:

CREATE TABLE user_sign_in (
id BIGINT AUTO_INCREMENT PRIMARY KEY,  -- 主键,自动递增(8字节)
userId BIGINT NOT NULL,                -- 用户ID,关联用户表(8字节)
signDate DATE NOT NULL,                -- 签到日期(3字节)
createdTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  -- 记录创建时间(4字节)
UNIQUE KEY uq_user_date (userId, signDate)  -- 用户ID和签到日期的唯一性约束(还需要额外空间)
);

大小计算:

  • 主键索引内:各字段(8+8+3+4) = 23 字节
  • 行头信息+NULL位图(10+ceil(4/8)) = 11 字节
  • 隐藏列:事务id6字节+回滚指针7字节 = 13 字节
  • 以上总共47B加上一些页的信息,这里就按55算
  • 唯一索引内:两个字段 8 + 3 ,加上主键 8 ,行头 + 页目录按 6 大约25字节
  • 总大小 55 + 25 = 80B
  • 80 * 100,0000 * 365 / 1024 / 1024 / 1024 = 27.19GB

而用 Redis Bitmap 一个用户存储一年的数据 ( value 部分 ) 仅需 46 字节,因为 46 * 8 = 368 ,能覆盖一年365天的记录。我们的键设计是:user:singin:{year}:{userid} 。以user:signin:2025:1927112888406622209举例。在redis控制台输入

MEMORY USAGE user:signin:2025:1927112888406622209

返回 136

那一百万用户 100,0000 * 136 / 1024 /1024 = 129.70 MB

相比数据库相差 27.19 * 1024 / 129.7 = 214.67 倍

  • 本地缓存是使用 JDK 自带的 bitset 一次性从 redis 拿到整个 bitmap 从而避免365次对 redis 的网络请求

  • 原先使用Map<LocalDate, Boolean> 后使用 List<Integer> 缩短返回数据大小(返回的是一年当中第几天签到)

  • 原先使用 for 循环遍历整个 bitmap 数据,后改进使用 NextSetBit 直接寻找下一个为 1 的位(注意:BitSet 类中的toString方法也使用了这个办法)

About

新项目,基于 Next.js + Spring Boot + Redis + MySQL + Elasticsearch 的面试刷题平台,运用 Druid + HotKey + Sa-Token + Sentinel 提高了系统的性能和安全性。管理员可以创建题库、题目和题解;用户可以注册登录、分词检索题目、在线刷题并查看刷题记录日历图。 此外,系统使用数据库连接池、热 Key 探测、缓存、高级数据结构等来提升性能。通过流量控制、熔断、动态 IP 黑白名单过滤、同端登录冲突检测、分级反爬虫策略来提升系统和内容的安全性。

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published