简介:本文讲讲述平安保险为何抉择 RocketMQ,以及在确定应用消息中间件后,又是如何去抉择哪款消息中间件的。
作者:孙园园|安全人寿资深开发
为什么选用 RocketMQ
首先跟大家聊聊咱们为什么会选用 RocketMQ,在做技术选型的过程中,利用场景应该是最先思考分明的,只有确定好了利用场景在做技术选型的过程中才有明确的指标和掂量的规范。像异步、解耦、削峰填谷这些消息中间件共有的个性就不一一介绍了,这些个性是决定你的场景需不需要应用消息中间件,这里次要讲述下在确定应用消息中间件后,又是如何去抉择哪款消息中间件的。
同步双写,确保业务数据安全可靠不失落
咱们在搭建消息中间件平台时的定位是给业务零碎做业务数据的传输应用,对业务数据的很重要的一个要求就是不容许丢数据,所以选用 RocketMQ 的第一点就是他有同步双写机制,数据在主从服务器上都刷盘胜利才算发送胜利。同步双写条件下,MQ 的写入性能与异步刷盘异步赋值相比必定会有所降落,与异步条件下大概会有 20% 左右的降落,单主从架构下,1K 的音讯写入性能还是能达到 8W+ 的 TPS,对大部分业务场景而言性能是能齐全满足要求的,另外对降落的这部分性能能够通过 broker 的横向扩招来补救,所以在同步双写条件下,性能是能满足业务需要的。
多 topic 利用场景下,性能仍旧强悍
第二点,业务零碎的应用场景会特地多,应用场景宽泛带来的问题就是会创立大量的 topic,所以这时候就得去掂量消息中间件在多 topic 场景下性能是否能满足需要。我本人在测试的时候呢,用 1K 的音讯随机往 1 万个 topic 写数据,单 broker 状态下能达到 2W 左右的 TPS,这一点比 Kafka 要强很多。所以多 topic 利用场景下,性能仍旧强悍是咱们选用 topic 的第二个起因。这点也是由底层文件存储构造决定的,像 Kafka、RocketMQ 这类消息中间件能做到靠近内存的读写能力,次要取决于文件的程序读写和内存映射。RocketMQ 中的所有 topic 的音讯都是写在同一个 commitLog 文件中的,然而 Kafka 中的音讯是以 topic 为根本单位组织的,不同的 topic 之间是互相独立的。在多 topic 场景下就造成了大量的小文件,大量的小文件在读写时存在一个寻址的过程,就有点相似随机读写了,影响整体的性能。
反对事务音讯、程序音讯、提早音讯、音讯生产失败重试等
RocketMQ 反对事务音讯、程序音讯、音讯生产失败重试、提早音讯等,性能比拟丰盛,比拟适宜复杂多变的业务场景应用
社区建设沉闷,阿里开源零碎
另外,在选用消息中间件时也要思考下社区的活跃度和源码所应用的开发语言,RocketMQ 应用 Java 开发,对 Java 开发人员就比拟敌对,不论是浏览源码排查问题还是在 MQ 的根底上做二次开发都比拟容易一点。社区里同学大都是国内的小伙伴,对大家参加 RocketMQ 开源奉献也是比拟亲热的,这里呢也是心愿更多的小伙伴能参加进来,为国内开源我的项目多做奉献。
SPI 机制简介及利用
介绍完为什么选用 RocketMQ 后,接下来给大家介绍下咱们是如何基于 SPI 机制利用 RocketMQ 的。SPI 全称为 (Service Provider Interface),是 JDK 内置的一种服务提供发现机制,我集体简略了解就是面向接口编程,留给使用者一个扩大的点,像 springBoot 中的 spring.factories 也是 SPI 机制的一个利用。如图给大家展现的是 RocketMQ 中 SPI 的一个利用。咱们基于 SPI 机制的 RocketMQ 客户端的利用的灵感也是来自于 MQ 中 SPI 机制的利用。RocketMQ 在实现 ACL 权限校验的时候,是通过实现 AccessValidator 接口,PlainAccessValidator 是 MQ 中的默认实现。权限校验这一块,可能因为组织架构的不一样会有不同的实现形式,通过 SPI 机制提供一个接口,为开发者定制化开发提供扩大点。在有定制化需要时只须要从新实现 AccessValidator 接口,不须要对源码大动干戈。
接下来先给大家介绍下咱们配置文件的一个简略模型,在这个配置文件中除了 sendMsgService、consumeMsgConcurrently、consumeMsgOrderly 这三个配置项外其余的都是 RocketMQ 原生的配置文件,发送音讯和生产音讯这三个配置项呢就是 SPI 机制的利用,是为具体实现提供的接口。可能有的同学会有疑难,SPI 的配置文件不是应该放在 META-INF.service 门路下么?这里呢咱们是为了不便配置文件的治理,索性就跟 MQ 配置文件放在了一起。后面也提到了,META-INF.service 只是一个默认的门路而已,为了方便管理做相应的批改也没有违反 SPI 机制的思维。
咱们再看下这个配置文件模型,这里的配置项呢囊括了应用 MQ 时所要配置的所有选项,proConfigs 反对所有的 MQ 原生配置,这样呢也就实现了配置与利用实现的解耦,利用端只需呀关注的具体的业务逻辑即可,生产者消费者的实现和消费者生产的 topic 都能够通过配置文件来指定。另外该配置文件也反对多 nameserver 的多环境应用,在较简单的利用中反对往多套 RocketMQ 环境发送音讯和生产多套不同环境下的音讯。消费者提供了两个接口次要是为了反对 RocketMQ 的并发生产和程序生产。接下来呢给大家分享下如何依据这个配置文件来初始化生产者消费者。首先给大家先介绍下咱们形象进去的客户端加载的一个外围流程。
客户端外围流程详情
图中大家能够看到,客户端的外围流程咱们形象成了三局部,别离是启动期、运行期和终止期。首先加载配置文件呢就是加载刚刚介绍的那个配置文件模型,在配置与利用齐全解耦的状态下,必须先加载完配置文件能力初始化后续的流程。在初始化生产者和消费者之前该当先创立好利用实现的生产者和消费者的业务逻辑对象 供生产者和消费者应用。在运行期监听配置文件的变动,依据变动动静的调整生产者和消费者实例。这里还是要再强调下配置与利用的解耦为动静调整提供了可能。终止期就比较简单了,就是敞开生产者和消费者,并从容器中移除。这里的终止期指的生产者和消费者的终止,并不是整个利用的终止,生产者和消费者的终止可能呈现在动静调整的过程中,所以终止了的实例肯定要从容器中移除,不便初始化后续的生产者和消费者。介绍完根本流程后,接下来给大家介绍下配置文件的加载过程。
如何加载配置文件
配置文件加载这一块的话,流程是比较简单的。这里次要讲的是如何去兼容比拟老的我的项目。RocketMQ 客户端反对的 JDK 最低版本是 1.6,所以在封装客户端时应该要思考到新老我的项目兼容的问题。在这里呢咱们客户端的外围包是反对 JDK1.6 的,spring 晚期的我的项目配置文件个别都是放在在 resources 门路下,咱们是本人实现了一套读取配置文件的和监听配置文件的办法,具体的大家能够参考 acl 中配置文件的读取和监听。在外围包的根底上用 springBoot 又封装了一套主动加载配置文件的包供微服务项目应用,配置文件的读取和监听都用的 spring 的那一套。配置文件加载完之后,配置文件中利用实现的生产者和消费者是如何与 RocketMQ 的生产者和消费者相关联的呢?接下来给大家分享下这方面的内容。
如何将生产消费者与业务实现关联
首先先看下消费者是如何实现关联的,上图是 MQ 消费者的音讯监听器,须要咱们去实现具体的业务逻辑解决。通过将配置文件中实现的生产逻辑关联到这里就能实现配置文件中的消费者与 RocketMQ 消费者的关联。消费者的接口定义也是很简略,就是去生产音讯。生产音讯的类型能够通过泛型指定,在初始化消费者的时候获取具体实现的参数类型,并将 MQ 承受到的音讯转换为具体的业务类型数据。由客户端对立封装好消息类型的转换。对生产音讯的返回值大家能够依据须要与 MQ 提供的 status 做一个映射,这里的 demo 只是简略显示了下。在获取具体的利用消费者实例的时候,如果你的生产逻辑里应用了 spring 治理的对象,那么你实现的生产逻辑对象也要交给 spring 治理,通过 spring 上下文获取初始化好的对象;如果你的生产逻辑里没有应用 spring 进行治理,能够通过反射的形式本人创立具体的利用实例。
与消费者不一样的是生产者须要将初始化好的 producer 对象传递到利用代码中去,而消费者是去获取利用中实现的逻辑对象,那如何将 producer 传递到业务利用中去呢?
业务代码中实现的生产者须要继承 SendMessage,这样业务代码就取得了 RmqProducer 对象,这是一个被封装后的生产者对象,该对象对发送音讯的办法进行的规范化定义,使之合乎公司的相应标准制度,该对象中的办法也会对 topic 的命名标准进行查看,标准 topic 有一个对立的命名标准。
如何动静调整生产消费者
首先谈到动静调整就须要谈一下动静调整产生的场景,如果没有适合的应用场景的话实现动静调整就有点金玉其外; 败絮其中了。这里我列举了四个配置文件发生变化的场景:
nameserver 发生变化的时候,须要从新初始化所有的生产者和消费者,这个个别是在 MQ 做迁徙或者以后 MQ 集群不可用是须要紧急切换 MQ;
增减实例的场景只有启动或敞开相应的实例即可,减少利用实例的场景个别是在须要减少一个消费者来生产新的 topic 的,缩小消费者个别是在某个消费者产生异样时须要紧急敞开这个消费者,及时止损。
调整消费者线程的场景中咱们对源码进行了一点批改,让利用端能获取到消费者的线程池对象,以便对线程池的外围线程数进行动静调整。这个的利用场景个别是在当某个消费者生产的数据比拟多,占用过多的 CPU 资源时,导致优先级更高的音讯得不到及时处理,能够先将该消费者的线程调小一些。
利用的长处
原文链接
本文为阿里云原创内容,未经容许不得转载。