基于SpringBoot + MyBatis + Caffeine + Redis + MySql + Kafka实现一个论坛网站 附完整代码

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 Tair(兼容Redis),内存型 2GB
简介: 基于SpringBoot + MyBatis + Caffeine + Redis + MySql + Kafka实现一个论坛网站 附完整代码

功能梳理

普通用户权限:


  • 支持站内账号登录,QQ 登录和 GitHub 账号登录(一键登录,方便快捷)
  • 支持发布帖子,可以添加自定义标签,支持 Markdown 格式,同时编辑页面提供目录索引
  • 支持用户编辑自己发布帖子
  • 支持点赞帖子,评论帖子,对评论进行评论,对评论进行点赞,当用户的帖子或者评论被点赞或评论时,会通过站内信通知用户
  • 查看帖子详情页面时,可以同时看到论坛的热门帖,以及相关的帖子(通过标签匹配获得)
  • 支持查看个人主页,查看该用户发布的所有帖子,以及最新的动态
  • 支持站内发送私信
  • 支持站内搜索,提供多种搜索条件
  • "user:Gepeng18" 搜索 Gepeng18 发布的帖子
  • "关键词 in:title" 搜索题目中有"关键词"的帖子
  • "关键词 in:content" 搜索帖子内容中有"关键词"的帖子
  • "关键词 in:tag" 搜索标签中有"关键词"的帖子
  • 支持以上条件组合使用



管理员权限:
  • 可以删除或者编辑用户的帖子
版主权限:
  • 可以将帖子加精或者置顶

云盘模块

普通用户权限:
  • 下载所有的文件
  • 在线播放低于 N 兆的音乐,视频
  • 在线查看代码文件
  • 在线浏览图片
  • 支持获取下载链接,提供给他人下载
  • 在线阅读电子书
  • 在线阅读工程
管理员专有权限:
  • 上传文件
  • 删除文件或文件夹
  • 可以查看"私人文件夹",该文件夹在普通用户模块不显示
  • 创建文件夹
  • 分享文件或者文件夹
  • 转存其他管理员分享的文件或文件夹


模块梳理

注册、登录模块

注册


  1. 检查是否允许注册。当用户点击页面顶部“登录”按钮,打开注册页面,允许注册时,输入账户、密码和邮箱,通过表单提交注册数据。
  2. 服务端对用户输入的信息进行检测。填入的信息不能为空,验证输入的账户是否已经存在,填写的邮箱是否已经注册过。
  3. 注册用户。用户传入的密码通过 MD5+salt 的方式加密,设置用户的类型为普通用户,用户的状态为未激活状态,设置用户的激活码,给用户随机分配系统自带的头像, 生成用户注册的时间
  4. 激活注册账号。服务端利用模板引擎发送激活邮件至用户注册时填写的邮箱中。 用户点击邮件中的激活码,访问服务端的激活服务。通过验证激活码来验证激活是否成功。
  5. 利用 kaptcha 生成验证码,将验证码放入 cookie 中,并存到 Redis 里。


登录


  1. 登录方式分为论坛注册账户登录和第三方账号登录(GitHub 和 QQ)。
  2. 论坛内注册的账户登录:提交账户信息后,服务端会先验证用户填入的信息,其中验证码在表现层就要判断,验证码不对密码和账号就不要判断了; 登录信息无误后,生成登录凭证(loginTicket),将登录凭证放入 cookie 中,并存到 Redis 里。浏览器每次访问时从 Redis 中取出 cookie,并判断登录状态。此处 Redis 存储 cookie 实现了分布式的部署。
  3. 第三方登录:选择第三方登录后,会去相应的第三方服务器中获取用户信息并返回给服务端。服务端会通过返回的用户信息中的 openId 来判断该用户是否已经注册。 若注册过即取出并登录,否则注册并登录。同时生成登录凭证,放入 cookie 里,存到 Redis 中,用户下次访问时判断是否登录。


缓存

个性化推荐模块


  1. 整体上本模块采用"推"和"拉"的方式并存。
  2. 当用户点赞,评论,发布博客时,会将这些"动态"封装成 feed 对象存入数据库,同时将这个动态发给所有的粉丝(从数据库中找到所有的粉丝,筛选最近 n 天登陆过的人,然后将此 feed 存入他们对应的 Redis 的 timelineKey 中,即 每个用户的 Redis 的 timelineKey 中存放着自己关注的对象的动态)
  3. 当用户登录后,Redis 中有值则从 Redis 中对应的 key 中取,否则先从 Redis 中获取所有的关注的人,然后从数据库中遍历搜索。 至此,获得了用户关注的人的最近动态
  4. 当用户每查看一个帖子时,就会将这个帖子的标签存到 Redis 对应的 tagKey 中。
  5. 最终,用户的个性化页面展示顺序即为:

           用户关注的人发送的帖子

          用户关注的人点赞的帖子

          用户关注的人评论的帖子

          用户最近查看的标签对应的帖子且发布时间是近期(否则用户看了两个"多线程"的帖子,然后向此用户推荐了网站所有的多线程,显然不合适,所以只推荐最近发布的"多线程"的帖子)

          再按照分数递减的顺序 注意点

  1. 我们为 timelineKey 设置了生存时间,如小葛关注了小芳,则小芳发布的帖子,进入了小葛的 timelineKey,此时,如果小葛 5 天没登录了,则从此小芳的点赞评论都不会在告诉小葛, 此时我们就可以把小葛的 timelineKey 删除了,当小葛再次登录时,小芳发布的帖子,评论点赞才会进入小葛的 timelineKey,以此解决 Redis 内存。
  2. 如果我们最近查看了"多线程",那么分页查询第一页一定是 0-10,这时候我们看的帖子的标签就会被 Redis 记录,此时如果我们点击第二页,则从 Redis 中的 tagKey 取值时,第二页的查询条件就会改变, 这时候可能第一页查看过的数据,第二页又会出现,或者是有些数据,永远看不到,即我们需要保证分页查询时,每次查询条件不变,所以我们设置了两个 key,持久化 key(persistence)和最近的 key(latest), 这时候我们每次查询都从持久化 key 中取,而每次查询第一页时,将最新的 key 置换为持久化 key,这样即可以保证每次查询条件相同,且是伪最新的标签。


主页热门标签显示模块


  • 用户发布帖子时,都会附带一个 tag 标签
  • 使用 quartz,每隔 3 个小时统计一次。遍历所有帖子,统计所有出现的标签。
  • 根据每个标签匹配所有帖子,统计帖子个总数,计算帖子总分,组成一个 tag。这里需要注意,我们在查询某标签(如算法)对应的帖子时, 查询数据库的算法使用了“%XX%”(如 % 算法 %)的匹配条件,这会得到其他相关联的标签(如“算法总结”等)。
  • 使用 treeSet 对这些标签按照总分排序,然后选出 N 个帖子存储在 tagCache 中,每当用户访问主页面时,就从 TagCache 中去取
  • 当帖子数量增多时,统计时间也可以设置为每天晚上 3 点,夜深人静偷偷统计。(统计帖子的个数,有点误差可以接受,所以一天统计一次似乎也可行)


环境搭建

  • 环境搭建,见 docker.md,本项目所有服务都在 docker 环境下搭建。
  • 数据库初始化:所有的 SQL script 见 SQL_Script
  • 运行顺序为 init_schema.sql(建表) -> init_quartz.sql(quartz 相关表)

更新日志


项目截图

首页

c275c4521f0d897591f4759f4637f0df.png


个性化推荐


c4c879e220a2ece2ccbb22cd8cb10125.png


帖子详情页

支持目录查看即目录跳转


image.png

站内搜索

0bf04ef9317a7b06aea50249558af862.png


标签检索


image.png



个人主页


最新动态

22357b94ef8f38c24ae76b4be6bffe14.png

站内私信功能

完整代码:https://download.csdn.net/download/weixin_55771290/87406820




相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
17天前
|
NoSQL 关系型数据库 MySQL
2024Mysql And Redis基础与进阶操作系列(4-2)作者——LJS[含MySQL非空、唯一性、PRIMARY KEY、自增列/自增约束举例说明等详解步骤及常见报错问题对应的解决方法]
24MySQL非空、唯一性、PRIMARY KEY、自增列/自增约束举例说明等详解步骤及常见报错问题对应的解决方法(4-2) 学不会你来砍我!!!
|
7天前
|
缓存 NoSQL 关系型数据库
Redis和Mysql如何保证数据⼀致?
在项目中,为了解决Redis与Mysql的数据一致性问题,我们采用了多种策略:对于低一致性要求的数据,不做特别处理;时效性数据通过设置缓存过期时间来减少不一致风险;高一致性但时效性要求不高的数据,利用MQ异步同步确保最终一致性;而对一致性和时效性都有高要求的数据,则采用分布式事务(如Seata TCC模式)来保障。
39 14
|
9天前
|
分布式计算 关系型数据库 MySQL
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型 图像处理 光通信 分布式计算 算法语言 信息技术 计算机应用
30 8
|
10天前
|
SQL 前端开发 关系型数据库
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
41 9
|
17天前
|
NoSQL 安全 关系型数据库
2024Mysql And Redis基础与进阶操作系列(6)作者——LJS[含MySQL 多表之一对一/多;多对多;多表联合查询等详解步骤及常见报错问题所对应的解决方法]
MySQL 多表之一对一/多;多对多;多表联合之交叉连接;内连接;左、右、外、满、连接;子查询及关键字;自连接查询等详解步骤及常见报错问题所对应的解决方法
|
17天前
|
SQL NoSQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(5)作者——LJS[含MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页等详解步骤及常见报错问题所对应的解决方法]
MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页、INSERT INTO SELECT / FROM查询结合精例等详解步骤及常见报错问题所对应的解决方法
|
21天前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:百万级数据统计优化实践
【10月更文挑战第21天】 在处理大规模数据集时,传统的单体数据库解决方案往往力不从心。MySQL和Redis的组合提供了一种高效的解决方案,通过将数据库操作与高速缓存相结合,可以显著提升数据处理的性能。本文将分享一次实际的优化案例,探讨如何利用MySQL和Redis共同实现百万级数据统计的优化。
54 9
|
17天前
|
SQL NoSQL 关系型数据库
|
17天前
|
存储 SQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(1)作者——LJS[含MySQL的下载、安装、配置详解步骤及报错对应解决方法]
Mysql And Redis基础与进阶操作系列(1)之[MySQL的下载、安装、配置详解步骤及报错对应解决方法]
|
17天前
|
SQL 关系型数据库 MySQL