亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Spring Boot項(xiàng)目實(shí)踐之問答社區(qū)

binaryTree / 2295人閱讀

摘要:異步事件處理本項(xiàng)目涉及到多種異步事件的處理。即是的粉絲,是的關(guān)注對(duì)象。模式定義優(yōu)缺點(diǎn)推事件觸發(fā)后廣播給所有粉絲。具體來說,推模式就是事件觸發(fā)后產(chǎn)生,觸發(fā)事件的用戶下所有粉絲的實(shí)現(xiàn)中都存入該的。

項(xiàng)目源代碼已托管在 Github,歡迎 Star、Fork。
Q & A 問答社區(qū)

QA 是一個(gè)基于 B/S 架構(gòu)而設(shè)計(jì)開發(fā)的社區(qū)網(wǎng)站。

主要為用戶提供以下服務(wù):

問題發(fā)布

評(píng)論

用戶私信

關(guān)注

站內(nèi)全文搜索

技術(shù)選型

Spring Boot + MyBatis + MySQL + Redis + FreeMarker

功能描述 注冊(cè)登錄

為了保證用戶信息安全,系統(tǒng)對(duì)用戶密碼采用「salt + md5」方式進(jìn)行加密。用戶注冊(cè)/登錄成功后,系統(tǒng)會(huì)生成一個(gè) ticket ,將 ticket 與用戶 id 相關(guān)聯(lián),并將此信息插入到數(shù)據(jù)庫表 login_ticket 中,同時(shí)將 ticket 響應(yīng)給客戶端。

用戶每次請(qǐng)求頁面的時(shí)候,都需要先經(jīng)過 PassportInterceptor 攔截器,攔截器判斷此 ticket 是否真實(shí)有效,若是,根據(jù) ticket 對(duì)應(yīng)的用戶 id ,查出相應(yīng)用戶信息,并添加至頁面上下文中。

用戶內(nèi)容發(fā)布

問題發(fā)布

評(píng)論發(fā)布

私信發(fā)布

在以上 UGC (User Generated Content, 用戶產(chǎn)生的內(nèi)容)中,系統(tǒng)都會(huì)進(jìn)行 HTML 標(biāo)簽及敏感詞過濾,這在一定程度上防止網(wǎng)站被注入腳本或者充斥著不良信息。

若沒有對(duì) HTML 標(biāo)簽進(jìn)行處理,當(dāng)用戶發(fā)布的內(nèi)容含有如時(shí),網(wǎng)站頁面每次加載此內(nèi)容時(shí)都會(huì)彈出消息框。

對(duì)于敏感詞過濾,按照常規(guī)的思維,也是最簡(jiǎn)單的方式,就是:對(duì)于每個(gè)敏感詞,都在文本中查找該敏感詞是否出現(xiàn),出現(xiàn)則進(jìn)行替換。這種方式,每個(gè)敏感詞都要在一段文本中進(jìn)行遍歷查找,復(fù)雜度非常高。

本項(xiàng)目采用「前綴樹」方式實(shí)現(xiàn)敏感詞過濾,空間換時(shí)間,效率較高。前綴樹結(jié)點(diǎn)結(jié)構(gòu)如下:

class TrieNode {
    // 標(biāo)記是否為敏感詞結(jié)尾
    boolean end;
    
    // 該結(jié)點(diǎn)的所有直接子結(jié)點(diǎn)
    Map subNodes = new HashMap<>();
    
    // 添加一個(gè)子結(jié)點(diǎn)
    void addSubNode(Character key, TrieNode node) {
        subNodes.put(key, node);
    }
    
    // 根據(jù)key獲取子結(jié)點(diǎn)
    TrieNode getSubNode(Character key) {
        return subNodes.get(key);
    }
}

后臺(tái)從敏感詞文件 SensitiveWords.txt 順序讀取每一行建立前綴樹。進(jìn)行過濾時(shí),遍歷需要過濾的文本,用星號(hào)替換發(fā)現(xiàn)的敏感詞。假設(shè)文本長(zhǎng)度為 len,前綴樹的最大高度為 h,那么此算法的最壞時(shí)間復(fù)雜度為 O(len*h)。

算法比較
假如敏感詞平均長(zhǎng)度為10,數(shù)量為100000,文本長(zhǎng)度為 len。
常規(guī)方式,復(fù)雜度O(100000 (len + 10));前綴樹算法復(fù)雜度O(10 len)。

對(duì)于評(píng)論功能,系統(tǒng)建立的是一個(gè)統(tǒng)一的評(píng)論服務(wù)中心,通過 EntityType 與 EntityId 識(shí)別所評(píng)論的實(shí)體。用戶對(duì)于問題/評(píng)論的回復(fù),都可以應(yīng)用此服務(wù)。查詢某實(shí)體下的評(píng)論時(shí),同樣根據(jù) EntityType 和 EntityId 查詢即可。

用戶內(nèi)容贊踩

贊踩功能采用「Redis」作為數(shù)據(jù)存儲(chǔ)。Why Redis?

比較一下 Redis 和 MySQL:

Redis: key-value數(shù)據(jù)庫,數(shù)據(jù)放在內(nèi)存

MySQL: 關(guān)系型數(shù)據(jù)庫,數(shù)據(jù)放在磁盤

Redis 適合放一些頻繁使用、比較熱的數(shù)據(jù)。因?yàn)閿?shù)據(jù)放在了內(nèi)存中,讀寫性能卓越。

Redis 類型 數(shù)據(jù)結(jié)構(gòu) 應(yīng)用場(chǎng)景
List 雙向列表 最新列表、關(guān)注列表
Set 無序集合 贊踩、抽獎(jiǎng)、已讀、共同好友
SortedSet 優(yōu)先隊(duì)列 排行榜
Hash 哈希表 不定長(zhǎng)屬性數(shù)
KV 單一數(shù)值 驗(yàn)證碼、PV、緩存

除了用戶內(nèi)容贊踩,在本項(xiàng)目中,Redis 還應(yīng)用于以下場(chǎng)景:

異步事件處理

關(guān)注服務(wù)

Timeline

本小節(jié)討論用戶內(nèi)容贊踩服務(wù)。

用戶對(duì)某一實(shí)體點(diǎn)贊,會(huì)將"LIKE:ENTITY_TYPE:ENTITY_ID"作為 key ,用戶 id 作為 value ,存入 like 集合中。同時(shí)移除 unlike 集合中該 key 對(duì)應(yīng)的用戶 id。點(diǎn)踩服務(wù)反之。
最后將點(diǎn)贊數(shù)響應(yīng)給頁面。

異步事件處理

本項(xiàng)目涉及到多種異步事件的處理。如:

用戶評(píng)論了某個(gè)問題

用戶點(diǎn)贊了某條評(píng)論

用戶關(guān)注了另一個(gè)實(shí)體

這些動(dòng)作并不是單一的,它們會(huì)觸發(fā)一些后續(xù)的操作:

用戶評(píng)論了某個(gè)問題,系統(tǒng)除了處理“評(píng)論”這個(gè)動(dòng)作外,還需要給該問題對(duì)應(yīng)的用戶發(fā)送一條消息,通知說“xx評(píng)論你的問題”,或者還需要給用戶增加積分/經(jīng)驗(yàn)...

事件觸發(fā)者并不關(guān)心這些后續(xù)的任務(wù),系統(tǒng)處理完某個(gè)動(dòng)作后就可以將結(jié)果返回給觸發(fā)者,而后續(xù)的任務(wù)交給系統(tǒng)進(jìn)行異步處理即可。

因此,設(shè)計(jì)一個(gè)異步事件處理框架尤為重要。
本項(xiàng)目的異步框架如下圖所示:

業(yè)務(wù)觸發(fā)一個(gè)異步事件,EventProducer 將該事件(EventModel)序列化并存入隊(duì)列(Redis List)中,EventConsumer 開啟線程循環(huán)從隊(duì)列中取出事件,識(shí)別該事件的類型,找出該類型對(duì)應(yīng)的一系列 EventHandler,交由這些 Handler 去處理。

EventModel 的設(shè)計(jì)如下:

class EventModel {
    // 事件類型
    EventType type;
    
    // 事件觸發(fā)者
    int actorId;
    
    // 事件對(duì)應(yīng)的實(shí)體
    int entityType;
    int entityId;
    
    // 事件對(duì)應(yīng)的實(shí)體的Owner
    int entityOwnerId;
    
    // 一些擴(kuò)展字段
    Map exts;
}
SNS 關(guān)注服務(wù)

與評(píng)論功能類似,對(duì)于關(guān)注功能,系統(tǒng)同樣建立了一個(gè)統(tǒng)一的關(guān)注服務(wù)中心,用戶可以關(guān)注不同的實(shí)體(問題/用戶),只需要通過 EntityType 和 EntityId 識(shí)別即可。
在數(shù)據(jù)存儲(chǔ)方面,采用 Redis 的 zset 完成,原因有以下幾個(gè):

zset 有序,系統(tǒng)可以根據(jù)用戶關(guān)注實(shí)體的時(shí)間倒序排列,獲取最新的關(guān)注列表;

zset 去重,用戶不能重復(fù)關(guān)注同一個(gè)實(shí)體;

zset 可以獲取兩用戶之間的共同關(guān)注。

一個(gè)用戶,系統(tǒng)存儲(chǔ)兩個(gè)集合:

①保存用戶關(guān)注的實(shí)體;②保存關(guān)注用戶的人。

即 A 是 B 的粉絲,B 是 A 的關(guān)注對(duì)象。 [參考資料 ]

用戶關(guān)注了一個(gè)問題,需要發(fā)生兩個(gè)動(dòng)作:

將問題存入①中

在②中存入用戶 id

這兩個(gè)動(dòng)作必須同時(shí)發(fā)生,因此,這里用到了 Redis 事務(wù)保證原子性和數(shù)據(jù)的一致性。

另外,對(duì)于關(guān)注功能,如前面所說,會(huì)觸發(fā)異步事件,將消息通知被關(guān)注的實(shí)體 / 實(shí)體 Owner。

用戶內(nèi)容排名

本系統(tǒng)未采用排名算法。若要了解相關(guān)算法,可以參考如下資料:

基于用戶投票的排名算法(一):Delicious和Hacker News

基于用戶投票的排名算法(二):Reddit

基于用戶投票的排名算法(三):Stack Overflow

基于用戶投票的排名算法(四):牛頓冷卻定律

基于用戶投票的排名算法(五):威爾遜區(qū)間

基于用戶投票的排名算法(六):貝葉斯平均

Timeline Feed 流服務(wù)

當(dāng)用戶更新動(dòng)態(tài)時(shí),該用戶所有粉絲都可以在一定時(shí)間內(nèi)收到新的動(dòng)態(tài)(也稱為新鮮事、feed),可以由 “推拉模式” 實(shí)現(xiàn)。

模式 定義 優(yōu)缺點(diǎn)
事件觸發(fā)后廣播給所有粉絲。 對(duì)于粉絲數(shù)過多的事件,后臺(tái)壓力較大,浪費(fèi)存儲(chǔ)空間;
流程清晰,開發(fā)難度低,關(guān)注新用戶需要同步更新 feed 流。
登錄打開頁面時(shí),根據(jù)關(guān)注的實(shí)體動(dòng)態(tài)生成 Timeline 內(nèi)容。 讀取壓力大,存儲(chǔ)占用小,緩存最新讀取的 feed,根據(jù)時(shí)間分區(qū)拉取。
推拉 活躍/在線用戶推,其他用戶拉。 降低存儲(chǔ)空間,又滿足大部分用戶的讀取需求。

具體來說,推模式就是:事件觸發(fā)后產(chǎn)生 feed,觸發(fā)事件的用戶下所有粉絲的 Timeline(redis list 實(shí)現(xiàn))中都存入該 feed 的 id。而拉模式,就是當(dāng)前用戶去拉取自己關(guān)注的人的 feed。

更多推拉模式相關(guān),可以參考 微博 feed 系統(tǒng)推拉模式。

Python 爬蟲

由于系統(tǒng)初始數(shù)據(jù)較少,為了豐富網(wǎng)站內(nèi)容,本項(xiàng)目采用 pyspider 實(shí)現(xiàn)對(duì) V2EX 網(wǎng)站的數(shù)據(jù)爬取,存儲(chǔ)到后臺(tái)數(shù)據(jù)庫,并展示在前端頁面上。

安裝 pyspider:

pip install pyspider

啟動(dòng) pyspider:

pyspider
站內(nèi)全文搜索服務(wù)

本項(xiàng)目在全文搜索服務(wù)上采用 Solr 框架,中文分詞采用 Solr 自帶的中文分詞插件 solr_cnAnalyzer 。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/71222.html

相關(guān)文章

  • [直播視頻] 《Java 微服務(wù)實(shí)踐 - Spring Boot 系列》限時(shí)折扣

    摘要:作為微服務(wù)的基礎(chǔ)設(shè)施之一,背靠強(qiáng)大的生態(tài)社區(qū),支撐技術(shù)體系。微服務(wù)實(shí)踐為系列講座,專題直播節(jié),時(shí)長(zhǎng)高達(dá)小時(shí),包括目前最流行技術(shù),深入源碼分析,授人以漁的方式,幫助初學(xué)者深入淺出地掌握,為高階從業(yè)人員拋磚引玉。 簡(jiǎn)介 目前業(yè)界最流行的微服務(wù)架構(gòu)正在或者已被各種規(guī)模的互聯(lián)網(wǎng)公司廣泛接受和認(rèn)可,業(yè)已成為互聯(lián)網(wǎng)開發(fā)人員必備技術(shù)。無論是互聯(lián)網(wǎng)、云計(jì)算還是大數(shù)據(jù),Java平臺(tái)已成為全棧的生態(tài)體系,...

    Enlightenment 評(píng)論0 收藏0
  • 次世代的會(huì)話管理項(xiàng)目 Spring Session

    摘要:會(huì)話管理一直是企業(yè)級(jí)應(yīng)用的重要部分。傳統(tǒng)會(huì)話管理技術(shù)的問題的目的是解決傳統(tǒng)的會(huì)話管理技術(shù)的各種問題。對(duì)如和之類的閉源產(chǎn)品,找到適合它們的會(huì)話管理技術(shù)的替代實(shí)現(xiàn)則通常是不可能的。典型的應(yīng)用會(huì)將當(dāng)前用戶的身份及其安全級(jí)別或角色存儲(chǔ)在會(huì)話里面。 歡迎大家前往騰訊云+社區(qū),獲取更多騰訊海量技術(shù)實(shí)踐干貨哦~ 本文來自云+社區(qū)翻譯社,由Tnecesoc編譯。 會(huì)話管理一直是 Java 企業(yè)級(jí)應(yīng)用的...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • Spring Boot 最流行的 16 條實(shí)踐解讀!

    摘要:來源是最流行的用于開發(fā)微服務(wù)的框架。以下依次列出了最佳實(shí)踐,排名不分先后。這非常有助于避免可怕的地獄。推薦使用構(gòu)造函數(shù)注入這一條實(shí)踐來自的項(xiàng)目負(fù)責(zé)人。保持業(yè)務(wù)邏輯免受代碼侵入的一種方法是使用構(gòu)造函數(shù)注入。 showImg(https://mmbiz.qpic.cn/mmbiz_jpg/R3InYSAIZkHQ40ly9Oztiart2lESCyjCH0JwFRp3oErlYobhibM...

    Ethan815 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<