首页 > 聚焦 > > 正文

世界今日报丨解剖屎山,寻觅黄金之第二弹

2023-05-02 22:45:58 来源:程序员客栈

大家好,我3y啊。由于去重逻辑重构了几次,好多股东直呼看不懂,于是我今天再安排一波对代码的解析吧。austin支持两种去重的类型:N分钟相同内容达到N次去重和一天内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);//运营总规则去重(一天内用户收到最多同一个渠道的消息次数)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);}});}

我猜想他的思路就是把构建去重参数和选择具体的去重服务给封装起来了,在最外层的代码看起来就很简洁了。后来又跟他聊了下,他的设计思路是这样的:考虑到以后会有其他规则的去重就把去重逻辑单独封装起来了,之后用策略模版的设计模式进行了重构,重构后的代码 模版不变,支持各种不同策略的去重,扩展性更高更强更简洁

确实牛逼。

我基于上面的思路微改了下入口,代码最终演变成这样:

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);}}}

到这,应该大多数人还能跟上吧?在讲具体的代码之前,我们先来简单看看去重功能的代码结构(这会对后面看代码有帮助)

去重的逻辑可以统一抽象为:在X时间段内达到了Y阈值,还记得我曾经说过:「去重」的本质:「业务Key」+「存储」。那么去重实现的步骤可以简单分为(我这边存储就用的Redis):

通过Key从Redis获取记录判断该Key在Redis的记录是否符合条件符合条件的则去重,不符合条件的则重新塞进Redis更新记录

为了方便调整去重的参数,我把X时间段和Y阈值都放到了配置里{"deduplication_10":{"num":1,"time":300},"deduplication_20":{"num":5}}。目前有两种去重的具体实现:

1、5分钟内相同用户如果收到相同的内容,则应该被过滤掉

2、一天内相同的用户如果已经收到某渠道内容5次,则应该被过滤掉

从配置中心拿到配置信息了以后,Builder就是根据这两种类型去构建出DeduplicationParam,就是以下代码:

DeduplicationParamdeduplicationParam=deduplicationHolder.selectBuilder(deduplicationType).build(deduplicationConfig,taskInfo);

Builder和DeduplicationService都用了类似的写法(在子类初始化的时候指定类型,在父类统一接收,放到Map里管理)

而统一管理着这些服务有个中心的地方,我把这取名为DeduplicationHolder

/***@authorhuskey*@date2022/1/18*/@ServicepublicclassDeduplicationHolder{privatefinalMapbuilderHolder=newHashMap<>(4);privatefinalMapserviceHolder=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);}}

前面提到的业务Key,是在AbstractDeduplicationService的子类下构建的:

而具体的去重逻辑实现则都在LimitService下,{一天内相同的用户如果已经收到某渠道内容5次}是在SimpleLimitService中处理使用mget和pipelineSetEX就完成了实现。而{5分钟内相同用户如果收到相同的内容}是在SlideWindowLimitService中处理,使用了lua脚本完成了实现。

LimitService的代码都来源于@caolongxiu的pull request,建议大家可以对比commit再学习一番:https://gitee.com/zhongfucheng/austin/pulls/19

1、频次去重采用普通的计数去重方法,限制的是每天发送的条数。

2、内容去重采用的是新开发的基于redis中zset的滑动窗口去重,可以做到严格控制单位时间内的频次。

3、redis使用lua脚本来保证原子性和减少网络io的损耗

4、redis的key增加前缀做到数据隔离(后期可能有动态更换去重方法的需求)

5、把具体限流去重方法从DeduplicationService抽取出来,DeduplicationService只需设置构造器注入时注入的AbstractLimitService(具体限流去重服务)类型即可动态更换去重的方法 6、使用雪花算法生成zset的唯一value,score使用的是当前的时间戳

针对滑动窗口去重,有会引申出新的问题:limit.lua的逻辑?为什么要移除时间窗口的之前的数据?为什么ARGV[4]参数要唯一?为什么要expire?

A: 使用滑动窗口可以保证N分钟达到N次进行去重。滑动窗口可以回顾下TCP的,也可以回顾下刷LeetCode时的一些题,那这为什么要移除,就不陌生了。

为什么ARGV[4]要唯一,具体可以看看zadd这条命令,我们只需要保证每次add进窗口内的成员是唯一的,那么就不会触发有更新的操作(我认为这样设计会更加简单些),而唯一Key用雪花算法比较方便。

为什么expire?,如果这个key只被调用一次。那就很有可能在redis内存常驻了,expire能避免这种情况。

推荐项目

最后再叨叨吧,很多人可能会发一段截图,跑来问我为什么要这样写,为什么要以这种方式实现,能不能以这种方式实现。这时候,我更想看到的是:你已经实现了第二种方式了,然后探讨你写的这种方案好不好,现有的代码差在哪里。

毕竟问问题很简单,我又不是客服,总不能没诚意的问题我都得一一回答吧。

如果想学Java项目的,我还是强烈推荐我的开源项目消息推送平台Austin,可以用作毕业设计,可以用作校招,可以看看生产环境是怎么推送消息的。

仓库地址(可点击阅读原文跳转):https://gitee.com/zhongfucheng/austin

我开通了股东服务内容,感兴趣可以点击下方看看,主要针对的是项目哟

VIP服务

标签:

世界今日报丨解剖屎山,寻觅黄金之第二弹

大家好,我3y啊。由于去重逻辑重构了几次,好多股东直呼看不懂,于是我今天再安排一波对代码的解析吧。aust

2023-05-02 22:45:58

新剧上映引争议,绝色美人演成“市井大姐”?

最近马伊琍被嘲得厉害。因出演笛安原著龙城三部曲(《西决》《东霓》《南音》)里像神话中的水妖般美丽危险

2023-05-02 21:28:13

彩虹岛online手游(彩虹岛online)-环球快播报

1、加血的是法师:强大的攻击力与脆弱的生命是所有人对法师的印象,这是一个可以操纵威力强大的魔法进行攻

2023-05-02 20:04:46

劳动节学种植技巧,温州医科大学开设“田野课堂”-环球今日讯

“大家都知道向日葵叶大,需要大量水份,但是目前阶段,泥土不宜过湿,要让它先湿后干,干湿交替,因为...

2023-05-02 19:15:48

最新快讯!哈登:我不是打不出侵略性得分 只是我的球队角色无需我这么干

今日NBA季后赛,76人在客场以119-115击败凯尔特人,系列赛比分来到1-0。赛后,哈登接受了记者采访。谈到自

2023-05-02 18:15:53

罕见!中国物种红色名录蝴蝶红灰蝶现身武汉|每日播报

湖北省内的生物多样性本底调查又有新发现。近日,记者了解到,在武汉东湖湿地内,调查人员发现了一种中国物

2023-05-02 17:05:03

2023年全民数字素养与技能提升月活动启动_环球速看

新华社福州4月27日电(记者王思北、董建国)以“数字赋能全民共享”为主题,2023年全民数字素养与技能提...

2023-05-02 16:08:57

穿越之一受多攻小说文_穿越之一受多攻小说-天天看点

1、天神右翼暗夜沉沦诱罪父子年下NP总受凤霸天下欲满杏林怎见浮生不若梦十二妖精污黑六夫皆妖十夫临门四人

2023-05-02 15:53:10

当前短讯!“五一”出游,小心它!医院已收治多名患者

五一假期,正是出去游玩的好时节。长沙市第四医院中毒门诊专家提醒,近一周以来,医院中毒门诊已连续收治多

2023-05-02 14:49:10

第一财经秦俭最新评论_第一财经秦俭博客 快看

1、昨天是节前要转出资金最后的卖股时间,今天再卖出资金只能到节后才能到账,所以该出的基本都出了,今天

2023-05-02 13:53:52

抗击通胀还是保护银行?美联储深陷两难困境 新动态

抗击通胀还是保护银行?美联储深陷两难困境,加息,美联储,银行业,货币政策

2023-05-02 12:40:07

房产信息:将汉普顿中尖尖的木屋变成周末度假胜地-世界今热点

随着时代的变迁,随着城市的改建,一棵棵苍天大树逐渐演变为一幢幢高楼大厦,住上高档次的新房子已经不是什

2023-05-02 11:49:02

全球今热点:“新毒株”引发“眼药热” 本土企业创新研发面临挑战

近日多地网友声称“二阳”,五一小长假到来,人员流动增加,“二次感染”相关话题冲上热搜。新冠新毒株X...

2023-05-02 10:54:41

思远蜂业直播 思远-世界观热点

今天来聊聊关于思远蜂业直播,思远的文章,现在就为大家来简单介绍下思远蜂业直播,思远,希望对各位小伙伴

2023-05-02 10:04:38

多图直击|张家口崇礼:812名铁人接受考验 “五一”期间崇礼区举办崇礼国际铁人两项挑战赛等多项赛事活动

5月1日,2023X-BIONIC崇礼国际铁人两项挑战赛在张家口市崇礼区鸣枪开赛。X-BIONIC崇礼铁人两项挑战赛共设立

2023-05-02 09:22:37

每日视点!如何在word中打分数_怎么在word中快速打出分数线

欢迎观看本篇文章,小勉来为大家解答以上问题。如何在word中打分数,怎么在word中快速打出分数线很多人还不

2023-05-02 08:47:51

环球讯息:空调变频和定频的区别_格力空调定频和变频的区别

1、变频空调和定频空调的区别和各自的优点,根据他们的这些特性来选择。2、具体来说变频空调和定频空调的区

2023-05-02 07:42:01

简讯:同比增长近2.8倍 极氪四月交付新车8101辆 稳步增长!

5月1日,除了蔚来、理想、小鹏、岚图、哪吒以外,极氪汽车也公布了自己的最新单月交付成绩。据悉,在2023年

2023-05-02 06:03:53

科创板生物医药业绩透视:上海谊众、艾力斯商业化出圈 多数亏损企业研发持续烧钱

《科创板日报》5月1日讯(记者朱洁琰)财报季落下帷幕,科创板生物医药2022年商业化成绩单揭榜。《科创板日

2023-05-02 04:58:49

全球快讯:地下城与勇士回归活动_回归勇士传家宝怎么弄

1、暗月马戏团又来啦!6 1版本所新增的暗月马戏团竞速赛方兴未艾,在6 2版本中,希格斯·暗月又为玩家...

2023-05-02 02:05:50

美国最新数据分析:美国4月Markit制造业PMI终值改善50.2_天天观点

5月1日21:45,美国最新数据分析,美国4月Markit制造业PMI终值前值50 4,公布值50 2。美国最新数据分析公布

2023-05-01 23:17:32

模板脚手架专业资质办理_模板脚手架专业承包资质标准 最新消息

1、当前,我国以组合钢模板为主的格局已经打破,已逐步转变为多种模板并存的格局,组合钢模板的应用量正在

2023-05-01 21:51:19

营造优美环境 服务群众需求——赤壁市羊楼洞文化旅游区“五一”侧记-天天热文

营造优美环境服务群众需求——赤壁市羊楼洞文化旅游区“五一”侧记---自“五一”劳动节假期以来,赤壁市...

2023-05-01 20:59:04

环球今头条!群雄混战,《长空之王》能稳居第一,离不开这几个看点

紧随其后的是《人生路不熟》和《这么多年》,一部是喜剧片,一部是爱情片,淘票票分别给出了9 4和8 8的评分

2023-05-01 19:37:00

陈粤明:救死扶伤践初心 全球热点

陈粤明在为患者检查身体。2004年,广东医科大学毕业的陈粤明在湛江中心人民医院工作至今,他牢记救死扶伤的

2023-05-01 18:56:19

世界信息:羊肚菌的营养价值

天天视点!房贷利率进入“3”时代 6城实施多孩家庭住房优惠政策

众多球员惊叹库里抢七战砍50分 当前独家

环球消息!琼斯:下赛季不再回归吉林 目标是签一支争冠球队

全球播报:龋齿严重程度图解_龋齿

《百鸟朝凤》五一首演 上海音乐厅打造沉浸式小剧场-环球新要闻

毕业赠言六年级作文400字_六年级作文400字

成龙女儿疑感情生变,同性妻“对她嗤之以鼻”画面曝 每日消息

环球速讯:罗斯科教堂:艺术的沉思净地

每日快讯!人物志 | 李大钊

梦见别人请我吃饭_梦见别人请我吃饭暗示什么

杀之恋_关于杀之恋的介绍_世界热头条

3199小游戏_8399小游戏

防流感股票排名,第四季度毛利润前十名 每日快看

安禄山怎么死的历史上_安禄山怎么死的

《长空之王》上映第3天实现票房逆跌 累计票房2.73亿_世界热议

word文档打字吃字_为什么文档打字后面的字会消失|天天最资讯

出去游玩被人打了,事后报警了,后来对方想要私了,我就取消报警了

亚历山大兹维列夫现在动力爆棚决心尽快拿下大满贯冠军头衔

【环球报资讯】再生水稻插秧忙

乡创“新”力量 |95后海归小伙创业养牡蛎 带动家乡村民就业增收-微动态

交纳养老保险时间多久?个人如何买养老保险?_讯息

环球关注:跨京广铁路部分建设全部完成,白云站综合枢纽距离年底开通又近一步

世界看点:火影忍者:血继限界中与水属性查克拉相关的6种遁术,威力很可观

世界热头条丨暴雪CEO呼吁更多公司合并以便与腾讯竞争:否则全球市场运营更具挑战

x 广告
x 广告

Copyright @  2015-2023 港澳家电网版权所有  备案号: 京ICP备2023022245号-31   联系邮箱:435 226 40 @qq.com