平安保险基于 SPI 机制的 RocketMQ 定制化应用

Posted 阿里巴巴云原生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了平安保险基于 SPI 机制的 RocketMQ 定制化应用相关的知识,希望对你有一定的参考价值。

第二点,业务系统的使用场景会特别多,使用场景广泛带来的问题就是会创建大量的 topic,所以这时候就得去衡量消息中间件在多 topic 场景下性能是否能满足需求。我自己在测试的时候呢,用 1K 的消息随机往 1 万个 topic 写数据,单 broker 状态下能达到2W左右的 TPS,这一点比 Kafka 要强很多。所以多 topic 应用场景下,性能依旧强悍是我们选用 topic 的第二个原因。这点也是由底层文件存储结构决定的,像 Kafka、RocketMQ 这类消息中间件能做到接近内存的读写能力,主要取决于文件的顺序读写和内存映射。RocketMQ 中的所有 topic 的消息都是写在同一个 commitLog 文件中的,但是 Kafka 中的消息是以 topic 为基本单位组织的,不同的 topic 之间是相互独立的。在多 topic 场景下就造成了大量的小文件,大量的小文件在读写时存在一个寻址的过程,就有点类似随机读写了,影响整体的性能。

3
RocketMQ 支持事务消息、顺序消息、消息消费失败重试、延迟消息等,功能比较丰富,比较适合复杂多变的业务场景使用

4
另外,在选用消息中间件时也要考虑下社区的活跃度和源码所使用的开发语言,RocketMQ 使用 Java 开发,对 Java 开发人员就比较友好,不管是阅读源码排查问题还是在 MQ 的基础上做二次开发都比较容易一点。社区里同学大都是国内的小伙伴,对大家参与 RocketMQ 开源贡献也是比较亲近的,这里呢也是希望更多的小伙伴能参与进来,为国内开源项目多做贡献。


介绍完为什么选用 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 的并发消费和顺序消费。接下来呢给大家分享下如何根据这个配置文件来初始化生产者消费者。首先给大家先介绍下我们抽象出来的客户端加载的一个核心流程。

图中大家可以看到,客户端的核心流程我们抽象成了三部分,分别是启动期、运行期和终止期。首先加载配置文件呢就是加载刚刚介绍的那个配置文件模型,在配置与应用完全解耦的状态下,必须先加载完配置文件才能初始化后续的流程。在初始化生产者和消费者之前应当先创建好应用实现的生产者和消费者的业务逻辑对象 供生产者和消费者使用。在运行期监听配置文件的变化,根据变化动态的调整生产者和消费者实例。这里还是要再强调下配置与应用的解耦为动态调整提供了可能。终止期就比较简单了,就是关闭生产者和消费者,并从容器中移除。这里的终止期指的生产者和消费者的终止,并不是整个应用的终止,生产者和消费者的终止可能出现在动态调整的过程中,所以终止了的实例一定要从容器中移除,方便初始化后续的生产者和消费者。介绍完基本流程后,接下来给大家介绍下配置文件的加载过程。

1
配置文件加载这一块的话,流程是比较简单的。这里主要讲的是如何去兼容比较老的项目。RocketMQ 客户端支持的 JDK 最低版本是 1.6,所以在封装客户端时应该要考虑到新老项目兼容的问题。在这里呢我们客户端的核心包是支持 JDK1.6 的,spring 早期的项目配置文件一般都是放在在 resources 路径下,我们是自己实现了一套读取配置文件的和监听配置文件的方法,具体的大家可以参考 acl 中配置文件的读取和监听。在核心包的基础上用 springBoot 又封装了一套自动加载配置文件的包供微服务项目使用,配置文件的读取和监听都用的 spring 的那一套。配置文件加载完之后, 配置文件中应用实现的生产者和消费者是如何与 RocketMQ 的生产者和消费者相关联的呢?接下来给大家分享下这方面的内容。

2
首先先看下消费者是如何实现关联的,上图是 MQ 消费者的消息监听器,需要我们去实现具体的业务逻辑处理。通过将配置文件中实现的消费逻辑关联到这里就能实现配置文件中的消费者与 RocketMQ 消费者的关联。消费者的接口定义也是很简单,就是去消费消息。消费消息的类型可以通过泛型指定,在初始化消费者的时候获取具体实现的参数类型,并将


RocketMQ RocketMQ 5.0 全新升级:

消息、事件、流融合处理平台




Java中的SPI机制

  • 什么是SPI

  SPI全程为Service Provider Interface,服务提供接口,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。

  技术图片

   Java SPI本质上其实就是“基于接口编程+策略模式+配置文件”组合实现的动态加载机制。

  • 什么时候用SPI

  在面向对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可插拔的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候不用在程序里动态指明,这就需要一种服务发现机制。Java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。

  很多开源框架中都采用了SPI思想,比如jdbc(Java 规定了JDBC的接口,可由不同厂商来实现MySQL,Oracle等),开源工具箱Geotools里面的DataStoreFactorySpi,我们可以自己去实现不同的DataStoreFactory,来支持不同数据引擎。

  • Java SPI的约定

  当服务的提供者提供了服务接口的一种实现之久,在jar包的META-INF/Services/目录中同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/Services/的配置文件找到具体的实现类名。并装载实例化,完成模块的注入。基于这样的一个约定就能很好的找到服务接口的实现类,而不需要在代码里指定。

  以Geotools的DataStoreFactorySpi为例,我们在org.geotools.data包里定义了接口

  技术图片

  我们在另一包里提供了关于PostGIS的实现PostgisNGDataStoreFactory

技术图片

 

  同时在jar包的META-INF/Services/目录中同时创了建一个以服务接口命名的文件,并约定了实现类名如下:

       技术图片

  技术图片

  同时提供一个查找所有实现类的工具:DataAccessFinder,客户端可以使用该工具获取到所有实现该接口的类,而不需要对类进行硬编码,这样的一个好处就是我们在jar中替换了DataStoreFactorySpi的实现类后,不会对客户端的编码产生任何影响。

  • 综上

  SPI就是一种将服务接口与服务实现分离以达到解耦、大大提升了程序可扩展行性的机制。引入服务提供者就是引入了SPI接口的实现者,通过本地注册来发现获取到具体的实现类。实现轻松可插拔。

  • 一个应用案例

  

 

  

 

以上是关于平安保险基于 SPI 机制的 RocketMQ 定制化应用的主要内容,如果未能解决你的问题,请参考以下文章

平安保险基于 SPI 机制的 RocketMQ 定制化应用

FlinkFLink PipelineExecutorFactory 基于工厂模式的任务提交与SPI机制

Java中的SPI机制

Dubbo SPI

Java SPI机制简介

Java SPI 机制详解