首页 >行情 > > 正文

天天热资讯!解剖屎山,寻觅黄金之第二弹

程序员客栈 2023-06-10 21:48:37

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

上一篇:天天微头条丨科技动态:三星Galaxy S20 FE秋季价格暴跌 下一篇:最后一页
x
推荐阅读

天天热资讯!解剖屎山,寻觅黄金之第二弹

2023-06-10

天天微头条丨科技动态:三星Galaxy S20 FE秋季价格暴跌

2023-06-10

realme领导人Madhav Sheth或成为荣耀印度区首席执行官

2023-06-10

马斯克:推特将向认证创作者支付在评论中投放广告的收益_世界快看点

2023-06-10

lh是什么激素(fsh是什么激素) 世界视点

2023-06-10

天津发布鼓励发展邮轮旅游实施细则 “真金白银”鼓励发展邮轮旅游

2023-06-10

RK3588-WIF/BT调试之AP6256-微资讯

2023-06-10

高龄能不能转行做程序员? 焦点速读

2023-06-10

乐平:科技大棚 增产增收 全球播资讯

2023-06-10

ai图片怎么导入ps(ai图片怎么导入ae)-天天日报

2023-06-10

暗黑4威能不同位置的效果加成介绍 环球时讯

2023-06-10

秋冬想要曼妙的身材,让三木教你用一条腰带来提升气质,时髦高级

2023-06-10

中方驳斥:无中生有、信口雌黄、恶意诋毁!

2023-06-10

上合示范区五年间到发中欧班列2765列 年均增长率约35%|天天视点

2023-06-10

一帧中国|在清代建筑群品川东文化(2023年6月10日) 环球微资讯

2023-06-10

天天即时看!高考进行时|他们是考生奔赴考场时见到的第一个人

2023-06-10

伊戈尔:6月8日公司高管黄慧杰的亲属减持公司股份合计1400股

2023-06-09

观察:“海事惠民服务点”走进东北亚最大的件杂货码头

2023-06-09

天天速递!吴京和杰森·斯坦森出席《巨齿鲨2:深渊》上海发布会 现场气氛欢快

2023-06-09

每日视点!报告:近六成本科生、超八成高职生起薪在6000元以下

2023-06-09

盘中异动 | 易方达日兴资管日经225ETF(QDII)涨2.02%

2023-06-09

全球短讯!杭州事业单位入围名单遭提前泄露?培训机构疑似提前拿到面试名单

2023-06-09

钱江摩托(000913.SZ):1-5月QJMOTOR的小排量销量超过3.3万台|环球实时

2023-06-09

小于等于号怎么打键盘_小于等于号怎么打_焦点快看

2023-06-09

存款利率下调、降息预期升温!关联你房贷的LPR会降吗? 全球短讯

2023-06-09

清风头条丨高龄津贴被重复领取之后…… 全球实时

2023-06-09

6·8世界海洋日:探秘深海珊瑚 提升青少年海洋保护素养|全球热文

2023-06-09

国外网友评论炸了,鸿蒙4.0掀起汽车革命

2023-06-09

当前速讯:新股公告|科笛-B(02487)香港公开发售及国际发售均获轻度超额认购 每股定价21.85港元

2023-06-09

环球热资讯!车钥匙长按锁车键怎么不关窗(名爵5怎么用钥匙关窗?)

2023-06-09

环球热资讯!皮肤黑是因为什么引起来的_皮肤黑的原因有哪些

2023-06-09

get out of什么意思(get out是什么意思) 环球视讯

2023-06-09

上海警方侦破医美产品领域妨害药品管理案,涉案金额达1400余万元|头条焦点

2023-06-09

夜读 | 交易系统是取胜的关键!他的独特见解是......

2023-06-09

赛力斯集团张兴海:聚共识谋发展,携手谱写汽车强国新篇章 当前讯息

2023-06-09

国外网友评论炸了,鸿蒙4.0掀起汽车革命-环球动态

2023-06-09

世界快看:爱旭股份副总经理卢浩杰:ABC组件可交付效率24% 电池效率年底目标27%

2023-06-08

险险险!浏阳消防从火场救出一家8口

2023-06-08

全球讯息:淘宝店怎么装修模板图片(淘宝店怎么装修)

2023-06-08

书法之道神彩为上 书法之道_全球快看点

2023-06-08

黄晓明又换新女友了,又是张嫩模脸,很享受当众摸她屁股

2023-06-08

环球视讯!陆家嘴论坛强调加大消费金融支持,新能源汽车、绿色家电等大宗消费该如何抓住机遇?

2023-06-08

世界热头条丨【四型机关建设】襄都区:区长大讲堂 干部来上课

2023-06-08

集体低迷!半场小波特&波普&布朗合计10中2共得7分

2023-06-08

宇邦新材:公司的MBB焊带和SMBB焊带分别主要适用于P型的PERC电池和N型的Topcon电池

2023-06-08

【收评】菜粕日内下跌1.29% 近5日累计涨幅1.71% 天天观天下

2023-06-08

浦东金桥:本次担保金额合计人民币 5.0334 亿元-世界播报

2023-06-08

力拓和天齐锂业已经与智利的Enami就锂业务举行会谈

2023-06-08

朱强:在图纸上“修复”古今巨变的“三山五园” 热点评

2023-06-08

乌克兰卡霍夫卡水电站大坝遭破坏,外交部:严重关切|全球焦点

2023-06-08

一地通报!发现2例,已隔离|动态

2023-06-08

【全球播资讯】深交所:腾信创新终止上市 6月15日起进入退市整理期

2023-06-08

世界消息!美媒称布林肯将在几周内访华,中方能否证实?外交部回应

2023-06-08

杰创智能董秘回复:数字化和人工智能是大势所趋,公司将深化该领域的研究,结合公司的自身业务优势 世界简讯

2023-06-08

环球百事通!系统教程篇:设置的系统还原点不起作用的原因

2023-06-07

闯关东中篇秋桃_闯关东中篇

2023-06-07

【世界报资讯】5月全球制造业PMI为48.3% 表现最亮眼者仍是亚洲国家

2023-06-07

预估2024年苹果Vision Pro出货量约20万台 后续消费款才是主打 天天新要闻_快报

2023-06-07

SK-II、OLAY计划在王府井集团旗下门店卖出2.5亿元|环球观察

2023-06-07

外交部:中美保持着必要沟通,美方应当切实尊重中方核心利益和重大关切

2023-06-07

高盛料美联储7月加息0.25厘后暂停

2023-06-07

天津滨海农商银行:8年坚守 为高考学子保驾护航_天天观热点

2023-06-07

办公室软件自学教程电子版_办公室软件自学教程_全球聚焦

2023-06-07

我市8家企业成功入选-环球播报

2023-06-07

今日热文:谁遗落了“潜水靴”?“北溪”管道爆炸新线索能否让真凶浮出水面

2023-06-07

湖北省启动2023年度“万千百”质量提升行动

2023-06-07

房企面值退市第一股来了 没有整理期-世界观热点

2023-06-07

今年4月韩国进口冷冻鳕鱼数量同比减少81%

2023-06-07

局域网两台电脑传输文件(局域网两台电脑传文件)

2023-06-07

李娜首谈凭什么拿澳网冠军:教练对我说的这句话受益终生!_世界播报

2023-06-07

东风路、黄埔大道全天禁入

2023-06-07

动态焦点:贵州省黔南布依族苗族自治州惠水县2023-06-04 14:15发布雷电黄色预警

2023-06-07

6月6日,深圳市委书记孟凡利与西门子全球执行副总裁、西门子中国董事长肖松一行会谈 天天热头条

2023-06-07

通讯!安全蛋煮几分钟?

2023-06-07

焦点资讯:当地时间6月6日起,位于荷兰海牙的国际法院(ICJ)就马航MH17坠机案举行听证

2023-06-07

环球热点!世界上第一枚邮票_世界上第1枚邮票的名称是什么

2023-06-07

口袋妖怪增强绿宝石全准神捕捉地点一览|环球快看

2023-06-07

古田兔子表情包图片_古田兔子qq表情_最新消息

2023-06-07

世界环境日 | 西藏:绿染雅江满目景

2023-06-06

中国第三座迪士尼有望落户青岛?官方回应:暂无此计划_速讯

2023-06-06

艾美特电压力锅使用说明_艾美特电压力锅 当前热门

2023-06-06

绝对偏差怎么计算_绝对偏差-今日要闻

2023-06-06

梅西巴黎告别战被嘘了吗?梅西巴黎告别战被嘘是怎么回事?

2023-06-06

汉字找茬王拯救姐姐攻略 想办法拯救小姐姐图文通关详解[多图]_每日快报

2023-06-06

世界头条:临海快速路靖江南路高架桥顺利完成大体积混凝土现浇

2023-06-06

鸿路钢构:可转债转股价格调整为32.96元/股

2023-06-06

博瑞医药:博瑞鑫稳减持公司股份约422万股

2023-06-06

今明两年,有“4类物品”或将迎来大降价?老百姓要提前了解清楚 每日观察

2023-06-06

温氏股份:5月肉猪销售收入36.64亿元 同比增长46.44%-头条焦点

2023-06-06

天天消息!千仞雪的一生是被仇视的,被剧情抛弃的角色,一样悲剧却无人同情

2023-06-06

江苏省连云港市市场监管局抽查30个批次化肥产品合格率为80%-世界最新

2023-06-06

天天热消息:csol里巴雷特m95和死神m2_csol巴雷特m95

2023-06-06

环球速递!从恐龙到鸟:“飞上蓝天”的关键一步是什么?

2023-06-06

天天即时看!联东集团与中国农业银行北京分行签署战略合作协议

2023-06-06

暑期游 提前热了 最新

2023-06-06

焦点快报!叮咚买菜4年亏损123亿 预制菜领域寻求突围

2023-06-06

开启首次太空飞行 载荷专家在“天宫”究竟干些啥

2023-06-06

看《洛基》前必读!赶在明日开播前,为你梳理洛基MCU完整时间线|全球热资讯

2023-06-06

景洪市气象台发布雷电黄色预警信号【Ⅲ级/较重】【2023-06-05】_环球新动态

2023-06-06

呼啦圈怎么转的技巧_呼啦圈怎么转|当前观察

2023-06-06