zoukankan      html  css  js  c++  java
  • 应用层的消息确认机制的思考

    最近在开发一个基于Netty通信框架的服务器,因为之前没有这方面的开发经验,所以有很多想法和问题,一个困扰我很久的,就是怎么做一个消息确认机制,确保消息的可靠传输。

    我想做的消息确认机制是这样的:当服务器向客户端发送消息的时候,会附有一个消息的ID标识,当消息到达客户端的时候,客户端会立刻返回确认已经接收到这个ID标识的消息,这个时候服务器就确定客户端接收到了这条消息。

    但是当因为网络状况(因为我对网络并没有特别深入的研究,所以我对网络问题模糊称为网络状况)不佳的时候,可能客户端就没有收到这条消息(粗略的认为是在某个位置丢失了,我也不知道这个说法是否准确,希望了解的大佬指点一下)。

    我的想法是服务器这边做一个定时器,发出特定ID消息之后,做一个定时器, 假设是三分钟,当三分钟之后没有收到客户端确认这条ID的消息,就认为是网络原因导致客户端没有办法收到,但是我要再尝试发一次。于是服务器会再发一次同样ID的消息,再次等待三分钟,三分钟之后还没收到确认,就再重发一次,如果第三次发出的消息三分钟后还没有收到确认消息,我就认为这条消息客户端永远不会收到了,就把它保存起来另行处理。

    最初的想法是为每条消息做一个定时任务,使用Quartz,发出的每一条消息的同时都增加一个triger任务,但这样做可能系统里会存留太多的triger,就当前的需求来说不会有太大问题,但这不是核心业务,我需要一个更轻量级一点的解决办法。

    随后群里大佬有推荐我用消息队列或自己实现一个环形队列,我之前没有用过消息队列,所以开始学习,思路是系统发出消息之前先把消息放到队列里去,确认消息来了之后从队列里取出来该消息,如果没收到,就一直放着再做处理。但学着发现,消息队列是队列啊,遵循FIFO的原则,所以在同一个队列里没有一个索引ID,我没办法指定消费队列里的某一条消息,总不能把每个消息都单独弄成一个队列吧。

    采用延时队列,把收到的确认消息保存起来,当三分钟过去之后消费消息,检查保存的确认消息(可以放到Map里也可以放到数据库里)中是否有这条消息的ID,如果失败就重发并重新加入队列。这看上去是一个能满足当前机制的途径,但看起来还是很笨重,毕竟这套确认消息机制的最初想法是为了满足小概率的事件,当网络不佳的时候或者是和客户端失去连接的时候,但是当客户端断开连接的时候服务器是能侦测到的,即是在发送消息失败的时候才感知到也是另一套处理方案(比如把未发送的消息存到数据库等下次连接的时候再考虑是否发送),而不应该通过这套消息确认机制。

    现在想一想我是想在应用层上作出一个可靠消息传输机制,但是这个想法本身是否是过度设计,因为消息确认机制不是我业务的核心内容,但是可能会占据资源,而且只有在很小概率的情况下能起到作用,或者根本不起作用。在网络结构中,运输层的层面上有对报文传送的可靠传送方式,在应用层上又去增加一层可靠性机制是不是很多余,如果大家有什么看法,希望能提供宝贵的意见。

  • 相关阅读:
    pytorch中的torch.autograd.backward()和torch.autograd.grad()
    深度学习中的归一化方法BN、LN、IN、GN
    PostgreSQL函数和操作符
    IDEA中cannot_resolve_method?
    IDEA 打开后很卡?
    win10磁盘分区
    PostgreSQLの交-并-差集(INTERSECT、UNION、EXCEPT)
    oracleの交-并-差集(INTERSECT、UNION /UNION ALL 、MINUS)
    秋招总结
    产品经理面试问题及答案大全《一》
  • 原文地址:https://www.cnblogs.com/ffaiss/p/10476574.html
Copyright © 2011-2022 走看看