MQ 用来解耦挺好的。我们有个业务,计算用户在线时长,然后触发完成 “每日在线 15 分钟” 的每日任务。登录,登出都发消息,接到消息的程序减一下时间得到在线时间触发任务完成。
我们的系统有个毛病,可能出现闪登闪退,也就是同一个毫秒登录马上登出,这就尴尬了,消费者可能先收到登出再收到登录。这个时候程序员小伙子们可来劲了:“我知道我知道,可以用 MQ 的保证消息顺序能力”,然而被我制止了。我已经受的够够的了,一有什么达不到,立马诉诸各类技术框架的功能。
不急,先想想,登录的业务本质是什么?就是验证身份,成功之后开启一段会话,登出自然就是终结这段会话咯,在线时长就是这段会话的时长。好,那么当先收到登出消息时,无非就是发现这个会话没有开始时间么,但是他确实是一个存在的会话啊,没有开始时间就没有好了,先放着,一会儿登录消息来了那么会话开始时间也就补齐了,可以调用会话的 “计算会话时长” 方法计算在线时间了。
所以这关 MQ 的保证消息顺序什么事?我们是不是做技术做魔怔了?把太多的业务解决方案诉诸技术,系统越来越复杂,在错误的道路上越走越远。。。
1
AItsuki 332 天前 via iPhone 3
你是对的
|
2
sunwei0325 332 天前
复杂业务还是需要 MQ 保证顺序的, 不然 aws 的 SQS 也不会设计一个 FIFO 队列了
|
3
Plutooo 332 天前 3
MQ MQ ,Message Queue ,我觉得需要 Queue 有顺序没有什么问题
|
4
54qyc 332 天前 13
OP 也魔怔了,看见别人用顺序消息就开始脑补开始喷了?别人思路必须跟你一样?你要是不接受有序消息,你不能反问别人还有没有其他的解决方案?上来就是恶意假设?不过这里顺序消息也根本处理不了秒登秒登出场景。生产的时候并不能保证先生产登录 后生产登出,如果是有多个应用服务器的话。
|
5
coderzhangsan 332 天前
看问题的角度不一样,程序员从技术角度要保证业务的可靠性和严谨性,没什么问题,需求交互场景细节这个可以沟通,按照需求调整,没必要鸡蛋里挑骨头。
|
6
B1acKy1in 332 天前
个人理解是简单的业务,消费者那里缓存下,然后验证下时间戳就够了;复杂系统还是搞点组件(甚至搞个服务)来处理下吧,毕竟复杂业务的架构跨度太大了,很难说哪里有啥问题。
|
7
zihuyishi 332 天前 5
这个计算在线时长的逻辑不太合适吧,如果我今天不登出意思就完成不了这个任务了?
如果以后要做防沉迷是不是我只要一直在线也可以一直玩下去了 |
8
k9982874 332 天前 via Android 19
取出最后登录时间,登出时间一减就成,确实不需要 mq 。
但是 op 的态度是真的让人讨厌。 |
9
opentrade 332 天前
程序闪退了,就不计算我的在线时长?
|
10
shalk 332 天前
如果登入消息丢了呢,这个时长就不记录了么
|
11
yibinhp 332 天前
@sunwei0325 请教一下,多消费者的情况下怎么保证 mq 有序消费啊
|
12
Jooeeee 332 天前
如果登录登出是同一个 mq ,且 mq 有这个能力,为什么不用呢。
另外,这个需求看着不需要很精确,没有登录消息,就当是 5 分钟好了 |
13
lsk569937453 332 天前
我是看了标题进来的,只能说你的应用场景可以不用 MQ 。
但是针对你的标题,我想说 MQ 确实需要一个保证顺序的功能。 比如现在主流的分布式事务的解决方案就是分布式消息,而分布式消息里面很重要的一点就是 MQ 的消息必须是顺序的。 |
15
sunwei0325 332 天前 1
MQ 保证顺序, 主要是因为分布式服务以及服务器网络通信等因素, 造成的 AB 消息入队, 结果是 BA 消息出队这种情况.
但是如果像闪退闪登这种, 2 个事件一起发, 很可能由于网络, 客户端先发的登出消息, 后于登录消息到达 MQ, 这种情况下, 即使 MQ 保证顺序, 消费者看到的依然是乱序. 上面说的这种情况可以借鉴 Flink 的 watermark+window, 由业务进行补偿处理, 虽然 IngestionTime 是乱序的, 但是 EventTime 是有序的. |
16
wolfie 332 天前 via Android
mq 消息存储没有时间戳吗。
多实例多线程 消费一个队列 如何应对。 |
17
Pantheoon 332 天前
队列的本质就是先进先出
|
18
kingfalse 332 天前 via Android
功能实现了吗?实现了就没毛病!毕竟每个人都有自己的骚操作。
|
19
GopherDaily 332 天前
你菜
|
20
makersy 332 天前
这标题就有问题。MQ 也是 queue ,保证顺序为什么不是 queue 该做的事情?
|
21
milkpuff 332 天前
楼主说的对。我赞同。
我觉得楼主的重点在于”把太多的业务解决方案诉诸技术“,这一点指出得准确 |
22
leonshaw 332 天前 via Android
这是重排,不是保序
|
23
GuangXiN 332 天前
MQ 不是 Message Queue 的缩写么? Queue 不保证 FIFO 还叫 Queue 么?
|
24
cp19890714 332 天前
挖掘业务本质, 是个很难但是非常重要的能力. 这个能力难以通过固有的教程去训练.
对于人来说, 技术能力可以通过已有的教程文档快速掌握, 自然就会依赖技术. |
25
PVXLL 332 天前 via iPhone
都是菜鸡
|
26
ShuWei 332 天前
通过两条消息的时间差去计算在线时长,这真的是个好的方案么?会不会,这个方案从一开始就是有问题的
|
27
adoal 332 天前 3
“我们的系统有个毛病”……你看,你自己都知道是业务系统的毛病,不去解决毛病也就罢了,毕竟屎山不能乱动,以防溅一脸屎汤。人家要在外围用技术手段来把你这业务系统这端的毛病给人家外围附加功能带来的困扰 workaround 掉,你还怪人家做技术做魔怔了。“系统越来越复杂,在错误的道路上越走越远”是“把太多的业务解决方案诉诸技术”导致的吗?你们这群技术不重要业务该被舔的嘤嘤怪,心里真的没有点碧树吗?
|
28
IvanLi127 332 天前 via Android
MQ 有复杂的也有简单的,你知道人家说的是什么 MQ 吗?
|
29
neoblackcap 332 天前 1
就这样的统计功能都要放在业务系统里面做,那什么系统跑不死啊。登录,登出的事件写日志(进 MQ 再落地也一个道理),直接通过回放日志,简单统计一下当天是否有超过 15 分钟的在线就得了。而且还不会对业务系统产生影响,因为这需求可以做成实时的,也可以做成离线。
OLAP 的活就不要压业务系统了。 |
30
SeaTac 332 天前
> 我们的系统有个毛病,可能出现闪登闪退
不先把系统的问题修一修么 |
31
xuanbg 331 天前
1 、我不懂闪退为啥还能有登出动作?
2 、计算在线时长不是应该用 redis 吗?用 MQ 做啥? |
32
haochih 331 天前
你是对的
|
33
jguo 331 天前 2
“我喜欢和聪明人交往,因为不用考虑他们的尊严”。讨论技术问题别上来就开启防御姿态。
|
34
lmq2582609 331 天前
第一反应是修复这个登入登出的毛病
|
36
zsdroid 331 天前
系统有毛病不管,先来发帖喷一喷别人。op 牛逼。
|
37
msaionyc 331 天前
“先放着”是什么意思,这条消息怎么处理?
如果这个消息处理的地方为这个行为做个补丁,其实也等于提高了系统复杂度,后人接手时也会摸不着头脑,为什么这么做 |
38
ecareyu 331 天前
其实 up 主,你说的压根就是两件事,但也可以说是一件事,就是,产品思维和技术思维,技术一般很难跳出技术思维这个圈,但是很多以产品思维来想,有些事,确实没必要完全通过复杂的技术实现,因为用户根本不会 care 。你要没必要喷那个小伙,毕竟,他只是个技术,你让他往产品想,那属实有点隔行如隔山了。
|
39
zhazi 331 天前
笑死,op 来找认同,结果被按着头喷。
水平不高的人当 ld 是这样的 |
40
Leviathann 331 天前
mq 保证的不是入队的顺序吗,入队就是乱的保证什么?
|
41
FrankAdler 331 天前 via Android
水平不高的人有话语权是这样的
block 了 |
42
Habyss 331 天前
可是 mq 单队列单消费者, 本身不就是有序的吗.
|
44
Masoud2023 331 天前
你们不应该先解决一下闪灯闪退的问题吗
|
45
GeruzoniAnsasu 331 天前
> 登录的业务本质是什么?就是验证身份,成功之后开启一段会话
明明你「理解」了本质,怎么还能想出这种结论。 假设你们的系统真的能先收到登出再收到登录,登出的时候,会话在哪? > 么当先收到登出消息时,无非就是发现这个会话没有开始时间么,但是他确实是一个存在的会话啊,没有开始时间就没有好了 哈? REALLY? 你是凭什么认为这个登出消息能是一个合法消息的? |
46
qiyilai 331 天前
为什么非要登出才能统计在线时长?好奇怪
|
47
jdkxnktkdkxod 331 天前
不能保证顺序的 mq 还能叫 mq 吗?
|
48
venglide 331 天前
典型的流处理问题,文不对题。
|
50
kelvin_fly 331 天前
我理解是两个事情。一是发送到 MQ 的 message 本身就顺序有问题,由于网络波动或者其他啥原因。 另一个是 MQ 保证顺序。 最好在 message 中携带业务的时间戳。
这个计算时长应该业务方自己解决先手顺序,因为只靠 MQ 的顺序也解决不了 |
51
Aresxue 331 天前
无非就是顺序消息存在的必要性,答案是有必要。只是说不能一股脑地把问题都丢给中间件以为就万事大吉了,10TPS 有 10TPS 的处理方式,1kTPS 有 1kTPS 的,10wTPS 也有 10wTPS 的,就事论事选择最适合业务的。
|
52
totoro52 331 天前
你们的业务好奇怪啊, 计算在线时长,而且是每日任务, 那取当日首次登陆时间,和当前存在时间计算一下不就知不知道满足 15 分钟了吗,
为什么还要去登出登入什么奇奇怪怪的逻辑,登出才出发任务? 那我一直登着不退出不就不触发这个任务了,难不成你们业务是必须实实在在的计算某一次在线时长满足 15 分钟的? |
54
Mikawa 331 天前
要不先修一下闪登的问题,然后在线的时候能不能发个心跳包
来自某个必须要登出才能统计在线的游戏的玩家 |
56
nuII 331 天前
笑死,主要问题来源不是因为闪登闪退吗?这问题不修,搞其他的有用?
|
57
WashFreshFresh 331 天前
怎么先放着,服务维护重启怎么办,存 redis 还是存库?存的话什么时候取出来,登出的时候取出来?
业务就是这样一步步搞复杂的。 |
58
Akiya 331 天前
同一个 partition 本来就是保证顺序的。但是 MQ 有序并不能解决你这里秒登秒退的问题。总之 OP 确实有点魔怔
|
59
imokkkk 331 天前
我理解 如果项目已经引入了 MQ ,用到这里来解决问题也不是不行,如果单纯为了解决这个问题引入 MQ ,那确实没必要额外在运维一个组件。
|
60
herofire 331 天前
你是对的!我必需为此点个赞
|
61
palfortime 331 天前 via Android
只有我好奇同一毫秒的登入登出是怎么达成的吗?
|
62
FaustY 331 天前
这辈子登出的次数用一只手都能数得过来,如果符合 lz 的场景的话,新增个接口,前端判断时间够了直接调用会不会好点。
|
63
zhuoyue100 331 天前
怎么能用登陆和登出来统计在线时长? 现在谁还点登出
|
64
iseki 331 天前
业务不诉诸技术诉诸什么?无非是不同的取舍而已,别说的这么清新脱俗。虽然我不赞同他的解决方案,但是你这种思想问题更大,他的方案不够严密只是水平问题,你这是路线问题。
不妨先想想所谓的「业务解决方案」真的只是业务吗。 |
65
qwwe01 331 天前
入队是无序的话,就算 MQ 保证了也解决不了。除非从发消息到 MQ 到消费都是同一条链路才能保证吧。
设计的话,为啥不记录下来自己计算一遍就好了 |
66
NoKey 331 天前
讨论一个问题啊,闪退的情况下,有回调发出登出消息么?
|
67
wh0syourda66y 331 天前
《我们业务有个问题》
《这样不就行了,想那么复杂干什么》 《以后出了问题再说》 《哦,这个问题是因为我们上次为了修复那个问题引进的》 《你问我为什么不解决根本问题,你懂不懂业务》 《我离职了,上个公司代码就是个屎山,技术差的要命》 |
68
BQsummer 331 天前
模型和 flink 的 watermark 挺相似的, 时间时间和消息时间是两回事.
|
69
sunsan05 331 天前
MQ 需要不需要保证顺序,是架构设计的时候决定的。架构设计的时候怎么决定的,就是考虑异常情况下的处理方案。
如果你需要顺序的数据并且做计算, 那么: 如果 MQ 不需要保证顺序,那就需要 Flink 这种流式计算(或自研)做窗口数据流校验。 如果你觉得实时数据也没必要,那就改为批处理,同样也是窗口期校验。 --- 到这你就会发现,是你要什么,然后才选择什么的,不能既要有要还要。如果想既要有也要还要,那就需要有牺牲。 |
70
MrSheng 331 天前
按照目前他们的设计,我在 14 分 59 秒退出,如此反复,哪怕玩一天,也无法达成“在线 15 分钟”任务。
|
71
mysunshinedreams 331 天前
MQ 也没法保证毫秒级的顺序吧,我记忆中 Kafka 从 producer 到 broker 还有一段时间呢,而且你这个登入和登出衔接这么近,打到两台节点上,到 broker 的顺序也不一定,这种东西真正的解决办法不应该是记录时间戳+延迟消息搞定吗
|
72
rioshikelong121 331 天前
很奇怪的实现方式。我完全可以不登出啊。
|
73
sunsan05 330 天前
|
74
atVoid 330 天前
不要先确定一个"我想喷 xx"目的, 然后在现实中当小警察时刻搜寻, 抓到一个看起来有点像的点就开喷.
PS: 要不还是先解决秒登秒出的 bug, 以及你们这方案不登出就没法完成任务的问题? 然后真的理解了很多的业务场景和方案, 才开始聊聊顺序消息. |
75
bthulu 330 天前
没有登陆的登出, 直接丢弃就好了, 不差这个几百毫秒的在线时间的.
|
76
LoliconInside 330 天前
思路有问题,你要统计的是“在线时长”,不是“登入-登出时间的差值”
如果我这辈子都不主动登出,是不是这辈子都无法完成这个在线任务? 个人思路:在登入后按分钟发送心跳包,服务端统计心跳包个数,满足个数后标记该用户“任务已完成” 这样你消息是否 FIFO 也无关紧要了,我只是想看你到底有没有满足“在线 15 分钟”这个条件而已 |
77
purensong 330 天前
看标题进没让我失望,浪费了一分钟
|
78
mysunshinedreams 330 天前
@sunsan05 #73 即使设定到很低,分布式架构上的假定还是会存在问题
|
79
DefoliationM 330 天前 via Android
没学过数据结构?不知道什么叫队列?先进先出不知道?
|
80
258 281 天前
登出?
|