我要实现一个推单功能了

2023-12-03 15:08
文章标签 实现 我要 单功能

本文主要是介绍我要实现一个推单功能了,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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

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

原因

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

但定时拉单有几个问题,一是时效性问题,如消费方每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语言

这篇关于我要实现一个推单功能了的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/449882

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机