大家好,我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);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);}}
前面提到的业务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服务
关键词:
2023年湖南高考缴费成功后可以退还吗?什么时候截止缴费?湖南省2023年普通高等学校招生考试(含普通高中学业水平选择性考试和普通高等学校对
2023湖南高考报名人数达68万?今年湖南高考报名人数达68万!4月23日下午,省教育厅召开2023年全省教育考试招生工作会议,要求加强考试招生治
教师资格网显示网报待确认是提交资料还没审核吗?所有申请人在中国教师资格网上完成报名后的状态均为网报待确认,申请人在长沙政务服务网提
郑州小学生有以下情形可以转学吗?1、入学未满一学期的(转出省外的除外);2、进入毕业年级的;3、国际班转入普通班的;4、拟转入学校与转出学校
一个人一年最多可以考几次普通话?一个人一年最多可以考三次普通话。根据国家语委办的文件规定,报名参加普通话测试的人员,必须在前5个月内未
郑州2023教资复核结果什么时间统一反馈?5月8日统一反馈复核结果。复核成绩无误的考生不再予以反馈,成绩有误的考生将电话通知考生本人。中
2023郑州教师资格认定体检价格公布了吗?郑州市高中、中专及各县(区、市)初中、小学、幼儿园教师资格认定体检费用和规定详见郑州市高级中学
北京市西城区能能办理外省转学吗?北京市西城区初二能办理外省转学的呢,根据北京市西城区中学的管理规定,外省的是可以办理转学的哈,但是
1、红烧牛肉 红烧牛肉 原料 牛肉500克,味精2克,胡椒粉、八
1、按照国家的劳动法,你们是有假放的。2、但是有一些地方还不能放,特
【美国亚裔高考近满分被六大名校拒绝】据福克斯新闻网当地时间6月8日报
演讲中,杨立昆再次强调人工智能是可控的,他表示,“恐惧是由对潜在负
湖南日报6月9日讯(全媒体记者孙敏坚)9日上午,由中国电子信息产业集
大家好,我3y啊。由于去重逻辑重构了几次,好多股东直呼看不懂,于是我
1、抚恤金按国家相关规定:1 抚恤金不纳税。2、2 抚恤金不计个人收入 3
今起,海口碧海大道部分路段限时交通管控为进一步优化海口市白沙门区域
跟着总书记传承发展中华优秀传统文化
今天小红来为大家带来的是鼠茅草种植方法,鼠茅草,让我们一起往下看看
1、武艺有女朋友了。2、你们知道么? 我知道,你们死活也不相信武艺
1、原形是be点三人称单数是iswas复数或第二人称是arewere第一人称是am
在深圳光明文化艺术中心分会场,借助文博会平台,运营管理团队和赖声川
我俩打架斗殴,他导致我左下巴破洞,缝3针 左脸划伤臃肿
1、你好,一般来说每个学校都有自己的相关制度。2、一、开展小学心理健
1、上机动车环保网,输入车型型号(注意不是车架号)、发动机型号、都能
撬动社会资本面向未来孕育创新力合肥利用投资的扶持、引导作用,吸引产
炎炎夏日,雪糕、冰淇淋开始进入销售旺季。去年,由于价格过高,“雪糕
广东工业设计城:创新设计赋能制造业,推动中国制造扬帆出海。
1、体制与机制是较易混淆的一对词语。2、按照《辞海》的解释,“体制”
直播吧6月10日讯近日,前NBA球员阿里纳斯在《Gil & 039;sArena》节目中谈到
5种花“不怕冷”,初冬不停开花,五颜六色,漂亮清新,小盆也能养!花
2023高考志愿填报指南:平行志愿、顺序志愿、技巧、新增专业。
1、你说的是什么青铜治疗,黄金治疗试炼吗?在昆莱山右上角的白虎寺,
直播吧6月10日讯雷吉纳俱乐部官方消息,内斯塔出任球队主帅。雷吉纳上
当然,对于事事都想争第一的C罗来说,昔日好友本泽马的到来,并没有夺
这是两人首度在大满贯赛事中交手,人们对于这场对决充满期待。阿尔卡拉
1、最简单的就是在榨汁机榨。2、2、将新鲜黄瓜一条洗净,放在器皿里捣
在线选铺服务推出后,旅客在12306网站购买试点车次卧铺车票,可在线自
【港澳台专线】新台两地自媒体人:用镜头架起两岸交流“心桥”中新
(财经)中国—匈牙利企业贸易对接会在布达佩斯举行,中国,布达佩斯,贸
1、途家网O2O模式全面整合了线上、线、线下资源和服务旅游地动产增值服
AMD宣布,AMD超威卓越平台已经全面登陆中国台式机市场,顶级系统集成商
众多全球跨国公司高管近日接连开启访华行程,引发密切关注,这反映出跨
我是大运火炬手|丁宁:大运会既是赛场,更是世界青年的交流展示平台站
相信大家对35平方的电缆一米有多少纯铜,35平方铜芯电缆一米多少斤的问
1、最快的是交龙蛋,和70的时候虚空龙一样,在临风岛捡龙蛋交就行。2、
据韩媒“ChosunIlbo”报道,三星电子已于本月初正式开启了大语言模型(
莽莽苍苍的林海雄浑壮阔的沙漠奔流不息的黄河水一望无垠的大草原……辽
辽宁大连瓦房店市多地遭遇冰雹天气
记者从中国铁路上海局集团有限公司获悉,6月11日1时36分,随着首趟热滑
今天小红来为大家带来的是ldquo是什么意思,ldquo浑rdquo字怎么组词,
“史无前例地跨越了《不扩散核武器条约》原则和实践的门槛”“严重冲击
”陈文浩称,据他了解到的情况,事故发生前,刘某安曾和镇上几名党员干
女人吃猪皮有什么作用女性吃猪皮有什么好处1、猪皮的营养价值猪皮是一
央视网消息:眼下,在河北省沧州渤海新区黄骅市,旱碱麦迎来了收获期。
1、没问题呀,我刚试了。2、是不是你该更新下ie了我就是看了视频才跟你
【ITBEAR科技资讯】6月10日消息,蔚来汽车宣布将于6月15日晚上19点全球
点击图片查看视频央视网消息:眼下,在河北省沧州渤海新区黄骅市,旱碱
有行业专家分析认为,到2025年,新型储能的产业规模或突破万亿元大关;
1、丁默群历史上根本没有此人。2、电视剧中的“丁默群”是根据汪伪政府
昨日,2023清科·南通宝月湖投资人大会在我市举行,宝月湖合伙人计划正
近年来,走出国门,走向世界成了中国车企向上的法门。日前,《华夏时报
1、剧场版死神地狱篇「死神」第四部剧场版上映日期确认!今年12月4日起
近期,南美洲国家智利暴发数年来最严重的呼吸道合胞病毒疫情。据路透社
【ITBEAR科技资讯】6月10日消息,索尼旗舰级真无线耳机WF-1000XM5似乎
不在四星级以上酒店办会、不请明星网红商演……商洛市政府提出这样“过
1、这个问题挺难回答的,我找了一篇长篇评论:你可以看看,然后再去看
1、发 音wǔfēngshíyǔ释 义五天刮一次风,十天下一场雨。2、形容
相信大家对卫生间漏水如何处理视频,卫生间漏水如何处理的问题都很疑惑
加盟皇马之后,皇马的中场阵容将空前强大,且聚拢的都是青年球员,未来
中新网6月10日电 据美国哥伦比亚广播公司(CBS)报道,当地时间9日,
相信大家对网上选了车牌号还能去车管所再选吗,网上选车牌号和去车管所
1、如果我的主张行不通,我就乘上木筏子到海外去。2、【评析】“道不行
来为大家解答以上的问题。方脸的人适合什么发型,方脸适合什么耳环这个
1、orange 名词n 1 橙,橙子,橘子[C] Heboughtacrateofora
1、网上订花都死贵死贵,而且都是没店的他们接到单就联系当地花店本来10
抽中检查就撤IPO的格林生物二闯创业板,拟再度扩充产能,香精,日化,ipo,
1、其实不吃药最好,现在有很多医院都有理疗,如果没到了非吃不可的地
2023年河北省养老金调整方案公布在即,那么究竟能涨多少钱?公布时间又
上海海港排名榜首,主教练为何被喊下课?
相信大家对赣r是江西哪里的车牌号,上饶车牌号是赣什么?的问题都很疑
绍兴这个村,计划今年启动拆迁工作,越城区,绍兴市,拆迁工作,领导留言板
最新退休工资涨幅已定,很多小伙伴就问了2023年四川养老金上调方法公布
如何保护墓葬壁画?敦煌研究院院长揭秘关键技术
来为大家解答以上的问题。好望角游戏交易平台什么时候开通,好望角游戏
1、这是秦桧跪像背后岳飞墓阙上的楹云:“青山有幸埋忠骨,白铁无辜铸佞
来为大家解答以上的问题。塔哈玛特神殿急救训练师,塔哈玛特神殿这个很
来为大家解答以上的问题。藏海花南派三叔百度网盘,藏海花南派三叔这个
来为大家解答以上的问题。厦门有什么好吃的,厦门有什么特色小吃这个很
1、不要网上查得到的希望不用很大空间的游戏道具也少点的1 2 3!木头人
1、自考的考试方式是宽进严出,考生报名自考的条件不是很多,如果想要
黑龙江省平均工资是多少?2022年黑龙江省平均工资大幅上涨,创下10年第
1、tags[tægz]n 标签,贴纸tag的复数形式【例句】Thepricetagsays$100a
1、太多的方法了,说一些简单实用的。2、酒精具有杀菌的作用,用来消除
今年5月公布全国养老金上调比例之后,6月份各大省份将参考整体上调养老
来为大家解答以上的问题。最后一艘潜艇电影国语版百度云,最后一艘潜艇
1、一、足的声母z,韵母u,音调zú二、释义:脚:~下(对对方的敬称)
1、如果点Y固定了视线,解开的时候没办法解开,可以拖动下小地图里的小
《零乡》更像是与你面对面亲切交谈一样的以非虚构、跨文体、自传、百科
1、最快的是交龙蛋,和70的时候虚空龙一样,在临风岛捡龙蛋交就行。2、
来为大家解答以上的问题。取四朵用石蕊溶液染成紫色的纸花,取四朵用石
武汉一男子连续使用退热栓剂引发急性肾衰近日,有媒体报道,武汉一名男
月10日消息,软件巨头微软计划以690亿美元收购游戏开发商动视暴雪(Act
相信大家对床垫甲醛多少超标,床垫甲醛释放量国家检测标准是多少的问题
外婆来家里帮忙照顾小核桃,加上何太之前阑尾炎手术,除了回了趟香港,
6月9日,最高人民法院、最高人民检察院、公安部三部门起草了《关于依法
就让我们屏气凝神拭目以待记者:韦骅编辑:郑昕、王沁鸥。
1、POS的手续费率,是按交易量的百分比扣除,按行业不同扣率不同:
1、文化的概念:文化,天地万物(包括人)的信息的产生融汇渗透(的过程
长沙地铁2号线最小行车间隔压缩至几分钟?4月28日、5月1日及5月3日,长沙地铁全线网将延长运营至24:00,为往来旅客提供夜间交通保障。各线路
2023年五一劳动节期间天津限早晚高峰吗?具体政策有哪些?2023年五一劳动节期间,天津不限早晚高峰,本地车、外地车、区域指标均不限。根据天
五一期间天津外地车高峰限行措施有哪些?自2023年4月3日起,工作日(因法定节假日放假调休而调整为上班的星期六、星期日除外)每日7时至9时、1
外地人在天津怎么坐地铁?进站买票乘坐,目前买票是用自动售票机 , 投纸币,五元、十元,根据你乘坐地点和乘坐的距离,票价是不一样的,在
天津地铁首条线路何时开通运营?天津轨道交通,是指服务于中国天津市的城市轨道交通系统,包括地铁系统、轻轨系统;其首条线路于1984年12月28