我要实现一个推单功能了

简介: 以前都是作为消息接收方,接收消息。记得当时做支付的时候,接收第三方支付公司的各种消息,如支付成功、支付失败、退款成功、退款失败。

以前都是作为消息接收方,接收消息。记得当时做支付的时候,接收第三方支付公司的各种消息,如支付成功、支付失败、退款成功、退款失败。

有的公司在消息推送的准确性与及时性方面做的很好,有的就很差,尤其是几家欧洲公司,如果我方消费失败,该消息会阻塞在队头,导致整个消费队列卡住,无法消费后面消息,引起我们的各种吐槽。

天道好轮回,苍天饶过了谁,终于轮到我当发送方了。虽然这个项目难度不是很高,但这是自己第一个推送相关的项目,所以记录一下。

原因

本来提供了拉单功能,消费方可定时拉单。

但定时拉单有几个问题,一是时效性问题,如消费方每N分钟拉取一次数据,则最大延迟为N分钟,时效性不好;二是拉取到的订单信息可能不全,对于信息不全的订单,消费方需要定时重新获取,增加了复杂性。

推单方案则能解决以上问题,首先只有信息完整才推单,其次是信息完整后立即推单。这既能保证时效性,同时也能降低对接复杂度。

方案调研

以前没做过推单功能,仔细想了一下,需要先调研三方面内容:推送什么内容、如何推送、推送失败如何处理。

推送内容

如何确定给消费方推送的内容呢?

通过与消费方沟通、咨询公司业务方、调查竞品,确定好推送内容。

不过仍有未考虑到的地方,在与接收方联调推单模式时,有的接收方想要批量推送功能。

目前设计为一单一单推送,基于现状也不会做批量推送功能,还是因为时效性问题,有消息就尽快推送给接收方,接收方收到后尽快流转。批量推送会让整体时效降低,而且实现上也会更加复杂。

但这个示例说明调研上有缺漏,今后可多调研几家,有些需求可以选择不做,但要知晓需求。

如何推送

如何将数据推送出去呢?

当然得有个平台!因为推送要考虑很多细节,如数据安全、异常处理、接口管理等,好在有部门已经做了推送的管理平台。提供出两种方案,同步方案和异步方案。

同步方案

同步方式,是消息发送方,直接调用接收方接口,能够立即感知结果

异步方案

异步方式,接收方将消息推送到消息队列,接收方按需进行消费

区别

同步和异步方式有如下区别

  1. 同步方式可直接知道接收方处理结果;异步方式无法知道处理结果
  2. 同步方式由发送方保证消息推送成功;异步方式由接收方自行保证

异步方式在设计上,只支持同类型的消息推送给同一个接收方,但商家订单属于不同接收方,使用异步方式会导致信息泄露。而且异步方式也无法知道消息接收情况,所以最终选择同步方案。

异常处理

推送流程比较简单,消费mq消息,给接收者推送订单信息。我们永远不要相信网络和接收方,总是出现各种各样的问题,当消息消费失败后如何处理呢?

当然希望Consumer在消费消息包的时候,如果出现一些异常,希望消息包不被直接丢弃,而是可以过段时间继续消费,同时不产生阻塞。简单来说就是重试。

rabbitmq

以前用的rabbitmq,消费异常后,可以将消息包重新放入主队列的队尾,有两种方案:

死信队列
  • basic_consume设置ack模式
  • 声明死信队列,设置x-message-ttl=30000x-dead-letter-routing-key=主队列名
  • 声明主队列,设置x-dead-letter-routing-key=死信队列名
  • 主队列通过RoutingKey绑定到Exchange

如果消费逻辑出现异常,消费脚本会调用basic\_reject(),消息包会被RabbitMQ Requeue到死信队列中。30s超时后,消息包会重新进入主队列的队尾。

重新投递

通过chanel.basicAck(tagId, false)与chanel.basicPublish(message.getMessageProperties().getReceivedExchange(), message.getMessageProperties().getReceivedRoutingKey(), true, MessageProperties.PERSISTENT\_TEXT\_PLAIN, body.getbytes()); 搭配可将消息放回消息队尾,这两个函数一个不再将未被确认的消息发送回队列,一个用于重新投递消息。

rocketmq

现在公司使用的rocketmq,基于我对rocketmq的理解,它也是可以进行无阻塞重试的,因为有重试队列嘛:

重试队列

消费失败后,消息会进入到 RocketMQ 的重试队列中。

  • 比如说消费者所属的消息组名称为AAAConsumerGroup
  • 其重试队列名称就叫做%RETRY%AAAConsumerGroup
  • 重试队列中的消息过一段时间会再次发送给消费者,如果还是无法正常执行会再次进入重试队列
  • 默认重试16次,还是无法执行,消息就会从重试队列进入到死信队列

因为公司对rocketmq做了一些更改,所以找同学确认重试机制。问了很多同学,大家都说是阻塞性重试,消息阻塞在队头,直到重试成功或达到重试上限。没办法,只能再找对应的研发同学进行确认。

原来他们设计了两种配置,消息有序和消息无序。在有序情况下,消费失败后会阻塞在队头,直到重试成功;无序情况下,会进入重试队列,根据设置的重试间隔和重试次数进行重试,不会阻塞。如此一来,重试问题也解决了。

之所以关注这一点,是因为阻塞性重试会导致后面的消息无法推送,对功能产生影响。

而且即使是非阻塞性重试,也最好设置重试上限,如果异常太多,容易导致消息生产方压力过大,产生崩溃。需要明白多次投递失败的责任方在接收者。

监控

项目上线后,需要进行监控,否则无法感知运行情况。数据团队同学给力,很快整理好报表,能够实时查看推单成功数量、推单失败数量、订单信息完整时间、推单失败细节。

通过这些数据,能快速发现隐藏问题,也能分析出各接收方的情况,有的接收方确实是一言难尽。

发展

项目上线后,能够确定订单信息完整时间,并能在订单信息完整后,将数据推送给相关方。

后续会优化拉单功能,保证拉到的订单都是完整订单,同时会更改系统中判断信息完整的逻辑,将判断模块做简化和收敛,为今后的系统更新做好准备。

资料

  1. 消息队列RocketMQ版消费消息失败是否会重新消费
  2. 消息队列中消息消费失败后的处理机制
  3. rabbitmq消息重回队列
  4. rabbitmq重试机制
  5. RabbitMQ的消息确认机制
  6. 团队使用RabbitMQ几个场景
  7. https://www.rabbitmq.com/documentation.html
  8. rabbitmq死信队列
  9. RabbitMQ 死信队列 + TTL介绍
  10. RocketMQ 死信队列 | 消费者出现异常如何处理?
  11. RocketMQ消费消息失败的处理办法

最后

大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)

我的个人博客为:https://shidawuhen.github.io/

往期文章回顾:

  1. 设计模式
  2. 招聘
  3. 思考
  4. 存储
  5. 算法系列
  6. 读书笔记
  7. 小工具
  8. 架构
  9. 网络
  10. Go语言
相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
8月前
|
存储 搜索推荐 NoSQL
抖音是怎么做到不重复推荐内容呢?
抖音是怎么做到不重复推荐内容呢?
|
8月前
当前年-往后推5年
当前年-往后推5年
25 0
|
机器学习/深度学习 编解码 人工智能
腾讯的这个算法,我搬到了网上,随便玩!
腾讯的这个算法,我搬到了网上,随便玩!
腾讯的这个算法,我搬到了网上,随便玩!
|
测试技术 定位技术
1424:我要送人头
题目描述: 废话他呆了,打了那么久DOTA 2 ,没见过这样的局。队友手了炸弹人和小娜迦,这局是要拖到什么时候啊。因此,废话决定要不停地送人头,让对面赶紧结束这场令他煎熬的比赛。 废话现在有一个软件,可以让他的英雄按照输入的矩阵行走。已知DOTA 2的地图是一个正方形,他只要输入单位转置矩阵就可以无限送人头了。
59 0
|
JavaScript 前端开发 数据可视化
字节不给大伙发月饼?🎑那我亲自给大伙发!🥮人人都有!
字节不给大伙发月饼?🎑那我亲自给大伙发!🥮人人都有!
|
分布式计算 大数据 Hadoop
【合集】想要轻松玩转阿里云?这里干货请收下!
在这里你可以寻找你想要的所有干货,带你一图了解阿里云!
253 0
【合集】想要轻松玩转阿里云?这里干货请收下!
|
SQL XML 安全
拼搏百天我要日站——思路
第一步做的就是信息收集,正所谓知己知彼百战百胜,我们根据网站URL可以查出一系列关于该网站的信息。通过URL我们可以查到该网站的IP、该网站操作系统、脚本语言、在该服务器上是否还有其他网站等等一些列的信息。更多的关于信息收集,我在另一篇文章中很详细的介绍了信息收集需要收集哪些信息,以及信息收集过程中需要用到的工具,传送门——> 渗透测试之信息收集
111 0
|
Web App开发 移动开发 前端开发
淘宝的互动项目,为什么总会刷爆你的好友圈?
最近一直在思考一个问题:“在互动团队这么多年了,什么样的互动项目是有温度的呢?又应该如何构建有温度的互动项目呢”?想了很久,接下来以我自己角度的理解来尝试着回答,如果回答不对之处,还请路过的大神拍砖指正。
1063 0
淘宝的互动项目,为什么总会刷爆你的好友圈?
网页端收消息,究竟是推还是拉?
任何脱离业务的架构设计都是耍流氓。网页端收消息,究竟是推还是拉?
661 0
作为一枚学生党,如何快速通过拉好友赚取生活费!
一年一度的双11又开始了,每年的活动你估计都想剁自己的手,但是,今年,你会发现一个清奇的活动,不仅能一分钱不花,还能赚钱。 今年的阿里云双11,跟往年不一样,今年采取拼团方式,让大家利用身边的好友来赚取红包和返现。