解剖屎山,尋覓黃金之第二彈 焦點(diǎn)關(guān)注
大家好,我3y啊。由于去重邏輯重構(gòu)了幾次,好多股東直呼看不懂,于是我今天再安排一波對(duì)代碼的解析吧。austin支持兩種去重的類型:N分鐘相同內(nèi)容達(dá)到N次去重和一天內(nèi)N次相同渠道頻次去重。
在最開始,我的第一版實(shí)現(xiàn)是這樣的:
publicvoidduplication(TaskInfotaskInfo){//配置示例:{"contentDeduplication":{"num":1,"time":300},"frequencyDeduplication":{"num":5}}JSONObjectproperty=JSON.parseObject(config.getProperty(DEDUPLICATION_RULE_KEY,AustinConstant.APOLLO_DEFAULT_VALUE_JSON_OBJECT));JSONObjectcontentDeduplication=property.getJSONObject(CONTENT_DEDUPLICATION);JSONObjectfrequencyDeduplication=property.getJSONObject(FREQUENCY_DEDUPLICATION);//文案去重DeduplicationParamcontentParams=DeduplicationParam.builder().deduplicationTime(contentDeduplication.getLong(TIME)).countNum(contentDeduplication.getInteger(NUM)).taskInfo(taskInfo).anchorState(AnchorState.CONTENT_DEDUPLICATION).build();contentDeduplicationService.deduplication(contentParams);//運(yùn)營總規(guī)則去重(一天內(nèi)用戶收到最多同一個(gè)渠道的消息次數(shù))Longseconds=(DateUtil.endOfDay(newDate()).getTime()-DateUtil.current())/1000;DeduplicationParambusinessParams=DeduplicationParam.builder().deduplicationTime(seconds).countNum(frequencyDeduplication.getInteger(NUM)).taskInfo(taskInfo).anchorState(AnchorState.RULE_DEDUPLICATION).build();frequencyDeduplicationService.deduplication(businessParams);}
(相關(guān)資料圖)
那時(shí)候很簡單,基本主體邏輯都寫在這個(gè)入口上了,應(yīng)該都能看得懂。后來,群里滴滴哥表示這種代碼不行,不能一眼看出來它干了什么。于是怒提了一波pull request重構(gòu)了一版,入口是這樣的:
publicvoidduplication(TaskInfotaskInfo){//配置樣例:{"contentDeduplication":{"num":1,"time":300},"frequencyDeduplication":{"num":5}}Stringdeduplication=config.getProperty(DeduplicationConstants.DEDUPLICATION_RULE_KEY,AustinConstant.APOLLO_DEFAULT_VALUE_JSON_OBJECT);//去重DEDUPLICATION_LIST.forEach(key->{DeduplicationParamdeduplicationParam=builderFactory.select(key).build(deduplication,key);if(deduplicationParam!=null){deduplicationParam.setTaskInfo(taskInfo);DeduplicationServicededuplicationService=findService(key+SERVICE);deduplicationService.deduplication(deduplicationParam);}});}
我猜想他的思路就是把構(gòu)建去重參數(shù)和選擇具體的去重服務(wù)給封裝起來了,在最外層的代碼看起來就很簡潔了。后來又跟他聊了下,他的設(shè)計(jì)思路是這樣的:考慮到以后會(huì)有其他規(guī)則的去重就把去重邏輯單獨(dú)封裝起來了,之后用策略模版的設(shè)計(jì)模式進(jìn)行了重構(gòu),重構(gòu)后的代碼 模版不變,支持各種不同策略的去重,擴(kuò)展性更高更強(qiáng)更簡潔
確實(shí)牛逼。
我基于上面的思路微改了下入口,代碼最終演變成這樣:
publicvoidduplication(TaskInfotaskInfo){//配置樣例:{"deduplication_10":{"num":1,"time":300},"deduplication_20":{"num":5}}StringdeduplicationConfig=config.getProperty(DEDUPLICATION_RULE_KEY,CommonConstant.EMPTY_JSON_OBJECT);//去重ListdeduplicationList=DeduplicationType.getDeduplicationList();for(IntegerdeduplicationType:deduplicationList){DeduplicationParamdeduplicationParam=deduplicationHolder.selectBuilder(deduplicationType).build(deduplicationConfig,taskInfo);if(Objects.nonNull(deduplicationParam)){deduplicationHolder.selectService(deduplicationType).deduplication(deduplicationParam);}}}
到這,應(yīng)該大多數(shù)人還能跟上吧?在講具體的代碼之前,我們先來簡單看看去重功能的代碼結(jié)構(gòu)(這會(huì)對(duì)后面看代碼有幫助)
去重的邏輯可以統(tǒng)一抽象為:在X時(shí)間段內(nèi)達(dá)到了Y閾值,還記得我曾經(jīng)說過:「去重」的本質(zhì):「業(yè)務(wù)Key」+「存儲(chǔ)」。那么去重實(shí)現(xiàn)的步驟可以簡單分為(我這邊存儲(chǔ)就用的Redis):
通過Key從Redis獲取記錄判斷該Key在Redis的記錄是否符合條件符合條件的則去重,不符合條件的則重新塞進(jìn)Redis更新記錄為了方便調(diào)整去重的參數(shù),我把X時(shí)間段和Y閾值都放到了配置里{"deduplication_10":{"num":1,"time":300},"deduplication_20":{"num":5}}。目前有兩種去重的具體實(shí)現(xiàn):
1、5分鐘內(nèi)相同用戶如果收到相同的內(nèi)容,則應(yīng)該被過濾掉
2、一天內(nèi)相同的用戶如果已經(jīng)收到某渠道內(nèi)容5次,則應(yīng)該被過濾掉
從配置中心拿到配置信息了以后,Builder就是根據(jù)這兩種類型去構(gòu)建出DeduplicationParam,就是以下代碼:
DeduplicationParamdeduplicationParam=deduplicationHolder.selectBuilder(deduplicationType).build(deduplicationConfig,taskInfo);
Builder和DeduplicationService都用了類似的寫法(在子類初始化的時(shí)候指定類型,在父類統(tǒng)一接收,放到Map里管理)
而統(tǒng)一管理著這些服務(wù)有個(gè)中心的地方,我把這取名為DeduplicationHolder
/***@authorhuskey*@date2022/1/18*/@ServicepublicclassDeduplicationHolder{privatefinalMapbuilderHolder=newHashMap<>(4);privatefinalMap serviceHolder=newHashMap<>(4);publicBuilderselectBuilder(Integerkey){returnbuilderHolder.get(key);}publicDeduplicationServiceselectService(Integerkey){returnserviceHolder.get(key);}publicvoidputBuilder(Integerkey,Builderbuilder){builderHolder.put(key,builder);}publicvoidputService(Integerkey,DeduplicationServiceservice){serviceHolder.put(key,service);}}
前面提到的業(yè)務(wù)Key,是在AbstractDeduplicationService的子類下構(gòu)建的:
而具體的去重邏輯實(shí)現(xiàn)則都在LimitService下,{一天內(nèi)相同的用戶如果已經(jīng)收到某渠道內(nèi)容5次}是在SimpleLimitService中處理使用mget和pipelineSetEX就完成了實(shí)現(xiàn)。而{5分鐘內(nèi)相同用戶如果收到相同的內(nèi)容}是在SlideWindowLimitService中處理,使用了lua腳本完成了實(shí)現(xiàn)。
LimitService的代碼都來源于@caolongxiu的pull request,建議大家可以對(duì)比commit再學(xué)習(xí)一番:https://gitee.com/zhongfucheng/austin/pulls/19
1、頻次去重采用普通的計(jì)數(shù)去重方法,限制的是每天發(fā)送的條數(shù)。
2、內(nèi)容去重采用的是新開發(fā)的基于redis中zset的滑動(dòng)窗口去重,可以做到嚴(yán)格控制單位時(shí)間內(nèi)的頻次。
3、redis使用lua腳本來保證原子性和減少網(wǎng)絡(luò)io的損耗
4、redis的key增加前綴做到數(shù)據(jù)隔離(后期可能有動(dòng)態(tài)更換去重方法的需求)
5、把具體限流去重方法從DeduplicationService抽取出來,DeduplicationService只需設(shè)置構(gòu)造器注入時(shí)注入的AbstractLimitService(具體限流去重服務(wù))類型即可動(dòng)態(tài)更換去重的方法 6、使用雪花算法生成zset的唯一value,score使用的是當(dāng)前的時(shí)間戳
針對(duì)滑動(dòng)窗口去重,有會(huì)引申出新的問題:limit.lua的邏輯?為什么要移除時(shí)間窗口的之前的數(shù)據(jù)?為什么ARGV[4]參數(shù)要唯一?為什么要expire?
A: 使用滑動(dòng)窗口可以保證N分鐘達(dá)到N次進(jìn)行去重?;瑒?dòng)窗口可以回顧下TCP的,也可以回顧下刷LeetCode時(shí)的一些題,那這為什么要移除,就不陌生了。
為什么ARGV[4]要唯一,具體可以看看zadd這條命令,我們只需要保證每次add進(jìn)窗口內(nèi)的成員是唯一的,那么就不會(huì)觸發(fā)有更新的操作(我認(rèn)為這樣設(shè)計(jì)會(huì)更加簡單些),而唯一Key用雪花算法比較方便。
為什么expire?,如果這個(gè)key只被調(diào)用一次。那就很有可能在redis內(nèi)存常駐了,expire能避免這種情況。
推薦項(xiàng)目最后再叨叨吧,很多人可能會(huì)發(fā)一段截圖,跑來問我為什么要這樣寫,為什么要以這種方式實(shí)現(xiàn),能不能以這種方式實(shí)現(xiàn)。這時(shí)候,我更想看到的是:你已經(jīng)實(shí)現(xiàn)了第二種方式了,然后探討你寫的這種方案好不好,現(xiàn)有的代碼差在哪里。
畢竟問問題很簡單,我又不是客服,總不能沒誠意的問題我都得一一回答吧。
如果想學(xué)Java項(xiàng)目的,我還是強(qiáng)烈推薦我的開源項(xiàng)目消息推送平臺(tái)Austin,可以用作畢業(yè)設(shè)計(jì),可以用作校招,可以看看生產(chǎn)環(huán)境是怎么推送消息的。
倉庫地址(可點(diǎn)擊閱讀原文跳轉(zhuǎn)):https://gitee.com/zhongfucheng/austin
我開通了股東服務(wù)內(nèi)容,感興趣可以點(diǎn)擊下方看看,主要針對(duì)的是項(xiàng)目喲
VIP服務(wù)
標(biāo)簽:
搶先讀
- csgo哪個(gè)開箱網(wǎng)站最大?csgo箱子爆率一般是多少?
- 撫順十四運(yùn)開幕式幾點(diǎn)開始?
- 大慶中考信息管理平臺(tái)登錄
- 挪威UECC第二艘雙燃料LNG電池混合動(dòng)力PCTC在瑞典哥德堡港命名 全球熱門
- 生成式AI創(chuàng)企的大問題:不缺錢,缺訓(xùn)練數(shù)據(jù)
- 目前那個(gè)銀行信用卡好辦額度高?哪家銀行信用卡好辦額度又高?
- 報(bào)告:韓國2070年75歲以上人口占比將居經(jīng)合組織之首 75~79歲人群近四成希望繼續(xù)工作
- 酸豆角太酸了如何除酸 酸豆角變酸是什么原理?
- 2023梵凈山旅游攻略(開放時(shí)間+門票+交通指南)
- 當(dāng)前熱訊:安徽省美術(shù)館聯(lián)盟成立
- 每日消息!玩游戲最好的筆記本(玩游戲最好的筆記本)
- 演員楊蓉:學(xué)演戲,得先學(xué)做人
- 警方上門調(diào)解兒媳穿短褲被公公打事件 環(huán)球訊息
- 每日訊息!空調(diào)漏水怎么處理視頻(空調(diào)漏水怎么處理)
- 香港小姐2023|仙氣Jumbo最上鏡,翻版劉玉翠身材超火辣|今日觀點(diǎn)
- 175億元投資流向江蘇灌南縣 每日焦點(diǎn)
- 2023 ChinaJoy-Game Connection 環(huán)球熱訊
- 海關(guān)總署恢復(fù)、批準(zhǔn)20家肉類企業(yè)在華注冊(cè)
- 中國光伏軍團(tuán)齊聚德國慕尼黑,較幾周前的上海展有何新亮點(diǎn)?|全球動(dòng)態(tài)
- 雖然看不懂,但中?;?0億,吃下荔灣廣信資產(chǎn)包地塊
- 河南民權(quán)縣一資金互助社違規(guī)吸儲(chǔ),一年期利率高達(dá)4%,有農(nóng)民17萬存款取不出 焦點(diǎn)精選
- 焦點(diǎn)簡訊:揚(yáng)州工會(huì)為新業(yè)態(tài)企業(yè)“法治體檢”
- 粒粒皆辛苦前面一句是什么詩句?粒粒皆辛苦打一成語是什么? 全球今熱點(diǎn)
- 抓實(shí)操演練 重安全生產(chǎn) | 古交市婦幼保健計(jì)劃生育服務(wù)中心開展消防安全培訓(xùn)
- 世界視訊!樹根互聯(lián)“根云工業(yè)互聯(lián)網(wǎng)操作系統(tǒng)4.0”發(fā)布三大場景版本
- 新壹科技CEO雷濤:AIGC時(shí)代給了普通人一個(gè)IP化的機(jī)遇_天天短訊
- 國家發(fā)改委:1-5月份 全國全社會(huì)用電量同比增長5.2%
- 火種成功采集!亞運(yùn)會(huì)倒計(jì)時(shí)100天,杭州準(zhǔn)備好了_環(huán)球熱文
- 黃山屯溪區(qū):讓老人享受幸福 “食”光 世界快播報(bào)
- 大連大孤山濱海社區(qū)衛(wèi)生服務(wù)站二價(jià)/四價(jià)hpv疫苗到苗通知
- 送杜少府之任蜀州翻譯及主旨(送杜少府之任蜀州翻譯)
- 世界熱頭條丨新仙劍奇?zhèn)b傳之揮劍問情角色排行一覽
- 廣發(fā)銀行發(fā)現(xiàn)精彩獲評(píng)“年度創(chuàng)新信用卡APP” 每日快看
- 股票趨勢(shì)線指的是哪根線?畫趨勢(shì)線注意事項(xiàng)有哪些?_天天消息
- win10忘記密碼如何開機(jī)_win10忘記密碼 環(huán)球快訊
- 環(huán)球快訊:在灣心,瞰世界!航拍南沙這一年
- 《無人知曉的故事》獲上影節(jié)電影項(xiàng)目創(chuàng)投大獎(jiǎng) 《她問》世界首映 焦點(diǎn)報(bào)道
- 中原科技城小微企業(yè)園項(xiàng)目順利通過竣工驗(yàn)收 觀熱點(diǎn)
- 領(lǐng)克09亞運(yùn)行政五座版上市 售價(jià)28.99萬元
- 資訊推薦:守住錢袋子 護(hù)好幸福家西安高新區(qū)開展“防范非法集資”集中宣傳日活動(dòng)
- 實(shí)時(shí)焦點(diǎn):智慧農(nóng)業(yè)屬于什么概念?十大智慧農(nóng)業(yè)龍頭股?
- 世界熱消息:資深紋繡培訓(xùn)講師吳麗姿:9年經(jīng)驗(yàn)成就全能型半永久技術(shù)高手
- 《星空》尚未發(fā)售就遭差評(píng) 玩家指責(zé)開發(fā)商及制作人 世界觀點(diǎn)
- 世界觀天下!當(dāng)前資訊!2023年9月全國計(jì)算機(jī)等級(jí)考試報(bào)名將于6月26日開始
- 北京論道|樂播投屏吳仕彬:新環(huán)境下投屏的場景化、合規(guī)化、市場化應(yīng)用 今日最新
- 每日精選:oppoa55手機(jī)鎖屏振動(dòng)怎么關(guān)閉?oppoA55怎么可以將鈴聲放大?
- 【環(huán)球時(shí)快訊】藍(lán)色協(xié)議登錄不進(jìn)去 開服網(wǎng)絡(luò)錯(cuò)誤有效解決方法
- 房貸提前還款的方式有幾種?房貸逾期不還的后果看這里 全球動(dòng)態(tài)
- 全球今日訊!球迷“狂飆”蓋過梅西進(jìn)球,媒體:熱情可理解,“越界”莫贊美
- 國家統(tǒng)計(jì)局:二季度經(jīng)濟(jì)增長明顯快于一季度
- 漫威有5位驚奇隊(duì)長?3個(gè)是一家人,還有一個(gè)能沖進(jìn)恒星 最新
- 【國際漫評(píng)】這是沒有新謠可造了嗎?
- 全球微頭條丨毀滅新生?這款暗黑續(xù)作究竟能否逆風(fēng)翻盤?
- 少量飲酒竟有益心臟健康?哈佛醫(yī)學(xué)院最新研究揭示背后原因……_環(huán)球新消息
- 環(huán)球今熱點(diǎn):陜西寶雞:暖心服務(wù)助力小麥歸倉
- 怎樣獲取莉莉婭的隱藏任務(wù)_需要怎么做-環(huán)球今日?qǐng)?bào)
- 小米14提前發(fā):采用華星極窄邊框直屏|環(huán)球百事通
- 2023年5月上汽集團(tuán)汽車產(chǎn)量情況:新能源汽車銷量同比增長5.94%_天天最新
- 匙能組什么詞語 匙能組什么詞
- 現(xiàn)在鋼鐵俠的模型值不值得買,你要有買二手和加價(jià)的心理準(zhǔn)備才行
- 2023年最新廣西高溫補(bǔ)貼標(biāo)準(zhǔn)及發(fā)放時(shí)間 廣西高溫補(bǔ)貼一個(gè)月多少錢?
- 招商銀行掌上生活獲評(píng)“年度最佳信用卡APP” 世界熱點(diǎn)評(píng)
- 債券基金有哪些風(fēng)險(xiǎn)?如何辦理基金轉(zhuǎn)換?-環(huán)球速讀
- 破壞組蛋白遺傳可能導(dǎo)致腫瘤加速發(fā)展
- SK海力士據(jù)報(bào)將翻倍HBM產(chǎn)能,因人工智能半導(dǎo)體需求增加_天天精選
- 今日要聞!廣西職業(yè)技術(shù)學(xué)院召開2023年教學(xué)部門績效考核工作研討會(huì)
- 天天消息!陜西旬邑縣:執(zhí)法暖民心 錦旗表謝意
- 武功公安持續(xù)深入轄區(qū)企業(yè)開展反詐宣傳_全球微頭條
- 中國民航局:5月份國內(nèi)客運(yùn)規(guī)模比2019年同期增長2.6%-天天報(bào)道
- 共和報(bào):西漢姆聯(lián)、伯恩茅斯和諾丁漢森林有意扎萊夫斯基
- 熱推薦:五年級(jí)英語手抄報(bào)內(nèi)容資料_五年級(jí)英語手抄報(bào)內(nèi)容
- 韓政府:6月15日起每天公布日本核污水排海安全信息_焦點(diǎn)日?qǐng)?bào)
- “消防+交通”打通消防車通道 世界今頭條
- 全球熱議:時(shí)光之穴開啟黑暗之門任務(wù)_時(shí)光之穴怎么去
- 定期存款利息稅-定期存款利息稅率是多少|(zhì)資訊
- 寧夏賀蘭 年產(chǎn)10萬噸物理法多晶硅及光伏全產(chǎn)業(yè)鏈項(xiàng)目開工建設(shè)
- 美國疾控中心:槍支暴力推波助瀾 青少年謀殺率飆升_全球快資訊
- 學(xué)?;貞?yīng)初三家長反對(duì)收費(fèi)被踢出群:家委會(huì)已退款_每日短訊
- 恩威醫(yī)藥同山東朗諾達(dá)成合作 戰(zhàn)略布局得到持續(xù)深化
- 每日關(guān)注!vivo全系列型號(hào)大全:從旗艦到入門級(jí),一網(wǎng)打盡!
- 初始投資成本是什么?初始投資成本怎么計(jì)算?
- 醫(yī)生進(jìn)校,為光祈幼兒園教職工普及健康知識(shí) 頭條焦點(diǎn)
- 天天觀熱點(diǎn):亞運(yùn)會(huì)的運(yùn)動(dòng)員村什么樣?先睹為快
- 空客公司預(yù)測未來二十年全球民用飛機(jī)交付數(shù)量將超過4萬架-焦點(diǎn)短訊
- 唯品會(huì)開啟618年中特賣節(jié)高潮期 運(yùn)動(dòng)戶外等品類迎來增長_全球關(guān)注
- 房地產(chǎn)屬于什么產(chǎn)業(yè)?房地產(chǎn)行業(yè)具體內(nèi)容有哪些?
- 日本央行決定繼續(xù)維持當(dāng)前寬松貨幣政策
- 每日熱議!西安交大理科實(shí)驗(yàn)班哪個(gè)專業(yè)強(qiáng)_西安交大理學(xué)院
- 高合HiPhi Y一體化壓鑄后艙獲碳中和大獎(jiǎng),7月15日全球上市|熱頭條
- 動(dòng)畫|寶“藏”朋友圈
- 前沿?zé)狳c(diǎn):辛奇是什么意思(辛奇隆個(gè)人資料出生哪一年)
- 世界觀焦點(diǎn):法國企業(yè)家中文接受采訪:中國依然是全球經(jīng)濟(jì)最重要?jiǎng)恿?/a>
- 阿里要建“歐洲版”天貓? 回應(yīng):天貓APP在歐洲本身就可以提供服務(wù)-全球看熱訊
- 世界熱頭條丨德意志銀行、富達(dá)國際收購萬達(dá)債券 已增持2.63億美元
- 世界觀天下!阿里影業(yè)為什么暴跌
- 愛情公寓4在線播放_(tái)愛情公寓3在線播放免費(fèi)高清_世界短訊
- 當(dāng)前最新:新零售+新能源 解碼安步汽車數(shù)字化突圍
- 開場81秒破門 梅西助阿根廷隊(duì)取勝
- 飛機(jī)靠橋率不高,讓坐擺渡車?民航局啟動(dòng)專項(xiàng)整治 天天聚看點(diǎn)
- 2023山東省第二康復(fù)醫(yī)院招聘備案制工作人員筆試準(zhǔn)考證打印通知-全球快資訊