【Jeepay】01-Kafka实现延迟消息与广播模式概要设计

背景介绍

由于公司需要进行公共服务架构调整,决定采用开源的Jeepay项目来构建自身的公共支付服务。
传送门:Jeepay项目github地址

在现有项目的基础上,我们进行了一些业务层面的改造,以更好地适应公司的业务场景。关于这些业务改造的具体内容,在本次专题中不会详细展开。

Jeepay是一套适合互联网企业使用的开源支付系统,支持多渠道服务商和普通商户模式。已对接微信支付,支付宝,云闪付官方接口,支持聚合码支付。

专题想要重点讨论的是:关于Jeepay中MQ的相关功能扩展,以及技术实现细节。

Jeepay天然支持四种MQ,分别为:ActiveMQ、RabbitMQ、AliyunRocketMQ、RocketMQ。

然而,公司的公共服务中选择了Kafka作为消息中间件。我们并不想因为Jeepay的需求而额外引入其他的MQ组件。因此,我们计划通过代码改造的方式,使Jeepay支持Kafka。

以上就是该专题的项目背景,希望可以帮助大家理解后续的讨论内容。


难点分析

阅读接口我们可以得知,Jeepay为集成MQ,提供了如下两个接口进行功能扩展:

1、MQSender接口要求:实现即时发送和延迟发送这两个方法

public interface IMQSender {

		/** 推送MQ消息, 实时 **/
		void send(AbstractMQ mqModel);
		
		/** 推送MQ消息, 延迟接收,单位:s **/
		void send(AbstractMQ mqModel, int delay);

}

2、MQ的发送方式,被抽象成为两种:队列发送和广播发送,都需要Kafka进行实现。

public enum MQSendTypeEnum {
	    /** QUEUE - 点对点  **/
	    QUEUE,
	    /** BROADCAST - 订阅模式  **/
	    BROADCAST
}

在专题开始之前,我觉得我们有必要搞清楚如下两个问题:

1、为什么Jeepay没有集成kafka
2、为什么kafka没有延时发送功能

思考这个两个问题的好处在于:能够帮助于我们在后续的方案设计阶段,快速的找到适合自己的解决方案。


为什么Jeepay没有集成kafka

提到消息中间件,Kafka在某些领域和场景的应用十分广泛。

既然如此,那为什么Jeepay中没有对其进行集成?

我通过对Kafak进行的系统性了解,得出了以下几个结论。个人理解,欢迎讨论和补充。

  1. kafka不能天然支持延迟发送 。
  2. kafka的广播模式的实现,不符合Jeepay的MQ框架标准。
  3. Kafka在大数据领域下具有低延迟、高吞吐的特色 ,但是消息可靠性上并没有提供完善的解决方案。在支付场景中无法发挥出它应有的能力。

为什么kafka没有延时发送

在上个问题中,我们站在应用层的角度,思考了为什么Jeepay没有集成kafka的几点原因。

现在,站在架构的层面上,我们接着思考:为什么kafka没有延时发送呢?

这个问题基于Kafka的底层原理,简要回顾一下:Kafka底层原理剖析

1、kafka 最低结构是一个分区(Partition),它是队列中具有增量偏移量的顺序事件 —— 即在生成日志的那一刻,除了末尾之外,不能在其他任何地方插入日志,没有延迟消息的概念。

2、除此之外,kafka 的定位是实时流处理平台,延时发送功能在业务应用场景上,也没有什么特别的必要。

所以,想要实现延时发送,底层天然不支持。

因此,我们只能尝试从外围改造,来解决这个问题。

定时发送和延时发送都是绝对时间,虽然 kafka 内部有用到时间轮的概念,但仅依靠时间轮,对于解决延时发送还是过于简单。在面对这个问题时,我们首先需要明白如下几个难点:

1、因为延时任务存在不可预期性,有的可能是十分钟后执行,有的可能是是半年或者一年后执行。这种情况下直接使用单个时间轮会导致圈数过大。

2、一个槽中的所有任务分发也是比较复杂的逻辑。

在寻找解决方案的时候,我们参考了RocketMQ的实现方式:RocketMQ只持特定的延时时间段:1s, 5s, 10s … 2h。不支持任意时间段的延时。因此,我们可以总结出两种解决延时发送问题的思路:

1、如果业务场景并不包括实时的大数据流处理的场景,且延时的时间跨度不大,我们可以把延迟消息存储到某种介质中,这种介质可以是key-value数据库、可以是redis缓存,可以是内存中的hashmap等等… 但这样做,性能方面肯定大打折扣。

2、如果从生产的角度,考虑性能的前提下,最极限的解决方案就是参考RocketMQ的实现方式。

最终,在进行权衡后,我们选择了第一种解决方案:利用Redis的有序集合(Zset)构建缓存队列,将延迟消息存储其中,从而实现延时发送功能。


下一章我们继续讨论:02-Kafka实现延迟消息与广播模式详细设计

以上就是帖子的全部内容啦,关注我,我会定期更新,期待与你的共同进步!

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值