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