V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhengchengdong
V2EX  ›  Java

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

  •  
  •   zhengchengdong · 122 天前 · 7494 次点击
    这是一个创建于 122 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    80 条回复    2023-12-21 09:43:29 +08:00
    AItsuki
        1
    AItsuki  
       122 天前 via iPhone   ❤️ 3
    你是对的
    sunwei0325
        2
    sunwei0325  
       122 天前
    复杂业务还是需要 MQ 保证顺序的, 不然 aws 的 SQS 也不会设计一个 FIFO 队列了
    Plutooo
        3
    Plutooo  
       122 天前   ❤️ 3
    MQ MQ ,Message Queue ,我觉得需要 Queue 有顺序没有什么问题
    54qyc
        4
    54qyc  
       122 天前   ❤️ 12
    OP 也魔怔了,看见别人用顺序消息就开始脑补开始喷了?别人思路必须跟你一样?你要是不接受有序消息,你不能反问别人还有没有其他的解决方案?上来就是恶意假设?不过这里顺序消息也根本处理不了秒登秒登出场景。生产的时候并不能保证先生产登录 后生产登出,如果是有多个应用服务器的话。
    coderzhangsan
        5
    coderzhangsan  
       122 天前
    看问题的角度不一样,程序员从技术角度要保证业务的可靠性和严谨性,没什么问题,需求交互场景细节这个可以沟通,按照需求调整,没必要鸡蛋里挑骨头。
    B1acKy1in
        6
    B1acKy1in  
       122 天前
    个人理解是简单的业务,消费者那里缓存下,然后验证下时间戳就够了;复杂系统还是搞点组件(甚至搞个服务)来处理下吧,毕竟复杂业务的架构跨度太大了,很难说哪里有啥问题。
    zihuyishi
        7
    zihuyishi  
       122 天前   ❤️ 5
    这个计算在线时长的逻辑不太合适吧,如果我今天不登出意思就完成不了这个任务了?
    如果以后要做防沉迷是不是我只要一直在线也可以一直玩下去了
    k9982874
        8
    k9982874  
       122 天前 via Android   ❤️ 19
    取出最后登录时间,登出时间一减就成,确实不需要 mq 。
    但是 op 的态度是真的让人讨厌。
    opentrade
        9
    opentrade  
       122 天前
    程序闪退了,就不计算我的在线时长?
    shalk
        10
    shalk  
       122 天前
    如果登入消息丢了呢,这个时长就不记录了么
    yibinhp
        11
    yibinhp  
       122 天前
    @sunwei0325 请教一下,多消费者的情况下怎么保证 mq 有序消费啊
    Jooeeee
        12
    Jooeeee  
       122 天前
    如果登录登出是同一个 mq ,且 mq 有这个能力,为什么不用呢。
    另外,这个需求看着不需要很精确,没有登录消息,就当是 5 分钟好了
    lsk569937453
        13
    lsk569937453  
       122 天前
    我是看了标题进来的,只能说你的应用场景可以不用 MQ 。

    但是针对你的标题,我想说 MQ 确实需要一个保证顺序的功能。

    比如现在主流的分布式事务的解决方案就是分布式消息,而分布式消息里面很重要的一点就是 MQ 的消息必须是顺序的。
    Goooooos
        14
    Goooooos  
       122 天前   ❤️ 1
    @yibinhp

    不同 MQ 有不同的实现。kafka 可以通过指定 key 让同一个 key 的消息落到同一个 partition
    sunwei0325
        15
    sunwei0325  
       122 天前   ❤️ 1
    MQ 保证顺序, 主要是因为分布式服务以及服务器网络通信等因素, 造成的 AB 消息入队, 结果是 BA 消息出队这种情况.

    但是如果像闪退闪登这种, 2 个事件一起发, 很可能由于网络, 客户端先发的登出消息, 后于登录消息到达 MQ, 这种情况下, 即使 MQ 保证顺序, 消费者看到的依然是乱序.

    上面说的这种情况可以借鉴 Flink 的 watermark+window, 由业务进行补偿处理, 虽然 IngestionTime 是乱序的, 但是 EventTime 是有序的.
    wolfie
        16
    wolfie  
       122 天前 via Android
    mq 消息存储没有时间戳吗。

    多实例多线程 消费一个队列 如何应对。
    Pantheoon
        17
    Pantheoon  
       122 天前
    队列的本质就是先进先出
    kingfalse
        18
    kingfalse  
       122 天前 via Android
    功能实现了吗?实现了就没毛病!毕竟每个人都有自己的骚操作。
    GopherDaily
        19
    GopherDaily  
       122 天前
    你菜
    makersy
        20
    makersy  
       122 天前
    这标题就有问题。MQ 也是 queue ,保证顺序为什么不是 queue 该做的事情?
    milkpuff
        21
    milkpuff  
       122 天前
    楼主说的对。我赞同。
    我觉得楼主的重点在于”把太多的业务解决方案诉诸技术“,这一点指出得准确
    leonshaw
        22
    leonshaw  
       122 天前 via Android
    这是重排,不是保序
    GuangXiN
        23
    GuangXiN  
       122 天前
    MQ 不是 Message Queue 的缩写么? Queue 不保证 FIFO 还叫 Queue 么?
    cp19890714
        24
    cp19890714  
       122 天前
    挖掘业务本质, 是个很难但是非常重要的能力. 这个能力难以通过固有的教程去训练.
    对于人来说, 技术能力可以通过已有的教程文档快速掌握, 自然就会依赖技术.
    PVXLL
        25
    PVXLL  
       122 天前 via iPhone
    都是菜鸡
    ShuWei
        26
    ShuWei  
       122 天前
    通过两条消息的时间差去计算在线时长,这真的是个好的方案么?会不会,这个方案从一开始就是有问题的
    adoal
        27
    adoal  
       122 天前   ❤️ 3
    “我们的系统有个毛病”……你看,你自己都知道是业务系统的毛病,不去解决毛病也就罢了,毕竟屎山不能乱动,以防溅一脸屎汤。人家要在外围用技术手段来把你这业务系统这端的毛病给人家外围附加功能带来的困扰 workaround 掉,你还怪人家做技术做魔怔了。“系统越来越复杂,在错误的道路上越走越远”是“把太多的业务解决方案诉诸技术”导致的吗?你们这群技术不重要业务该被舔的嘤嘤怪,心里真的没有点碧树吗?
    IvanLi127
        28
    IvanLi127  
       122 天前 via Android
    MQ 有复杂的也有简单的,你知道人家说的是什么 MQ 吗?
    neoblackcap
        29
    neoblackcap  
       122 天前   ❤️ 1
    就这样的统计功能都要放在业务系统里面做,那什么系统跑不死啊。登录,登出的事件写日志(进 MQ 再落地也一个道理),直接通过回放日志,简单统计一下当天是否有超过 15 分钟的在线就得了。而且还不会对业务系统产生影响,因为这需求可以做成实时的,也可以做成离线。
    OLAP 的活就不要压业务系统了。
    SeaTac
        30
    SeaTac  
       121 天前
    > 我们的系统有个毛病,可能出现闪登闪退
    不先把系统的问题修一修么
    xuanbg
        31
    xuanbg  
       121 天前
    1 、我不懂闪退为啥还能有登出动作?
    2 、计算在线时长不是应该用 redis 吗?用 MQ 做啥?
    haochih
        32
    haochih  
       121 天前
    你是对的
    jguo
        33
    jguo  
       121 天前   ❤️ 2
    “我喜欢和聪明人交往,因为不用考虑他们的尊严”。讨论技术问题别上来就开启防御姿态。
    lmq2582609
        34
    lmq2582609  
       121 天前
    第一反应是修复这个登入登出的毛病
    me1onsoda
        35
    me1onsoda  
       121 天前
    @yibinhp 一个消费者对应一个 broker
    zsdroid
        36
    zsdroid  
       121 天前
    系统有毛病不管,先来发帖喷一喷别人。op 牛逼。
    msaionyc
        37
    msaionyc  
       121 天前
    “先放着”是什么意思,这条消息怎么处理?
    如果这个消息处理的地方为这个行为做个补丁,其实也等于提高了系统复杂度,后人接手时也会摸不着头脑,为什么这么做
    ecareyu
        38
    ecareyu  
       121 天前
    其实 up 主,你说的压根就是两件事,但也可以说是一件事,就是,产品思维和技术思维,技术一般很难跳出技术思维这个圈,但是很多以产品思维来想,有些事,确实没必要完全通过复杂的技术实现,因为用户根本不会 care 。你要没必要喷那个小伙,毕竟,他只是个技术,你让他往产品想,那属实有点隔行如隔山了。
    zhazi
        39
    zhazi  
       121 天前
    笑死,op 来找认同,结果被按着头喷。
    水平不高的人当 ld 是这样的
    Leviathann
        40
    Leviathann  
       121 天前
    mq 保证的不是入队的顺序吗,入队就是乱的保证什么?
    FrankAdler
        41
    FrankAdler  
       121 天前 via Android
    水平不高的人有话语权是这样的
    block 了
    Habyss
        42
    Habyss  
       121 天前
    可是 mq 单队列单消费者, 本身不就是有序的吗.
    Habyss
        43
    Habyss  
       121 天前
    @Habyss #42 无序的话,
    1. 生产者入队就无序
    2. 消费者做了特殊处理,无序
    3. 多消费者同时处理,无序
    跟 mq 本身没什么关系吧
    Masoud2023
        44
    Masoud2023  
       121 天前
    你们不应该先解决一下闪灯闪退的问题吗
    GeruzoniAnsasu
        45
    GeruzoniAnsasu  
       121 天前
    > 登录的业务本质是什么?就是验证身份,成功之后开启一段会话

    明明你「理解」了本质,怎么还能想出这种结论。


    假设你们的系统真的能先收到登出再收到登录,登出的时候,会话在哪?





    > 么当先收到登出消息时,无非就是发现这个会话没有开始时间么,但是他确实是一个存在的会话啊,没有开始时间就没有好了

    哈? REALLY? 你是凭什么认为这个登出消息能是一个合法消息的?
    qiyilai
        46
    qiyilai  
       121 天前
    为什么非要登出才能统计在线时长?好奇怪
    jdkxnktkdkxod
        47
    jdkxnktkdkxod  
       121 天前
    不能保证顺序的 mq 还能叫 mq 吗?
    venglide
        48
    venglide  
       121 天前
    典型的流处理问题,文不对题。
    StyleTnT
        49
    StyleTnT  
       121 天前
    @zihuyishi 想到了梦幻,不退出登录就不用充点卡。
    kelvin_fly
        50
    kelvin_fly  
       121 天前
    我理解是两个事情。一是发送到 MQ 的 message 本身就顺序有问题,由于网络波动或者其他啥原因。 另一个是 MQ 保证顺序。 最好在 message 中携带业务的时间戳。
    这个计算时长应该业务方自己解决先手顺序,因为只靠 MQ 的顺序也解决不了
    Aresxue
        51
    Aresxue  
       121 天前
    无非就是顺序消息存在的必要性,答案是有必要。只是说不能一股脑地把问题都丢给中间件以为就万事大吉了,10TPS 有 10TPS 的处理方式,1kTPS 有 1kTPS 的,10wTPS 也有 10wTPS 的,就事论事选择最适合业务的。
    totoro52
        52
    totoro52  
       121 天前
    你们的业务好奇怪啊, 计算在线时长,而且是每日任务, 那取当日首次登陆时间,和当前存在时间计算一下不就知不知道满足 15 分钟了吗,
    为什么还要去登出登入什么奇奇怪怪的逻辑,登出才出发任务? 那我一直登着不退出不就不触发这个任务了,难不成你们业务是必须实实在在的计算某一次在线时长满足 15 分钟的?
    nbndco
        53
    nbndco  
       121 天前
    @totoro52 我也想说,在线时间计算还能靠登出这个信号么?我都不记得我上次登出任何东西是什么时候了。
    Mikawa
        54
    Mikawa  
       121 天前
    要不先修一下闪登的问题,然后在线的时候能不能发个心跳包
    来自某个必须要登出才能统计在线的游戏的玩家
    totoro52
        55
    totoro52  
       121 天前
    @nbndco 游戏可能就会频繁涉及登出登入,但以登出作为计算任务的触发点, 我是没想到,这要是发个在线时长奖励活动, 我岂不是还要把游戏重开一下才能领。。
    nuII
        56
    nuII  
       121 天前
    笑死,主要问题来源不是因为闪登闪退吗?这问题不修,搞其他的有用?
    WashFreshFresh
        57
    WashFreshFresh  
       121 天前
    怎么先放着,服务维护重启怎么办,存 redis 还是存库?存的话什么时候取出来,登出的时候取出来?
    业务就是这样一步步搞复杂的。
    Akiya
        58
    Akiya  
       121 天前
    同一个 partition 本来就是保证顺序的。但是 MQ 有序并不能解决你这里秒登秒退的问题。总之 OP 确实有点魔怔
    imokkkk
        59
    imokkkk  
       121 天前
    我理解 如果项目已经引入了 MQ ,用到这里来解决问题也不是不行,如果单纯为了解决这个问题引入 MQ ,那确实没必要额外在运维一个组件。
    herofire
        60
    herofire  
       121 天前
    你是对的!我必需为此点个赞
    palfortime
        61
    palfortime  
       121 天前 via Android
    只有我好奇同一毫秒的登入登出是怎么达成的吗?
    FaustY
        62
    FaustY  
       121 天前
    这辈子登出的次数用一只手都能数得过来,如果符合 lz 的场景的话,新增个接口,前端判断时间够了直接调用会不会好点。
    zhuoyue100
        63
    zhuoyue100  
       121 天前
    怎么能用登陆和登出来统计在线时长? 现在谁还点登出
    iseki
        64
    iseki  
       121 天前
    业务不诉诸技术诉诸什么?无非是不同的取舍而已,别说的这么清新脱俗。虽然我不赞同他的解决方案,但是你这种思想问题更大,他的方案不够严密只是水平问题,你这是路线问题。
    不妨先想想所谓的「业务解决方案」真的只是业务吗。
    qwwe01
        65
    qwwe01  
       121 天前
    入队是无序的话,就算 MQ 保证了也解决不了。除非从发消息到 MQ 到消费都是同一条链路才能保证吧。
    设计的话,为啥不记录下来自己计算一遍就好了
    NoKey
        66
    NoKey  
       121 天前
    讨论一个问题啊,闪退的情况下,有回调发出登出消息么?
    wh0syourda66y
        67
    wh0syourda66y  
       121 天前
    《我们业务有个问题》
    《这样不就行了,想那么复杂干什么》
    《以后出了问题再说》
    《哦,这个问题是因为我们上次为了修复那个问题引进的》
    《你问我为什么不解决根本问题,你懂不懂业务》
    《我离职了,上个公司代码就是个屎山,技术差的要命》
    BQsummer
        68
    BQsummer  
       121 天前
    模型和 flink 的 watermark 挺相似的, 时间时间和消息时间是两回事.
    sunsan05
        69
    sunsan05  
       121 天前
    MQ 需要不需要保证顺序,是架构设计的时候决定的。架构设计的时候怎么决定的,就是考虑异常情况下的处理方案。
    如果你需要顺序的数据并且做计算,
    那么:
    如果 MQ 不需要保证顺序,那就需要 Flink 这种流式计算(或自研)做窗口数据流校验。
    如果你觉得实时数据也没必要,那就改为批处理,同样也是窗口期校验。

    ---

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

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

    个人思路:在登入后按分钟发送心跳包,服务端统计心跳包个数,满足个数后标记该用户“任务已完成”
    这样你消息是否 FIFO 也无关紧要了,我只是想看你到底有没有满足“在线 15 分钟”这个条件而已
    purensong
        77
    purensong  
       120 天前
    看标题进没让我失望,浪费了一分钟
    mysunshinedreams
        78
    mysunshinedreams  
       120 天前
    @sunsan05 #73 即使设定到很低,分布式架构上的假定还是会存在问题
    DefoliationM
        79
    DefoliationM  
       120 天前 via Android
    没学过数据结构?不知道什么叫队列?先进先出不知道?
    258
        80
    258  
       71 天前
    登出?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1438 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 43ms · UTC 17:15 · PVG 01:15 · LAX 09:15 · JFK 12:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.