首页 > 资讯 > > 正文

解剖屎山,寻觅黄金之第二弹

来源:程序员客栈 2023-06-06 14:05:31

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

x
推荐阅读

解剖屎山,寻觅黄金之第二弹

2023-06-06 14:05:31

盐水老鸭的做法有哪些? 世界新消息

2023-06-06 13:13:12

RCEP全面生效 为区域经济一体化注入强劲动力

2023-06-06 12:22:58

3D存储大量激发需求——早盘消息汇总2023年6月6号_焦点速递

2023-06-06 11:37:55

最高人民检察院关于印发《最高人民检察院关于刑事抗诉工作的若干意见》的通知(对于最高人民检察院关于印发《最高人民检察院关于刑事抗诉工作的若干意见》的通知简单介绍)

2023-06-06 10:34:03

【天天快播报】日本女子因华航空姐没讲日语暴怒辱骂 乘客看不惯回怼

2023-06-06 09:51:56

环球视点!达米安:会以最佳方式备战欧冠决赛,防守曼城需要全队共同努力

2023-06-06 09:08:41

水黾科昆虫(水黾科) 当前滚动

2023-06-06 07:52:02

跟领导初次见面说什么客套话(领导初次见面聊天开场白)

2023-06-06 06:55:45

Woj:快船将原总经理助理特伦特-雷登提拔为球队总经理 全球消息

2023-06-06 05:40:32
相关新闻

解剖屎山,寻觅黄金之第二弹

2023-06-06 14:05:31

盐水老鸭的做法有哪些? 世界新消息

2023-06-06 13:13:12

RCEP全面生效 为区域经济一体化注入强劲动力

2023-06-06 12:22:58

3D存储大量激发需求——早盘消息汇总2023年6月6号_焦点速递

2023-06-06 11:37:55

最高人民检察院关于印发《最高人民检察院关于刑事抗诉工作的若干意见》的通知(对于最高人民检察院关于印发《最高人民检察院关于刑事抗诉工作的若干意见》的通知简单介绍)

2023-06-06 10:34:03

【天天快播报】日本女子因华航空姐没讲日语暴怒辱骂 乘客看不惯回怼

2023-06-06 09:51:56

环球视点!达米安:会以最佳方式备战欧冠决赛,防守曼城需要全队共同努力

2023-06-06 09:08:41

水黾科昆虫(水黾科) 当前滚动

2023-06-06 07:52:02

跟领导初次见面说什么客套话(领导初次见面聊天开场白)

2023-06-06 06:55:45

Woj:快船将原总经理助理特伦特-雷登提拔为球队总经理 全球消息

2023-06-06 05:40:32

郭碧婷疑带娃长居杭州!身材丰腴被疑怀三胎,儿子首曝正脸似向佐_环球速讯

2023-06-06 05:07:14

芸芸众生,芸芸语(光怪陆离、似曾相识……)_全球资讯

2023-06-06 03:37:13

当前资讯!2023郑州中牟高考考点有哪些

2023-06-06 03:07:43

环球实时:阿尔巴尼亚穷么(阿尔巴尼亚穷吗)

2023-06-06 02:38:30

真实姓名找人的手机号_真实姓名找人网 环球快播

2023-06-06 01:12:50

热点聚焦:秋天的命运国语版资源_秋天的命运国语版

2023-06-05 23:52:57

为什么打开一个程序总是显示程序无法找到入口呢_为什么打开一个程序总是显示程序无法找到入口

2023-06-05 23:09:57

海报|太平洋不是日本的下水道

2023-06-05 22:37:31

86年属虎的做什么行业最适合,属相属虎的适合做什么行业

2023-06-05 22:02:38

北向资金净卖出12.15亿元,美的集团、赣锋锂业等获加仓

2023-06-05 20:55:50

淅川县多措并举 引导民营经济人士积极履行社会责任 环球聚看点

2023-06-05 19:08:43

史上最卷618来了 让谁来买单?

2023-06-05 18:20:16

今日观点!七夕会时尚 | 走进蟠龙的新梦

2023-06-05 17:54:02

筑梦大运,行知小学六(3)中队学子红旗下颂祖国

2023-06-05 17:13:51

今日汇市观察:美元指数上涨至104.16 澳洲央行利率决策仍不确定 五大货币最新技术分析-当前头条

2023-06-05 17:01:29

涨停雷达:ST板块异动 ST华铁触及涨停

2023-06-05 15:48:09

主汛期到了,如何打好水旱灾害防御主动仗?_天天快报

2023-06-05 14:41:16

揭秘:6月第1周为啥这几个小区关注度最高? 天天新视野

2023-06-05 14:32:25

“拱昭”携手 共谋教育发展

2023-06-05 14:12:03

世界新动态:Simple Date Format类到底为啥不是线程安全的?

2023-06-05 13:24:53

天天讯息:猪肉概念持续下挫 华统股份等跌超4%

2023-06-05 12:42:04

【就业分析】硕士毕业后如果考选调,考研时应该如何择校?

2023-06-05 11:43:39

变压器容量与功率换算(变压器容量与功率的关系) 报道

2023-06-05 10:56:28

官方预热:摩托罗拉 Razr 40 系列折叠屏手机即将登陆印度

2023-06-05 10:22:41

什么是世界史专业属于学科|全球实时

2023-06-05 09:32:20

全球今亮点!清明上河图高清细节图(清明上河图高清)

2023-06-05 09:00:06

card是什么意思_cake是什么意思

2023-06-05 07:58:10

重大调整,周一生效!4000亿资金提前行动? 观热点

2023-06-05 06:45:31

焦点信息:宋燮(关于宋燮介绍)

2023-06-05 05:12:20

天天热讯:马云持有阿里巴巴多少股份_马云阿里巴巴股份占多少

2023-06-05 02:49:05

天天快资讯丨泰山海拔高度是多少米高_泰山海拔

2023-06-05 00:37:25

小考试题及答案大全_小考试题_环球看热讯

2023-06-04 22:41:42

什么花在晚上十一点开(晚上十一点开的花) 最新

2023-06-04 21:25:42

windows无法启动print spooler服务1068(windows无法启动print spooler服务)

2023-06-04 20:18:04

制造费用会计(制造费用会计分录)

2023-06-04 19:13:52

乘联会崔东树:中国新能源车出口要建设好欧洲市场的口碑和信誉 减少内耗

2023-06-04 18:16:19

刂字旁的字有哪些字字旁的字(饣字旁的字 饣字旁的字有哪些简介介绍)

2023-06-04 17:21:37

力王监狱之力王完整版国语版_力王之监狱力王国语

2023-06-04 16:09:20

天天看点:飞盘衰落,“小众网红运动”为何难长红?

2023-06-04 15:13:03

分类汇总的操作步骤包括_分类汇总的操作步骤_全球聚焦

2023-06-04 14:18:03

祝福祖国的一句话语_祝福祖国的一句话 焦点速讯

2023-06-04 13:47:17

今日播报!代写遗嘱的法律要件有何种

2023-06-04 12:20:46

feed流投放(feed 流)_当前播报

2023-06-04 11:09:47

巴拉克百科_巴拉克定律

2023-06-04 10:36:37

教师教学创新大赛【一等奖】创新成果报告分享(干货6篇) 天天微头条

2023-06-04 09:46:44

黄震怀揣着对事业的热爱,带领团队不断探索,勇攀技术新高峰 【奋斗者正青春】逐梦星河的航天青年

2023-06-04 08:56:00

国内最先进高铁隧道数智化管片开启试生产

2023-06-04 07:59:44

【独家】WWDC23:苹果可能宣布对“Siri”虚拟助手的重大更改

2023-06-04 06:15:25

每日快看:小孩子早餐吃什么好比较有营养的

2023-06-04 04:57:16

三年级除法竖式练习题百度_三年级除法竖式练习题

2023-06-04 03:28:36

JKL第一视角自己交死亡双招被秒:表情呆滞 猛摸鼻子

2023-06-04 01:34:37

头条焦点:剪映怎么放大镜头特写加回放(剪映怎么放大镜头特写)

2023-06-03 23:43:10

每日体育报:利雅得新月打算6月6日宣布签下梅西 即时看

2023-06-03 21:59:34

别把超额业绩报酬建立在投资者痛苦基础上|全球今热点

2023-06-03 21:08:06

今日播报!大众带t发动机_大众teramont什么发动机

2023-06-03 19:56:07

G7易流助力河北天联实业,财运通提升数字化货运管理能力

2023-06-03 18:51:57

焦点滚动:中日防长在香格里拉对话会期间举行双边会晤

2023-06-03 17:59:14

天天消息!华丰HUAFENG品牌介绍_华丰电子元件

2023-06-03 17:00:07

观热点:00后女生,爆肝10天,盖出武侠小说中9大神仙岛

2023-06-03 16:17:35

环球热头条丨优酷下载视频怎么转换格式_优酷下载视频怎么转换mp4

2023-06-03 15:53:37

我的世界启动器账号和密码免费送 我的世界启动器账号

2023-06-03 14:55:57

环球关注:tf家族成员资料简介12人_TF家族的成员名单

2023-06-03 14:10:57

安吉红星美凯龙世博家居广场_世界今头条

2023-06-03 12:45:57

重磅!7月1日起高明买房可入户!入户攻略|百事通

2023-06-03 11:47:47

天天热资讯!传真号码大全山东_传真号码大全

2023-06-03 11:18:47

原神穿越综漫_求综漫小说 100万字以上主角穿越的世界要多_全球聚焦

2023-06-03 10:43:08

迪士尼乐园有望落户武汉?官方:正在洽谈-全球热讯

2023-06-03 09:25:26

羚锐制药:6月2日融资买入656.78万元,融资融券余额1.72亿元

2023-06-03 08:48:12

大学时代小说(大学时代)_天天简讯

2023-06-03 07:57:56

“灵长类基因组计划”取得重大进展 公布27种灵长类动物基因组数据

2023-06-03 06:53:37

理想L7 Air版:1.5T增程动力+449马力!可以入手吗?

2023-06-03 05:49:58

中华博物书法在线查询_中华博物书法字典 观察

2023-06-03 04:29:04

头条焦点:织金县发布特别严重暴雨警告

2023-06-03 03:31:44

吉力在一起读什么_吉力念什么

2023-06-03 03:27:38

Meta抢发新头显,“截胡”苹果新VR

2023-06-03 03:02:37

暴走大事件第三季在线观看(暴走大事件为什么封了) 简讯

2023-06-03 01:39:43

【全球报资讯】最小“画家”只有三岁!武汉一所大学美术馆举办“童画展”

2023-06-03 01:37:23

微头条丨心较比干多一窍下一句_心较比干多一窍病如西子胜三分

2023-06-03 00:09:58

智媒中心建设项目排版胶印厂房、轮转车间改造装修及智媒中心加建工程PVC塑胶地板采购比选结果公示 最资讯

2023-06-02 23:14:25

天天看热讯:中国科技馆周一闭馆吗?

2023-06-02 22:47:04

鹤壁市鹤山区妇联:手牵手探秘科学 心连心共度佳节-快播报

2023-06-02 22:06:26

3300秒!我国载人登月火箭主力发动机再创新纪录

2023-06-02 21:39:46

中国人民银行行长易纲会见阿根廷经济部长马萨与阿根廷央行行长佩塞一行

2023-06-02 20:34:04

6月2日国内DOTP企业报价下跌

2023-06-02 18:59:02

【世界播资讯】心手相牵 快乐成长——四平中院第二党支部开展“六一”儿童节主题党日活动

2023-06-02 18:50:40

赤龙牙野菜多少钱一斤 赤龙牙 快资讯

2023-06-02 17:16:31

滚动:得陇望蜀的意思_得陇望蜀的意思

2023-06-02 16:53:14

领益智造(002600)6月2日主力资金净卖出5475.28万元 天天快看

2023-06-02 16:14:25

天天视讯!一张图:2023/06/02黄金原油外汇股指"枢纽点+多空占比"一览

2023-06-02 15:27:44

中青旅举办“六一”研学游 助推古北水镇文旅融合|环球实时

2023-06-02 14:50:03