MQ 就 MQ 好了,保证顺序那什么的是你该干的事儿吗?啊?

2023-10-31 16:39:52 +08:00
 zhengchengdong

MQ 用来解耦挺好的。我们有个业务,计算用户在线时长,然后触发完成 “每日在线 15 分钟” 的每日任务。登录,登出都发消息,接到消息的程序减一下时间得到在线时间触发任务完成。

我们的系统有个毛病,可能出现闪登闪退,也就是同一个毫秒登录马上登出,这就尴尬了,消费者可能先收到登出再收到登录。这个时候程序员小伙子们可来劲了:“我知道我知道,可以用 MQ 的保证消息顺序能力”,然而被我制止了。我已经受的够够的了,一有什么达不到,立马诉诸各类技术框架的功能。

不急,先想想,登录的业务本质是什么?就是验证身份,成功之后开启一段会话,登出自然就是终结这段会话咯,在线时长就是这段会话的时长。好,那么当先收到登出消息时,无非就是发现这个会话没有开始时间么,但是他确实是一个存在的会话啊,没有开始时间就没有好了,先放着,一会儿登录消息来了那么会话开始时间也就补齐了,可以调用会话的 “计算会话时长” 方法计算在线时间了。

所以这关 MQ 的保证消息顺序什么事?我们是不是做技术做魔怔了?把太多的业务解决方案诉诸技术,系统越来越复杂,在错误的道路上越走越远。。。

8697 次点击
所在节点    Java
80 条回复
palfortime
2023-11-01 14:26:19 +08:00
只有我好奇同一毫秒的登入登出是怎么达成的吗?
FaustY
2023-11-01 14:28:34 +08:00
这辈子登出的次数用一只手都能数得过来,如果符合 lz 的场景的话,新增个接口,前端判断时间够了直接调用会不会好点。
zhuoyue100
2023-11-01 14:31:06 +08:00
怎么能用登陆和登出来统计在线时长? 现在谁还点登出
iseki
2023-11-01 14:38:07 +08:00
业务不诉诸技术诉诸什么?无非是不同的取舍而已,别说的这么清新脱俗。虽然我不赞同他的解决方案,但是你这种思想问题更大,他的方案不够严密只是水平问题,你这是路线问题。
不妨先想想所谓的「业务解决方案」真的只是业务吗。
qwwe01
2023-11-01 14:57:49 +08:00
入队是无序的话,就算 MQ 保证了也解决不了。除非从发消息到 MQ 到消费都是同一条链路才能保证吧。
设计的话,为啥不记录下来自己计算一遍就好了
NoKey
2023-11-01 16:32:16 +08:00
讨论一个问题啊,闪退的情况下,有回调发出登出消息么?
wh0syourda66y
2023-11-01 16:45:51 +08:00
《我们业务有个问题》
《这样不就行了,想那么复杂干什么》
《以后出了问题再说》
《哦,这个问题是因为我们上次为了修复那个问题引进的》
《你问我为什么不解决根本问题,你懂不懂业务》
《我离职了,上个公司代码就是个屎山,技术差的要命》
BQsummer
2023-11-01 17:41:11 +08:00
模型和 flink 的 watermark 挺相似的, 时间时间和消息时间是两回事.
sunsan05
2023-11-01 17:59:08 +08:00
MQ 需要不需要保证顺序,是架构设计的时候决定的。架构设计的时候怎么决定的,就是考虑异常情况下的处理方案。
如果你需要顺序的数据并且做计算,
那么:
如果 MQ 不需要保证顺序,那就需要 Flink 这种流式计算(或自研)做窗口数据流校验。
如果你觉得实时数据也没必要,那就改为批处理,同样也是窗口期校验。

---

到这你就会发现,是你要什么,然后才选择什么的,不能既要有要还要。如果想既要有也要还要,那就需要有牺牲。
MrSheng
2023-11-01 18:11:35 +08:00
按照目前他们的设计,我在 14 分 59 秒退出,如此反复,哪怕玩一天,也无法达成“在线 15 分钟”任务。
mysunshinedreams
2023-11-01 18:57:06 +08:00
MQ 也没法保证毫秒级的顺序吧,我记忆中 Kafka 从 producer 到 broker 还有一段时间呢,而且你这个登入和登出衔接这么近,打到两台节点上,到 broker 的顺序也不一定,这种东西真正的解决办法不应该是记录时间戳+延迟消息搞定吗
rioshikelong121
2023-11-01 19:51:36 +08:00
很奇怪的实现方式。我完全可以不登出啊。
sunsan05
2023-11-02 09:01:46 +08:00
@mysunshinedreams 可以毫秒级,KAFKA 可以把 BUFFER 和等待参数都设定到很低。

注意,这是算力上的问题。不是架构上的问题。
atVoid
2023-11-02 11:02:33 +08:00
不要先确定一个"我想喷 xx"目的, 然后在现实中当小警察时刻搜寻, 抓到一个看起来有点像的点就开喷.
PS: 要不还是先解决秒登秒出的 bug, 以及你们这方案不登出就没法完成任务的问题?
然后真的理解了很多的业务场景和方案, 才开始聊聊顺序消息.
bthulu
2023-11-02 12:40:28 +08:00
没有登陆的登出, 直接丢弃就好了, 不差这个几百毫秒的在线时间的.
LoliconInside
2023-11-02 12:44:07 +08:00
思路有问题,你要统计的是“在线时长”,不是“登入-登出时间的差值”
如果我这辈子都不主动登出,是不是这辈子都无法完成这个在线任务?

个人思路:在登入后按分钟发送心跳包,服务端统计心跳包个数,满足个数后标记该用户“任务已完成”
这样你消息是否 FIFO 也无关紧要了,我只是想看你到底有没有满足“在线 15 分钟”这个条件而已
purensong
2023-11-02 15:28:24 +08:00
看标题进没让我失望,浪费了一分钟
mysunshinedreams
2023-11-02 17:10:32 +08:00
@sunsan05 #73 即使设定到很低,分布式架构上的假定还是会存在问题
DefoliationM
2023-11-02 18:36:38 +08:00
没学过数据结构?不知道什么叫队列?先进先出不知道?
258
2023-12-21 09:43:29 +08:00
登出?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/987160

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX