解剖屎山,尋覓黃金之第二彈 全球看點(diǎn)
大家好,我3y啊。由于去重邏輯重構(gòu)了幾次,好多股東直呼看不懂,于是我今天再安排一波對代碼的解析吧。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);}
(資料圖片僅供參考)
那時(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ì)思路是這樣的:考慮到以后會有其他規(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)(這會對后面看代碼有幫助)
去重的邏輯可以統(tǒng)一抽象為:在X時(shí)間段內(nèi)達(dá)到了Y閾值,還記得我曾經(jīng)說過:「去重」的本質(zhì):「業(yè)務(wù)Key」+「存儲」。那么去重實(shí)現(xiàn)的步驟可以簡單分為(我這邊存儲就用的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,建議大家可以對比commit再學(xué)習(xí)一番:https://gitee.com/zhongfucheng/austin/pulls/19
1、頻次去重采用普通的計(jì)數(shù)去重方法,限制的是每天發(fā)送的條數(shù)。
2、內(nèi)容去重采用的是新開發(fā)的基于redis中zset的滑動窗口去重,可以做到嚴(yán)格控制單位時(shí)間內(nèi)的頻次。
3、redis使用lua腳本來保證原子性和減少網(wǎng)絡(luò)io的損耗
4、redis的key增加前綴做到數(shù)據(jù)隔離(后期可能有動態(tài)更換去重方法的需求)
5、把具體限流去重方法從DeduplicationService抽取出來,DeduplicationService只需設(shè)置構(gòu)造器注入時(shí)注入的AbstractLimitService(具體限流去重服務(wù))類型即可動態(tài)更換去重的方法 6、使用雪花算法生成zset的唯一value,score使用的是當(dāng)前的時(shí)間戳
針對滑動窗口去重,有會引申出新的問題:limit.lua的邏輯?為什么要移除時(shí)間窗口的之前的數(shù)據(jù)?為什么ARGV[4]參數(shù)要唯一?為什么要expire?
A: 使用滑動窗口可以保證N分鐘達(dá)到N次進(jìn)行去重?;瑒哟翱诳梢曰仡櫹耇CP的,也可以回顧下刷LeetCode時(shí)的一些題,那這為什么要移除,就不陌生了。
為什么ARGV[4]要唯一,具體可以看看zadd這條命令,我們只需要保證每次add進(jìn)窗口內(nèi)的成員是唯一的,那么就不會觸發(fā)有更新的操作(我認(rèn)為這樣設(shè)計(jì)會更加簡單些),而唯一Key用雪花算法比較方便。
為什么expire?,如果這個(gè)key只被調(diào)用一次。那就很有可能在redis內(nèi)存常駐了,expire能避免這種情況。
推薦項(xiàng)目最后再叨叨吧,很多人可能會發(fā)一段截圖,跑來問我為什么要這樣寫,為什么要以這種方式實(shí)現(xiàn),能不能以這種方式實(shí)現(xiàn)。這時(shí)候,我更想看到的是:你已經(jīng)實(shí)現(xiàn)了第二種方式了,然后探討你寫的這種方案好不好,現(xiàn)有的代碼差在哪里。
畢竟問問題很簡單,我又不是客服,總不能沒誠意的問題我都得一一回答吧。
如果想學(xué)Java項(xiàng)目的,我還是強(qiáng)烈推薦我的開源項(xiàng)目消息推送平臺Austin,可以用作畢業(yè)設(shè)計(jì),可以用作校招,可以看看生產(chǎn)環(huán)境是怎么推送消息的。
倉庫地址(可點(diǎn)擊閱讀原文跳轉(zhuǎn)):https://gitee.com/zhongfucheng/austin
我開通了股東服務(wù)內(nèi)容,感興趣可以點(diǎn)擊下方看看,主要針對的是項(xiàng)目喲
VIP服務(wù)
標(biāo)簽:
搶先讀
- 推薦一款輕量級全棧式開源測試平臺! 全球播資訊
- 2023端午節(jié)石家莊景點(diǎn)匯總(持續(xù)更新) 環(huán)球最新
- 羅氏藥物Columvi獲FDA批準(zhǔn),預(yù)計(jì)未來幾周在美國上市 今日熱文
- 中國移動發(fā)布短視頻生態(tài)合作計(jì)劃!
- 覃海寧:生物多樣性保護(hù)可以從原地保護(hù)和遷地保護(hù)著手|世界看點(diǎn)
- 女子右手卡進(jìn)機(jī)器滾輪,聊城消防員5分鐘快速救援
- 環(huán)球訊息:云南白藥CEO董明談云南白藥的“變與不變”
- 大悅城控股:“20大悅01”不行使贖回選擇權(quán) 下調(diào)票面利率為3.15%-全球新要聞
- 看熱訊:中國著名出版社聯(lián)合發(fā)布學(xué)術(shù)圖書英譯成果 力推中國學(xué)術(shù)走向世界
- ET5 Touring引人矚目 可蔚來還是更需要一款“Model Y”
- 一圖讀懂“亮劍浦江”上海個(gè)人信息保護(hù)專項(xiàng)行動:為期半年,“劍”指八大消費(fèi)場景
- 2023合肥城鄉(xiāng)居民醫(yī)保補(bǔ)繳流程
- IMF:歐元區(qū)通脹仍強(qiáng)勁 歐洲央行需進(jìn)一步加息并保持緊縮
- 胎動是什么(胎動的癥狀是什么樣的)|當(dāng)前要聞
- ?新一輪防守反擊打響,A股夏季攻勢焦點(diǎn)
- 觀城·宜賓丨2023動力電池大會碩果累累,促高校畢業(yè)生就業(yè)如火如荼-今日熱聞
- 每日速訊:Brand Finance發(fā)布全球酒店品牌Top50榜單
- 豪捐3.5億人民幣,盛贊袁隆平,“訪華??汀北葼柹w茨這次來華在關(guān)注什么?
- 當(dāng)前通訊!卓創(chuàng)資訊:白羽肉雞6-7月市場行情或延續(xù)季節(jié)性下滑走勢
- 貴州省普安縣發(fā)布雷電黃色預(yù)警
- 2023秋季學(xué)期湖南開學(xué)時(shí)間是幾號
- 焦點(diǎn)熱議:年內(nèi)三季度風(fēng)電新增裝機(jī)534萬千瓦 同比增長0.72%
- 夢幻西游2008買下4000億經(jīng)驗(yàn)角色,9年前6k5買滿修號還帶裝備和BB
- 環(huán)球熱點(diǎn)評!英特爾發(fā)布全新硅自旋量子比特芯片Tunnel Falls,推動量子計(jì)算走向?qū)嵱?/a>
- 在大連打進(jìn)國足首球 林良銘:我會貢獻(xiàn)所有的力量給國家隊(duì)
- 五部門:支持保險(xiǎn)機(jī)構(gòu)擴(kuò)大農(nóng)村居民意外傷害險(xiǎn)、健康保險(xiǎn)、養(yǎng)老保險(xiǎn)等產(chǎn)品供給 看點(diǎn)
- 報(bào)道:寶馨科技
- 坐地鐵直達(dá)上海!蘇州11號線軌交今日免費(fèi)試乘:6月運(yùn)營 今日訊
- 遠(yuǎn)大再定合肥濱湖高端改善,萬眾矚目的BK202303號地塊案名正式發(fā)布!|新動態(tài)
- 獎勵一套房,慰問金10萬!最新回應(yīng):都不收
- 湖人后悔了嗎?湖人舊將再奪總冠軍成熱火克星!_當(dāng)前頭條
- 世界球精選!智明達(dá): 公司有將AI技術(shù)用于項(xiàng)目研發(fā),目前暫無研發(fā)生產(chǎn)AI服務(wù)器的計(jì)劃
- 環(huán)球頭條:業(yè)內(nèi)人士:預(yù)計(jì)PC換機(jī)潮將在2024年出現(xiàn) 對相關(guān)芯片需求有望明顯增長
- “八大突破”提供更實(shí)用住房保障服務(wù) 蘇州公積金靈活就業(yè)試點(diǎn)2.0版7月1日實(shí)施
- 分享米飯團(tuán)子的簡單做法 ,秒變米飯殺手_微資訊
- 打造新團(tuán)隊(duì)!Woj:蒙蒂聘請杰克擔(dān)任活塞助理教練|天天滾動
- 渤海銀行積極參與2023年全民反詐宣傳活動_今日熱門
- 芯片初創(chuàng)公司【Etched.ai】完成536萬美元種子輪融資,Primary Venture Partners 領(lǐng)投
- 【世界聚看點(diǎn)】2023昆明市第一中學(xué)高中招生公告 附學(xué)費(fèi)+咨詢電話+人數(shù)
- 【全球報(bào)資訊】服務(wù)設(shè)計(jì)為互聯(lián)網(wǎng)剪輯類工具帶來新機(jī)遇
- 當(dāng)前頭條:大澤電極近期獲得首批由昆明市市場監(jiān)督管理局審定批準(zhǔn)的“知識產(chǎn)權(quán)運(yùn)營服務(wù)體系建設(shè)專利密集型產(chǎn)品”的認(rèn)定
- (聚焦海峽論壇)“海峽金融論壇·臺企發(fā)展峰會”啟幕 臺港澳青年創(chuàng)新創(chuàng)業(yè)獲“大禮包”-環(huán)球視點(diǎn)
- 添新規(guī)了!故宮管理更規(guī)范更細(xì)致
- 環(huán)球即時(shí):華脈科技:控股股東籌劃重大事項(xiàng) 股票6月19日開市起停牌
- 環(huán)球焦點(diǎn)!安康還有這樣一所大學(xué),你知道嗎?
- 惠同新材北交所IPO注冊獲批:擬募資約1.66億元 用于年產(chǎn)350噸金屬纖維項(xiàng)目等
- 納爾股份(002825.SZ):股東王樹明及楊建堂減持期過半 已減持合計(jì)3.86%股份
- 當(dāng)前看點(diǎn)!粵港澳大灣區(qū)車展:坦克500 Hi4-T 月底上市,坦克400 Hi4-T華南首秀
- 打造開放高地 江西贛州國際陸港“融灣”再加速
- 家長反對家委會收費(fèi)犒勞考生被班主任踢出群,當(dāng)?shù)亟逃纸槿隷每日快播
- 每日焦點(diǎn)!IPO觀察丨從億晶光電套現(xiàn)超30億后 荀建華家族再建“小號”沖擊上市引質(zhì)疑
- 世界快資訊丨阿里巴巴全球數(shù)學(xué)競賽決賽6月17日正式打響
- 熱門看點(diǎn):鄭州高新區(qū)楓楊辦事處深入開展“隨手拍”宣傳活動
- 懷孕8個(gè)月女子遭連開4槍,母子皆亡,被害時(shí)正與丈夫在車?yán)锏燃t燈-天天熱聞
- 省委召開專題會議研究推進(jìn)小流域綜合治理試點(diǎn)工作 每日訊息
- 全球速看:抖音如何開櫥窗賣東西?怎么引入流量?
- 世界微動態(tài)丨無盡劍路西法口訣(無盡劍路西法)
- 四川省1-5月規(guī)模以上工業(yè)增加值同比增長2.9% 天天播報(bào)
- win7如何加密磁盤 windows7怎樣給磁盤加密-當(dāng)前熱門
- 環(huán)球今日報(bào)丨2023昆明市第七屆運(yùn)動會志愿者福利有哪些?
- 蓮湖區(qū)紅廟坡街道召開重點(diǎn)項(xiàng)目·企業(yè)招商推介大會 奏響地區(qū)高質(zhì)量發(fā)展強(qiáng)音|環(huán)球滾動
- 每年花300億吃榴蓮,中國人為何榴蓮成癮?
- 環(huán)球觀天下!孩子改隨母姓,父親就能不用再付撫養(yǎng)費(fèi)了?
- 預(yù)見:探討近期分布式光伏的變化 每日熱文
- 美國得州等多地遭遇龍卷風(fēng),5000萬人受惡劣天氣威脅金十期貨6月16日訊,6月16日,據(jù)美國有線電視新聞網(wǎng)報(bào)道,美國多地遭遇龍卷風(fēng),大片地區(qū)有超過5000萬人受到惡劣天氣的威脅,可能會再次出現(xiàn)風(fēng)暴、冰雹、強(qiáng)風(fēng)和龍卷風(fēng)等惡劣天氣 天天訊息
- 芯??萍纪ㄟ^ISO 26262功能安全管理體系A(chǔ)SIL D認(rèn)證_當(dāng)前關(guān)注
- 激發(fā)國內(nèi)市場活力 二季度消費(fèi)市場有望保持平穩(wěn)增長態(tài)勢|當(dāng)前快訊
- 世界快看點(diǎn)丨618活動火熱進(jìn)行中!龍騰四海止盈通力科技超50%!
- 當(dāng)前短訊?。ň劢怪袊哔|(zhì)量發(fā)展)以僑為橋 泉州優(yōu)品“揚(yáng)帆出?!?/a>
- 西延高鐵馬坊隧道及北村隧道相繼貫通 天天快報(bào)
- 世界熱議:預(yù)計(jì)年內(nèi)上市 奇瑞TJ-1官方定名探索06
- 34.5億+15%溢價(jià)率!城建競得朝陽奶西29-315-1地塊_當(dāng)前報(bào)道
- “天擎”誕生記——高效制取綠氫 降低終端用氫成本!
- 硬核科技論|別被洗腦 雙電機(jī)有時(shí)候并非你所想 天天關(guān)注
- 當(dāng)前短訊!電小二SG 2000 Plus戶外電源亮相慕尼黑太陽能展會,支持光伏充電
- 天天觀速訊丨選華為,還是特斯拉,或者自研?車企們要面臨三選一了
- 我國成立綠色建筑全國重點(diǎn)實(shí)驗(yàn)室推動建筑業(yè)清潔低碳轉(zhuǎn)型|環(huán)球觀點(diǎn)
- “防溺水”應(yīng)急演練走進(jìn)鄭州水務(wù)集團(tuán)水源廠 環(huán)球快看點(diǎn)
- 財(cái)政部:1-5月全國稅收收入84774億元,同比增長17%_全球百事通
- 天津市路燈管理處組織開展達(dá)沃斯燈桿道旗宣傳布展_天天時(shí)快訊
- 局部大暴雨 安徽啟動暴雨Ⅳ級應(yīng)急響應(yīng)
- 世界關(guān)注:中國商業(yè)智能行業(yè)發(fā)展現(xiàn)狀分析2023
- Global licensing industry optimistic about Chinese market 今日熱聞
- 全球微速訊:平安人壽重慶分公司:關(guān)于理性消費(fèi)、合理借貸的提示
- 河南鄭州航空港組織開展“粽香傳情 愛在港區(qū)”主題黨員志愿服務(wù)活動
- 怎樣看病最能省錢?
- 華昌達(dá)副董事長突然失聯(lián) 或與第二大股東涉嫌合同詐騙相關(guān) 世界實(shí)時(shí)
- 五部門:截至4月末涉農(nóng)貸款余額53.16萬億元 同比增長16.4%
- 模擬輸入24位立體聲ADC(數(shù)模轉(zhuǎn)換器)CJC1808
- 天天通訊!“2022十大重慶經(jīng)濟(jì)年度創(chuàng)新人物”參評人|唐浩夫:以投資創(chuàng)造價(jià)值,為中國醫(yī)療產(chǎn)業(yè)升級貢獻(xiàn)力量
- 天天看熱訊:青島首批供地:14宗地?cái)埥?06億元 海信、中海、越秀落子
- 《雨世界》7月11日推出PS5和Xbox版 主機(jī)DLC同日發(fā)售|天天資訊
- 合盛硅業(yè): 朋友公司目前尚無有機(jī)硅期貨業(yè)務(wù),僅有工業(yè)硅期貨業(yè)務(wù) 當(dāng)前快報(bào)
- 盛會將至!第十三屆煙臺國際葡萄酒博覽會6月16日開幕|熱點(diǎn)評
- 昔日石山今披綠裝 重慶石漠化土地五年減逾440萬畝_新要聞
- 今日看點(diǎn):“微手術(shù)”避免“通天口” 青濱附院實(shí)現(xiàn)一次手術(shù)治療兩種疾病
- 環(huán)球快訊:拼多多如何擺脫“小玩意兒”
- 2023西安美術(shù)館6到7月展覽活動內(nèi)容
- 【在希望的田野上】小麥主產(chǎn)區(qū)多措并舉穩(wěn)產(chǎn)保豐
- 長興制藥將持有的長興恒力小額貸款有限公司5%股權(quán)以323.3萬轉(zhuǎn)讓給標(biāo)的公司股東韓玲玉 最新