SpringBoot -- 抱团学习社区系统项目实战
文章目錄
- 📑 項目簡介
- 📖 核心技術棧
- 💻 開發環境
- ? 界面展示
- 🎯 功能邏輯圖
- 注冊
- 登錄 | 登出
- 分頁顯示所有的帖子
- 賬號設置
- 發布帖子(異步請求)
- 顯示評論及相關信息
- 添加評論(事務管理)
- 私信列表和詳情頁
- 發送私信(異步請求)
- 點贊(異步請求)
- 我的獲贊數量
- 關注(異步請求)
- 關注列表
- 發送系統通知
- 顯示系統通知
- 搜索
- 置頂加精刪除(異步請求)
- 網站數據統計
- 帖子熱度計算
📑 項目簡介
抱團學習社區系統 是一套前后端不分離的社區系統,基于目前主流 Java Web 技術棧(SpringBoot + MyBatis + MySQL + Redis + Kafka + Elasticsearch + Spring Security + …)。包含帖子、評論、私信、系統通知、點贊、關注、搜索、用戶設置、數據統計等功能模塊。
📖 核心技術棧
后端:
- Spring
- Spring Boot 2.1.5 RELEASE
- Spring MVC
- Mybatis
- 數據庫:MySQL 5.7
- 分布式緩存:Redis
- 本地緩存:Caffeine
- 消息隊列:kafka 2.12-2.3.0
- 搜索引擎:elasticsearch-6.4.3
- 安全:Spring Security
- 郵件服務:Spring Mail
- 分布式定時任務:Spring Quartz
- 日志:SLFJ(日志接口)+ Logback(日志實現)
前端:
- Thymeleaf
- Bootstrap 4.x
- JQuery
- Ajax
💻 開發環境
- 操作系統:Windows 10
- 構建工具:Apache Maven
- 集成開發工具:Intellij IDEA
- 應用服務器:Apache Tomcat
- 接口測試工具:Postman
- 壓力測試工具:Apache JMeter
- Java版本:Java 8
? 界面展示
- 帖子發布頁
- 帖子詳情頁
- 私信詳情頁
- 賬號設置頁
- 搜索詳情頁
🎯 功能邏輯圖
單向綠色箭頭:- 前端模板 -> Controller:表示這個前端模板中有一個超鏈接是由這個 Controller 處理的- Controller -> 前端模板:表示這個 Controller 會像該前端模板傳遞數據或者跳轉雙向綠色箭頭:表示 Controller 和前端模板之間進行參數的相互傳遞或使用單向藍色箭頭: A -> B,表示 A 方法調用了 B 方法單向紅色箭頭:數據庫或緩存操作注冊
- 用戶注冊成功,將用戶信息存入 MySQL,但此時該用戶狀態為未激活
- 向用戶發送激活郵件,用戶點擊鏈接則激活賬號(Spring Mail)
登錄 | 登出
登錄認證模塊跳過了 Spring Secuity 自帶的認證機制。主要邏輯如下:
- 進入登錄界面,隨機生成一個字符串來標識這個將要登錄的用戶,將這個字符串短暫的存入 Cookie(60 秒);
- 動態生成驗證碼,并將驗證碼及標識該用戶的字符串短暫存入 Redis(60 秒);
- 為登錄成功(驗證用戶名、密碼、驗證碼)的用戶隨機生成登錄憑證且設置狀態為有效,并將登錄憑證及其狀態等信息永久存入 Redis,再在 Cookie 中存一份登錄憑證;
- 使用攔截器在所有的請求執行之前,從 Cookie 中獲取登錄憑證,只要 Redis 中該憑證有效并在有效期內,本次請求就會一直持有該用戶信息(使用 ThreadLocal 持有用戶信息,保證多臺服務器上用戶的登錄狀態同步);
- 勾選記住我,則延長 Cookie 中登錄憑證的有效時間;
- 用戶登出,將憑證狀態設為無效,并更新 Redis 中該登錄憑證的相關信息。
下圖是登錄模塊的功能邏輯圖,并沒有使用 Spring Security 提供的認證邏輯(我覺得這個模塊是最復雜的,這張圖其實很多細節還沒有畫全)
分頁顯示所有的帖子
- 支持按照 “發帖時間” 顯示
- 支持按照 “熱度排行” 顯示(Spring Quartz)
- 將熱帖列表和所有帖子的總數存入本地緩存 Caffeine(利用分布式定時任務 Spring Quartz 每隔一段時間就刷新計算帖子的熱度/分數 — 見下文,而 Caffeine 里的數據更新不用我們操心,它天生就會自動的更新它擁有的數據,給它一個初始化方法就完事兒)
賬號設置
- 修改頭像(異步請求)
- 將用戶選擇的頭像圖片文件上傳至七牛云服務器
- 修改密碼
此處只畫出修改頭像:
發布帖子(異步請求)
發布帖子(過濾敏感詞),將其存入 MySQL
顯示評論及相關信息
評論部分前端的名稱顯示有些缺陷,有興趣的小伙伴歡迎提 PR 解決 ~
關于評論模塊需要注意的就是評論表的設計,把握其中字段的含義,才能透徹了解這個功能的邏輯。
評論 Comment 的目標類型(帖子,評論) entityType 和 entityId 以及對哪個用戶進行評論/回復 targetId 是由前端傳遞給 DiscussPostController 的
一個帖子的詳情頁需要封裝的信息大概如下:
添加評論(事務管理)
發布對帖子的評論(過濾敏感詞),將其存入 MySQL
私信列表和詳情頁
發送私信(異步請求)
點贊(異步請求)
將點贊相關信息存入 Redis 的數據結構 set 中。其中,key 命名為 like:entity:entityType:entityId,value 即點贊用戶的 id。比如 key = like:entity:2:246 value = 11 表示用戶 11 對實體類型 2 即評論進行了點贊,該評論的 id 是 246
某個用戶的獲贊數量對應的存儲在 Redis 中的 key 是 like:user:userId,value 就是這個用戶的獲贊數量
我的獲贊數量
關注(異步請求)
- 若 A 關注了 B,則 A 是 B 的粉絲 Follower,B 是 A 的目標 Followee
- 關注的目標可以是用戶、帖子、題目等,在實現時將這些目標抽象為實體(目前只做了關注用戶)
將某個用戶關注的實體相關信息存儲在 Redis 的數據結構 zset 中:key 是 followee:userId:entityType ,對應的 value 是 zset(entityId, now) ,以關注的時間進行排序。比如說 followee:111:3 對應的value (20, 2020-02-03-xxxx),表明用戶 111 關注了一個類型為 3 的實體即人(用戶),關注的這個實體 id 是 20,關注該實體的時間是 2020-02-03-xxxx
同樣的,將某個實體擁有的粉絲相關信息也存儲在 Redis 的數據結構 zset 中:key 是 follower:entityType:entityId,對應的 value 是 zset(userId, now),以關注的時間進行排序
關注列表
發送系統通知
顯示系統通知
搜索
- 發布事件
- 發布帖子時,通過消息隊列將帖子異步地提交到 Elasticsearch 服務器
- 為帖子增加評論時,通過消息隊列將帖子異步地提交到 Elasticsearch 服務器
- 搜索服務
- 從 Elasticsearch 服務器搜索帖子
- 從 Elasticsearch 服務器刪除帖子(當帖子從數據庫中被刪除時)
- 顯示搜索結果
類似的,置頂、加精也會觸發發帖事件,就不再圖里面畫出來了。
置頂加精刪除(異步請求)
網站數據統計
- 獨立訪客 UV
- 存入 Redis 的 HyperLogLog
- 支持單日查詢和區間日期查詢
- 日活躍用戶 DAU
- 存入 Redis 的 Bitmap
- 支持單日查詢和區間日期查詢
- 權限管理(Spring Security)
- 只有管理員可以查看網站數據統計
帖子熱度計算
每次發生點贊(給帖子點贊)、評論(給帖子評論)、加精的時候,就將這些帖子信息存入緩存 Redis 中,然后通過分布式的定時任務 Spring Quartz,每隔一段時間就從緩存中取出這些帖子進行計算分數。
帖子分數/熱度計算公式:分數(熱度) = 權重 + 發帖距離天數
// 計算權重 double w = (wonderful ? 75 : 0) + commentCount * 10 + likeCount * 2; // 分數 = 權重 + 發帖距離天數 double score = Math.log10(Math.max(w, 1))+ (post.getCreateTime().getTime() - epoch.getTime()) / (1000 * 3600 * 24);總結
以上是生活随笔為你收集整理的SpringBoot -- 抱团学习社区系统项目实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: antd FormItem嵌套FormI
- 下一篇: WGCNA:(加权共表达网络分析)