解剖屎山,尋覓黃金之第二彈
大家好,我3y啊。由于去重邏輯重構(gòu)了幾次,好多股東直呼看不懂,于是我今天再安排一波對代碼的解析吧。austin支持兩種去重的類型:N分鐘相同內(nèi)容達到N次去重和一天內(nèi)N次相同渠道頻次去重。
在最開始,我的第一版實現(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);//運營總規(guī)則去重(一天內(nèi)用戶收到最多同一個渠道的消息次數(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);}
【資料圖】
那時候很簡單,基本主體邏輯都寫在這個入口上了,應(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è)計思路是這樣的:考慮到以后會有其他規(guī)則的去重就把去重邏輯單獨封裝起來了,之后用策略模版的設(shè)計模式進行了重構(gòu),重構(gòu)后的代碼 模版不變,支持各種不同策略的去重,擴展性更高更強更簡潔
確實牛逼。
我基于上面的思路微改了下入口,代碼最終演變成這樣:
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時間段內(nèi)達到了Y閾值,還記得我曾經(jīng)說過:「去重」的本質(zhì):「業(yè)務(wù)Key」+「存儲」。那么去重實現(xiàn)的步驟可以簡單分為(我這邊存儲就用的Redis):
通過Key從Redis獲取記錄判斷該Key在Redis的記錄是否符合條件符合條件的則去重,不符合條件的則重新塞進Redis更新記錄為了方便調(diào)整去重的參數(shù),我把X時間段和Y閾值都放到了配置里{"deduplication_10":{"num":1,"time":300},"deduplication_20":{"num":5}}。目前有兩種去重的具體實現(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都用了類似的寫法(在子類初始化的時候指定類型,在父類統(tǒng)一接收,放到Map里管理)
而統(tǒng)一管理著這些服務(wù)有個中心的地方,我把這取名為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)建的:
而具體的去重邏輯實現(xiàn)則都在LimitService下,{一天內(nèi)相同的用戶如果已經(jīng)收到某渠道內(nèi)容5次}是在SimpleLimitService中處理使用mget和pipelineSetEX就完成了實現(xiàn)。而{5分鐘內(nèi)相同用戶如果收到相同的內(nèi)容}是在SlideWindowLimitService中處理,使用了lua腳本完成了實現(xiàn)。
LimitService的代碼都來源于@caolongxiu的pull request,建議大家可以對比commit再學習一番:https://gitee.com/zhongfucheng/austin/pulls/19
1、頻次去重采用普通的計數(shù)去重方法,限制的是每天發(fā)送的條數(shù)。
2、內(nèi)容去重采用的是新開發(fā)的基于redis中zset的滑動窗口去重,可以做到嚴格控制單位時間內(nèi)的頻次。
3、redis使用lua腳本來保證原子性和減少網(wǎng)絡(luò)io的損耗
4、redis的key增加前綴做到數(shù)據(jù)隔離(后期可能有動態(tài)更換去重方法的需求)
5、把具體限流去重方法從DeduplicationService抽取出來,DeduplicationService只需設(shè)置構(gòu)造器注入時注入的AbstractLimitService(具體限流去重服務(wù))類型即可動態(tài)更換去重的方法 6、使用雪花算法生成zset的唯一value,score使用的是當前的時間戳
針對滑動窗口去重,有會引申出新的問題:limit.lua的邏輯?為什么要移除時間窗口的之前的數(shù)據(jù)?為什么ARGV[4]參數(shù)要唯一?為什么要expire?
A: 使用滑動窗口可以保證N分鐘達到N次進行去重?;瑒哟翱诳梢曰仡櫹耇CP的,也可以回顧下刷LeetCode時的一些題,那這為什么要移除,就不陌生了。
為什么ARGV[4]要唯一,具體可以看看zadd這條命令,我們只需要保證每次add進窗口內(nèi)的成員是唯一的,那么就不會觸發(fā)有更新的操作(我認為這樣設(shè)計會更加簡單些),而唯一Key用雪花算法比較方便。
為什么expire?,如果這個key只被調(diào)用一次。那就很有可能在redis內(nèi)存常駐了,expire能避免這種情況。
推薦項目最后再叨叨吧,很多人可能會發(fā)一段截圖,跑來問我為什么要這樣寫,為什么要以這種方式實現(xiàn),能不能以這種方式實現(xiàn)。這時候,我更想看到的是:你已經(jīng)實現(xiàn)了第二種方式了,然后探討你寫的這種方案好不好,現(xiàn)有的代碼差在哪里。
畢竟問問題很簡單,我又不是客服,總不能沒誠意的問題我都得一一回答吧。
如果想學Java項目的,我還是強烈推薦我的開源項目消息推送平臺Austin,可以用作畢業(yè)設(shè)計,可以用作校招,可以看看生產(chǎn)環(huán)境是怎么推送消息的。
倉庫地址(可點擊閱讀原文跳轉(zhuǎn)):https://gitee.com/zhongfucheng/austin
我開通了股東服務(wù)內(nèi)容,感興趣可以點擊下方看看,主要針對的是項目喲
VIP服務(wù)
標簽:
搶先讀
- 湖北發(fā)布災害風險提示:雷暴大風天氣來了,非必要不出行-每日資訊
- 熱點在線丨遼寧省藥品監(jiān)督管理局注銷1家公司《藥品營許可證》
- 環(huán)球信息:股東知情權(quán)應(yīng)該如何行使
- 世界微頭條丨中國首家麗思卡爾頓隱世酒店開業(yè)
- 甘州區(qū)上秦鎮(zhèn)中心學校舉辦第四屆小學生詩詞大會
- 為何一到夏季,結(jié)石卻多發(fā)?可能存在這3點因素,勸你要避避開
- 永寧縣新就業(yè)群體服務(wù)季正式啟動
- 房屋拆遷糾紛訴訟時效是多久
- 鍥介檯娌逛環(huán)鏂欑粓緇撳懆綰夸簩榪炶穼錛屼駭娌瑰浗鏈熷緟涓浗涔伴渶鎵樺競
- 湖紅之源:新化紅茶“挑擔茶葉上北京”_環(huán)球精選
- 貴陽郵政:打通大動脈 疏通微循環(huán)
- 金融街完成發(fā)行10億元公司債券,票面利率為3.14% 焦點速讀
- 當前速讀:宸展光電:聘任徐可欣擔任公司董事會秘書
- 環(huán)球頭條:2023上海端午節(jié)游玩推薦景點有哪些?
- 信用卡現(xiàn)金轉(zhuǎn)出有利息嗎 怎么提前還|每日信息
- 安陽紅旗渠機場飛行程序?qū)嵉仳炞C試飛成功
- 【環(huán)球聚看點】武磊梅開二度,國足4-0勝緬甸!
- 解剖屎山,尋覓黃金之第二彈
- 天天看熱訊:國產(chǎn)GPU的第一縷光:自研架構(gòu)“天狼星”在京亮相
- 2023年電子標簽產(chǎn)業(yè)深度調(diào)研及發(fā)展趨勢預測 今日報
- 個人原因離職申請書范文 全球播資訊
- 新烽光電啟動IPO輔導,解決方案應(yīng)用于智慧排水、智慧供水等_天天熱點評
- 上汽大眾、上通五菱回暖緩慢,誰來緩解上汽集團的產(chǎn)銷焦慮? 環(huán)球訊息
- 【天天時快訊】股份公司和有限公司的區(qū)別?
- 天天精選!大運會火炬手姜志強:將大運精神延續(xù)至賽場外,助推數(shù)字經(jīng)濟發(fā)展
- 專題講座連連看 揚州航務(wù)中心第二期揚帆講堂開講啦
- 2023粵港澳車展:極狐阿爾法S/T森林版上市 售價18.58萬元起
- 谷歌為你準備了一個秘密的片魂復活節(jié)彩蛋 天天新要聞
- 京東白條,螞蟻花唄本質(zhì)就是信用卡,更方便,自從有了這兩樣,我信用卡都很少用了-視焦點訊
- 勝利監(jiān)理(836665):擬10派0.6元,共派現(xiàn)1749.87萬元_世界新視野
- 世界觀天下!云從科技投資算力芯片企業(yè)奕斯偉計算,打通大模型生態(tài)閉環(huán)
- 16日北京將迎本輪高溫峰值 最高氣溫預計39℃
- 資訊推薦:汽車下鄉(xiāng)政策回顧:新能源汽車市場潛力巨大,代步型純電+平價混動將成為主力產(chǎn)品
- 烏當區(qū)2023幼升小入學報名指南(對象+時間+入口+學區(qū)劃片)_天天快資訊
- 杭州地鐵公安公示“偷拍案”處罰信息,律師:有“羞辱性懲罰”和侵犯隱私之嫌_世界今頭條
- 世界快訊:甘州區(qū)市場監(jiān)管局西街市場監(jiān)管所開展早夜市計量器具專項檢查
- 公司邀請函
- 世界動態(tài):停息掛賬還收利息不?停息掛賬之前的利息還需要嗎?|天天速看
- 織嘜機(織嘜) 環(huán)球快資訊
- 鄧清清 抖音(鄧清清) 全球訊息
- 增設(shè)電梯陷“拉鋸戰(zhàn)”:電梯選址距自家僅1米,一樓業(yè)主不同意被起訴-天天觀天下
- 梅西中國行,有哪些品牌搭上了“順風車”?
- 世界播報:北京亦莊搭平臺助企業(yè)共赴雙碳之約
- 榮盛發(fā)展為5家全資子公司融資提供合計不超10.7億元擔保 環(huán)球今日訊
- 環(huán)球要聞:重癥肌無力關(guān)愛日|全身漸漸無力,最終喚起心靈之力
- 世界快看點丨“流動的咨詢臺”——崇明海事局開展“安全宣傳咨詢?nèi)铡被顒?/a>
- 今日熱聞!河南:強化監(jiān)督執(zhí)紀 筑牢南水北調(diào)工程安全“堤壩”
- 廣東最新平均工資出爐!這些行業(yè)仍“吃香”→_天天新消息
- 每日視訊:2023南陽端午節(jié)游玩景點推薦
- 每日速看!6月FOMC會議點評:“留有余地”的暫停加息
- 600余場活動!30余萬個崗位!重慶市“百日千萬招聘專項行動”來了
- 天天速遞!強觀察|這些返回艙里的“神器”為航天員保駕護航
- 跨界布局儲能領(lǐng)域!家電龍頭獲外資連買7日 當前播報
- 天馬行空揮灑創(chuàng)意!《狂想樂園》今日上市! 世界速訊
- 高爾夫全錦賽:上海男隊和陜西女隊繼續(xù)占據(jù)榜首
- 書從文:青海發(fā)生山體滑坡(已致5死2失聯(lián))
- 中煤國際工程集團武漢設(shè)計研究院(關(guān)于中煤國際工程集團武漢設(shè)計研究院的基本詳情介紹)|全球快消息
- word里怎么打鋼筋等級符號(鋼筋等級符號) 新消息
- 石嘴山市氣象臺發(fā)布大風藍色預警【IV級/一般】【2023-06-16】
- 司法重拳嚴懲性侵未成年人犯罪
- 陜西寶雞:暖心服務(wù)助力小麥歸倉-天天頭條
- (聚焦中國高質(zhì)量發(fā)展)以僑為橋 泉州優(yōu)品“揚帆出?!?天天新資訊
- 北京朝陽區(qū)“閱讀大運河”系列主題活動啟幕 世界實時
- 發(fā)改委:研究部署加強居民增收工作 各地要加大穩(wěn)就業(yè)工作力度-即時看
- 金融如何賦能“天府糧倉”建設(shè)?崇州這場發(fā)布會給出答案_觀焦點
- 本周全國碳市場碳排放配額總成交額突破2700萬元_全球即時
- “云”上逛房,福利多多,2023齊魯(濟南)夏季房展匯盛大啟動-熱門看點
- 天天看點:讓安全走進社區(qū)!中原區(qū)首家“社區(qū)警校”開課啦
- 哈佛醫(yī)學院丑聞曝光!太平間管理員倒賣遺體,6 人已被逮捕 天天速訊
- 又有券商被監(jiān)管談話!-最新資訊
- 沿江高鐵武宜段步入“四電”施工階段 環(huán)球快報
- 華商雙翼平衡混合基金增設(shè)C份額
- 神州播報丨北京警方通報“球迷沖入球場擁抱梅西”事件:已行拘!12個月內(nèi)不得進體育場館看同類比賽
- 帶你全面提升工作效率:B端設(shè)計規(guī)范攻略(三)
- 【世界新視野】南陽宛城區(qū):“四美庭院”扮靚城市顏值
- 谷歌&凱度:2023年中國全球化品牌50強 比亞迪進入前十
- 世界今日訊!【透視】美知名媒體人稱“世界上其他國家對中國的看法和美國不同”引發(fā)網(wǎng)友共鳴
- 市紀委監(jiān)委下發(fā)通知嚴禁黨員干部、公職人員違規(guī)操辦“學子宴”“謝師宴” 天天熱聞
- 當前熱文:猝不及防!西安又一本土房企破產(chǎn),買房人要警惕!
- 民航局:預計今年暑運每日有近195萬旅客通過航空出行-訊息
- 福州一商店隨便賣紅牛被查:沒有保健品售賣許可證_新資訊
- 批了!再添一所九年一貫制學校_全球動態(tài)
- 《射雕》演員太坎坷,孤獨離世、酒店猝死、開煤氣自殺,令人惋惜-速看料
- 6月16日內(nèi)蒙時泰液化天然氣價格動態(tài) 環(huán)球速讀
- 速看:sony(lt26ii)
- 性價比神卡!盈通RX 6600顯卡降至1399元:8GB顯存
- 天天觀察:諾安基金韓冬燕在管產(chǎn)品近1年業(yè)績居同類前1%
- 環(huán)球聚焦:華爾街大銀行裁員人數(shù)將超過1.1萬人
- 俄羅斯經(jīng)濟學家:美國借債“成癮”將危及全球經(jīng)濟復蘇
- 貴陽市2023年學前教育宣傳月宣講活動在清鎮(zhèn)舉行_世界熱聞
- 全球速訊:天天速遞!信用卡停息掛賬后逾期多久會被起訴?網(wǎng)貸逾期了暫時還不上怎么辦?
- 通訊!夏夜和夜宵是絕配!餐飲消費催熱“夏日夜經(jīng)濟”
- 全球熱點!端午節(jié)臨近 重慶手工現(xiàn)包粽子受熱捧
- 下載音樂到U盤怎么下載mp3格式 下載音樂到u盤怎么下載 熱點在線
- 葡萄酒怎做的?(葡萄酒怎么做的步驟) 微資訊
- 速看:2023樂華88度溫泉樂園端午夜場特惠
- 土拍丨蘇系房企成功搖號進京 保利擊退石景山區(qū)“老地主”
- 韋伯以學術(shù)為志業(yè)的演講基調(diào)是(韋伯)
- 《萌探》仙俠特輯,娜扎最美,劉令姿最敢,謝娜沾了趙麗穎的光_焦點速遞
- 迎峰度夏又至 中國統(tǒng)調(diào)電廠存煤達歷史新高