首页 >要闻 > > 正文

【天天新要闻】解剖屎山,寻觅黄金之第二弹

程序员客栈 2023-04-23 05:40:29

大家好,我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服务

上一篇:全球信息:明日方舟愚人号的UI再次被槽 去年鹰角就用后续的活动承认了错误 下一篇:最后一页
x
推荐阅读

【天天新要闻】解剖屎山,寻觅黄金之第二弹

2023-04-23

全球信息:明日方舟愚人号的UI再次被槽 去年鹰角就用后续的活动承认了错误

2023-04-23

就在明天傍晚!

2023-04-23

我的galgame记录——长夜终将结束,黎明就在眼前_焦点资讯

2023-04-23

即时焦点:高德李新华:巡游出租车不能变成纯网约车 老师傅的社会出行保障价值依然重要

2023-04-23

今日爱迪尔珠宝百度百科_爱迪尔珠宝怎么样

2023-04-23

重点聚焦!雅诗兰黛护肤步骤_雅诗兰黛护肤步骤是什么

2023-04-23

计算机网络技术主要学什么? 计算机网络技术到底学的是什么

2023-04-23

卫校是什么学校_有什么专业

2023-04-23

台球桌标准尺寸是几寸_请问 台球桌的标准尺寸是多少 美式和斯诺克的

2023-04-22

【全球快播报】山药蒸多久就可以蒸熟了 山药煮多久几分钟能熟

2023-04-22

[快讯]香雪制药公布年报-精彩看点

2023-04-22

【扬子专栏:KPL最前沿】临阵换将激发新潜力 南京Hero零封长沙TES提前锁定季后赛 世界播报

2023-04-22

文明的坐标|福建土楼“观赏天地方圆” 速看料

2023-04-22

心理猎人_微速讯

2023-04-22

成立8个教育集团,儋州推进集团化办学!附学校名单-热点评

2023-04-22

基期是什么意思通俗点_基期是什么意思|当前快讯

2023-04-22

上行文应当标注签发人姓名_公文写作里只有上行文在首页需要标注签发人 为什么下行文不需要

2023-04-22

“壮族三月三”来梧州,哪些打卡地是你和亲友不能错过的?

2023-04-22

当前通讯!2020年湖北二建证书什么时候办理_湖北二建什么时候拿证

2023-04-22

世界最新:对付中国,美国要搞个“90天冲刺”

2023-04-22

世界讯息:南开大学八里台校区附近停车_南开大学八里台校区

2023-04-22

每日速讯:社评:中菲要合力拔出美国钉进的楔子

2023-04-22

125路公交车路线查询 25路公交车路线查询 全球速看料

2023-04-22

2023“一带一路”年度汉字9个候选字揭晓

2023-04-22

每日简讯:怎样跳皮筋_有什么玩法

2023-04-22

【报资讯】哲思 | 修为高的人,都懂得养这三种贵气

2023-04-22

全球视讯!V观财报|长城汽车一季度净利降近九成

2023-04-22

天天短讯!如何在杯子里做胡萝卜蛋糕

2023-04-22

热点在线丨魅力学科 | 观生命之奇 绽模型之美——理综魅力月生物学专场

2023-04-22

指甲有竖纹,就是不健康?有这7个变化的人要当心|全球快播

2023-04-22

环球讯息:10-9!斯诺克世锦赛再爆冷门,中国新星淘汰世界冠军,大满贯出局

2023-04-22

围攻光明顶的六大门派是哪几个 六大门派围攻光明顶是哪六门派掌门人是谁-环球快看点

2023-04-22

图知道|保护地球,青年接力 每日速看

2023-04-22

宁夏持续降雨降雪

2023-04-22

微头条丨希罗接受右手修复手术至少缺席6周 字母哥未参加球队训练G3出战成疑

2023-04-22

当前最新:曼城甚至可接受战平枪手 欧冠VS皇马前榜首易主?

2023-04-22

燃油宝到底有没有效果知乎_燃油宝到底有没有效果

2023-04-22

智能计算协同优化算法及应用_对于智能计算协同优化算法及应用简单介绍

2023-04-22

快报:注意!上班时间有变

2023-04-22

蓝厂两款折叠屏新机发布,颜值你心动了吗? 环球讯息

2023-04-22

新宁:把准市场脉搏 青山变成金山

2023-04-22

广州黄埔:出台“赛龙夺锦”十条,助力项目快批快建快投产|当前动态

2023-04-22

今年“五一”假期前后,泉城夜宴·明湖秀正式开演 环球速读

2023-04-22

全球快讯:格科微:4月21日融券卖出45.35万股,融资融券余额4.48亿元

2023-04-22

世界微动态丨中国人保总裁王廷科出任公司党委书记

2023-04-22

美股年内最强新股出炉!这家中概股上市首日大涨1150%

2023-04-22

上交所:将依规加快推进*ST紫晶 *ST泽达的退市流程

2023-04-22

为什么吃的不多还是胖的快_为什么吃的不多还是胖 环球视讯

2023-04-22

每日快讯!四川省阿坝藏族羌族自治州若尔盖县2023-04-21 16:38发布雷电黄色预警

2023-04-22

金源电气2022年亏损1158.70万 同比亏损减少 多个项目未能按时交付

2023-04-22

5个工作日到账!徐汇企业获上海普惠金融顾问综合服务平台首单贷款_每日头条

2023-04-22

天知神知子知我知这句话的意思是_天知 神知 我知 子知 何谓无知 的意思

2023-04-22

通源石油2022年净利2227.93万同比增长52.75% 董事长张国桉薪酬102.79万 天天时讯

2023-04-22

乳腺癌“救命药”瑞宁得一药难求 原价300元最高已涨价至5000元

2023-04-22

[年报]立昂微(605358):东方证券承销保荐有限公司关于杭州立昂微电子股份有限公司2022年持续督导年度报告书

2023-04-22

人工智能又“倒车接人”?冠军收益逆势创纪录!第九期比赛周六开始报名,快来角逐大奖!

2023-04-22

环球热推荐:ChatGPT之父称巨型人工智能模型时代已结束

2023-04-22

中技能源2022年净利244.04万同比下滑74.57% 计提坏账准备增加_全球简讯

2023-04-22

成功组织27个集采品目,武汉市框架协议采购多层级、多类型全面铺开|天天速递

2023-04-22

红糖与甘蔗糖的区分?_天天时讯

2023-04-22

全面二孩政策的利弊(二孩政策的利弊)

2023-04-22

重磅!拜登最新发声,市场巨震,影响多大?权威专家:A股不必反应过激

2023-04-22

焦点消息!股票行情快报:华控赛格(000068)4月21日主力资金净卖出93.06万元

2023-04-22

AI动捕研究师:AI让动捕人人可及,一部手机让你在元宇宙动起来

2023-04-22

环球动态:部落冲突八本阵型视频_部落冲突八本阵型高清

2023-04-22

股票行情快报:苑东生物(688513)4月21日主力资金净买入217.34万元|新要闻

2023-04-22

世界资讯:iphone定时关机怎么设置方法(电脑定时关机怎么取消)

2023-04-22

即时:侃财丨什么是真爱粉?

2023-04-22

今日热搜:老人无牌无证驾驶老头乐从河南跑到江苏 还要周游全国

2023-04-21

每日热讯!央行谈银行存款“降息”:市场化环境下的正常现象

2023-04-21

必和必拓(BHP.US)维持铁矿石生产指引,下调铜和镍产量预期

2023-04-21

守住破板,后市翻番_世界热文

2023-04-21

南非能用天然气和绿色氢气取代煤炭吗? 环球聚看点

2023-04-21

小米手机开机显示fastboot什么意思_手机一直显示已进去fastboot 为什么 怎么办|天天观点

2023-04-21

智能用电产业联盟_对于智能用电产业联盟简单介绍

2023-04-21

路口左拐的遇到直行的,互不相让结果悲剧了——-全球今热点

2023-04-21

天天资讯:劳动纠纷必须先仲裁后诉讼吗

2023-04-21

每日速读!糖业股震荡走高

2023-04-21

光韵达股东户数下降1.88%,户均持股7.83万元

2023-04-21

物业丨招商积余:一季度实现归母净利润1.85亿元 同比增长27.24%-环球微速讯

2023-04-21

晨鸣纸业: 关于股东股份质押业务续作的公告

2023-04-21

今日聚焦!中孚实业大宗交易成交750.08万股 成交额2602.78万元

2023-04-21

环球快资讯丨文员招聘要求和条件_文员招聘要求

2023-04-21

海南发布“十佳”旅游主题系列名录 天天速看

2023-04-21

焦点热门:万方和知网查重结果一样吗(万方和知网查重出来的结果大么)

2023-04-21

信息:国义招标:营销网点布局有利于公司整合全国资源、提高资源配置效率,优势互补,降低整体成本、实现配置效益

2023-04-21

第四届中国未来景区大会:数字化提升旅游场景

2023-04-21

非法捕捞野生螺蛳1000余斤 被查处

2023-04-21

Python面向对象编程-魔术方法-__call__和__getattr__方法_即时

2023-04-21

彭州市气象台发布大风蓝色预警信号【IV级/一般】 最新资讯

2023-04-21

我市入选两项!省第二批基础教育教师培训出彩项目入选名单公示

2023-04-21

五一国内游预订全线超2019年

2023-04-21

《长沙夜生活》陈可辛领衔主创打卡“长沙不眠夜” 全球新消息

2023-04-21

边陲小城瑞丽的复苏时刻

2023-04-21

硚口宝丰街道社区基金成立

2023-04-21

高速冷冻离心机_关于高速冷冻离心机简述

2023-04-21

曹文轩的作文课:请学会凝视这个世界

2023-04-21

【世界独家】安徽省人民币各项贷款增速连续四个月领跑全国

2023-04-21

提醒!4月25日起,北京这些公交线路调整营业时间

2023-04-21