消息中间件有哪些(消息中间件有哪些,分别有啥用)

今天,我们讨论面向消息的中间件的一些关键特性。关于消息中间件基础知识的文章很多,包括各种开源消息中间件的比较和选择,这里就不赘述了。因此,本文只选取了消息中间件

聊聊消息中间件的关键特性和问题总结

今天,我们讨论面向消息的中间件的一些关键特性。关于消息中间件基础知识的文章很多,包括各种开源消息中间件的比较和选择,这里就不赘述了。

因此,本文只选取了消息中间件的一些关键特性,并总结了实践中的一些常见问题。

兼顾消息发布、订阅和排队。

聊聊消息中间件的关键特性和问题总结

点对点队列模式消息模式点对点队列模式消息模式

聊聊消息中间件的关键特性和问题总结

发布订阅模型Topic消息模型订阅模型主题消息模型

消息中间件有一个关键能力,就是一对多的消息发布和订阅模式。因此,消息中间件通常有两种能力,一种是队列消息队列能力,另一种是主题消息主题能力。对于消息主题,即消息主题模式,支持消息的发布和订阅。

对于队列模式的消息,如果它们被消耗了,那么无论哪个消息端消耗了它们,它们都将被从队列中清除。对于主题模式,如果单个订阅者收到消息,则消息不会被清除,但所有订阅者都需要使用该消息。

那么我们来看一个最简单的场景,就是ERP系统需要分发消息给CRM和SRM。因此,启用消息发布模式,并建立消息主题,例如帐户分配消息。同时,SRM和CRM系统是消息的订阅者,因此在订阅者处编写相应的侦听器来订阅消息。如下所示:

聊聊消息中间件的关键特性和问题总结

但是,CRM和SRM都是集群部署,每个应用程序都有三个集群节点。每个节点在启动时都订阅并监视消息主题。

然后,当ERP分配帐户时,如果常规模式变得相同,消息将被所有六个订户获得。此时,对于CRM系统中的三个集群来说,很明显三次获取的消息是重复的。因此,我们需要,对于订阅者,在一个集群包内,只要一个节点收到消息,该消息就应该被清除。但是不同的集群组之间,应该还是话题模式。

因此,在消息中间件的实现中,需要对集群节点有进一步的分组能力。比如上面的CRM和SRM,就要分成两组,通常称为ClientID。通过ClientID分组,可以实现组间话题能力,而组内启用队列模式。

不同消息中间件的实现思路基本相同,就是都需要一个ClientID分组的概念。

比如虚拟话题的功能就是在ActiveMQ中实现的。使用起来非常简单。对于新闻发布者来说,是很正常的话题,名字以VirtualTopic开头。例如VirtualTopic。试验..

对于消息接收者,它是一个队列。在不同的应用中使用不同的前缀作为队列的名称,可以表明自己的身份,实现消费类应用的分组。例如,消费者。A.VirtualTopic.TEST表明它是一个名为A的消费者,同样,也是消费者。B.VirtualTopic.TEST表示它是一个名为b的客户端。

可以在同一个应用中使用多个消费者来消费这个队列,然后就可以实现上面两个功能了。因为不同的应用程序使用不同的队列名称(前缀不同),所以所有消息都可以在不同的应用程序中接收。每个客户端相当于一个持久订阅者,这个客户端可以使用多个消费者来分担消费任务。

兼顾消息发布、订阅和路由。

再进一步说消息发布和订阅,还是基于前面的场景,ERP分发账户信息。目前,有两个订户,SRM和CRM。但还是会有一些特别的场景:

比如CRM收到消息,但自身处理问题导致消息丢失,需要ERP系统重新发送消息。其次,有些会计科目可能只有SRM系统可以使用,需要定向,只发送到SRM系统。那么在这种情况下,一个话题主题往往无法支撑这个需求。当然,不同的路由规则可以建立不同的主题,但是如果路由规则复杂,建立大量的主题是不现实的。

聊聊消息中间件的关键特性和问题总结

而类似的主流基于JMS的消息中间件往往不具备主题+路由规则的消息传递能力,只能通过新的接口来处理。或者消息仍然按照传统的规则分发,如果订阅者收到的消息确实不需要或者已经存在,就自行丢弃。

至于RabbitMQ,我们可以看到有专门的话题交流模式。主题交换根据路由关键字和交换的类型将消息发送到一个或多个队列,并可以实现发布/订阅模式,即发布和订阅。类似下图:

聊聊消息中间件的关键特性和问题总结

可靠性和消息持久性。

在整个技术架构中引入消息中间件后,虽然达到了异步解耦的效果,但实际上增加了整个集成架构的复杂度,影响了整个架构的可靠性。

至于如何增加消息中间件的可靠性,一个方面是高可用性集群架构,另一个方面是消息本身要支持持久存储。确保消息不会因为消息的持久存储而丢失。

聊聊消息中间件的关键特性和问题总结

一般来说,消息持久化可以分为两类:文件和数据库。文件本身分为两种方式:本地磁盘文件和共享文件系统。

在本地磁盘模式下,可以看到,如果当前Broker节点宕机,虽然可以将消息临时存储在本地,但是在当前节点被手动恢复之前,消费者无法及时获取消息。这个问题的实际解决方案是启用类似主从的部署架构,即消息会快速实时同步到从节点。这样,即使主节点无法访问,订户也可以快速从从节点获取消息。

对于共享文件系统或数据库模式,实际消息只在一个集中的地方持久化,所以不存在消息多点复制的操作。如果一个节点发生故障,共享的存储消息可以快速恢复到其他冗余节点。

分布式交易

我们讨论了基于消息中间件的消息一致性的实现,如下:

场景:在采购系统中准备采购订单时,需要在本地成功保存单据,并在提交单据申请时启动远程流程平台提供的流程启动服务。在这种场景下,第二步属于必须最终完成的操作,同时允许业务最终一致(不要因为流程平台本身的问题导致单据提交不成功,流程失败如何重试是系统内部的事情)。

对于这种情况,基于消息的最终一致性逻辑如下:

聊聊消息中间件的关键特性和问题总结

可以看出,账单的提交和流程的启动仍然需要在一个事务中进行控制,这本身就是一个分布式的事务控制场景。尤其是当消息中间件需要持久存储获取的消息时。

聊聊消息中间件的关键特性和问题总结

也就是说,从提交账单到向消息中间件发送消息,这两个活动需要在一个事务中进行控制。然而,消息中间件本身有两种方法。

一种是只要获得消息,只要还在内存中,就认为成功,返回给发送方,也就是异步刷机。还有一种是得到消息后,必须坚持写成功再返回,也就是同步刷。

所以要保证不丢失消息,必须是同步刷机模式,消息只有持久化成功才能返回。

坚持的作用是什么?

当从订阅方获取消息的进度较慢,或者订阅方长时间不取消息,那么消息就堆积在消息中间件中,消息中间件的内存容量优先,必须持久化更多的历史消息进行内存释放。否则,消息中间件本身就很难处理。

那么大量积压的新闻怎么办?常见的方式是设置消息的过期机制,比如设置为5天,那么超过5天没有被订阅者领走的消息会被自动丢弃。但是这种方法本身也会影响消息发送的完整性。

当然,挤压消息也可以手动清理。

比如目前已经产生了1亿条消息,分别由ERP分发到SRM和CRM系统,但是CRM系统对这些消息没有消费,处于积压状态。我们需要手动清理这部分CRM订阅消息。这时候可以看出,类似于基于数据库删除大表。

就是性能极慢。由于消息清理过程实际上是一个有条件的删除过程,而且数据也可能存在于多个磁盘文件中,所以清理后需要对磁盘文件进行重组。关于消息的持久化存储,前面提到过,将消息写入磁盘文件的性能极高,比数据库快很多。但是,当出现这种条件删除或消息清理场景时,性能会很差。

还是JMS AMQP?

JMS(Java Messaging Service)是Java平台上面向消息的中间件(MOM)的技术规范。它促进了消息系统中Java应用程序之间的消息交换,并通过提供生成、发送和接收消息的标准接口来简化企业应用程序的开发,并将其翻译为Java消息服务。

企业使用的传统消息集成中间件,如IBM MQ、Weblogic JMS、开源ActiveMQ等,基本都是基于JMS标准规范和协议。支持点对点队列模式,也支持消息发布订阅。

AMQP(Advanced Message Queuing Protocol,高级消息队列协议)是应用层标准的高级消息队列协议,提供统一的消息服务,是应用层协议的开放标准,是为面向消息的中间件设计的。基于该协议的客户端和消息中间件可以传递消息,不受客户端/中间件不同产品和开发语言的限制。

例如,RabbitMQ是通过AMQP协议实现的。

这里不能说基于AMQP的消息中间件的性能就一定比JMS好。在阿里基于JMS的RocketMQ上能查到的性能测试数据,其实比RabbitMQ要好。

具体测试数据请参考网上的对比图:

聊聊消息中间件的关键特性和问题总结

高可用性集群构建

集群可以分为两类,一类是应用中间件集群,另一类是持久中间件集群。

应用中间件集群

对于应用中间件集群,比如weblogic,tomcat应用中间件,Web container。这个类实现高可用性相对容易,因为不涉及数据持久存储的问题。

集群高可用,唯一的就是服务器节点之间会话状态信息的同步。目前有很多方案,比如会话同步复制,用数据库、Redis等共享库来保存会话信息。更简单的说,你可以访问上层的负载均衡设备,通过负载均衡设备配置会话保持来保持会话信息。在这种情况下,只需要容忍集群节点的故障,并且该节点上的当前会话不可用。

其次,集群节点的心跳检测。一种是最简单的方法是心跳ping。如果出现异常,则认为该节点出现故障。在这种情况下,无法判断集群节点是装死还是挂起。所以还有更进一步的做法,就是采用OpenRestry实现集群负载和动态心跳监控。

持久中间件集群

聊聊消息中间件的关键特性和问题总结

对于消息中间件,Redis缓存数据库等。,典型的特征就是数据持久化的问题。这些中间件本身的高可用集群思想基本一致。

集群配置问题

集群配置,可以看到有1主1从、多主、多(主+从)等多种模式实现集群扩展。应该注意,主从的目的是在主设备停机时从从设备获取消息,而不影响消息的实时性能。从节点实际上是实时复制主节点的数据,不提供性能共享。

但是多主的目的是真正的分散消息,发泄到集群的性能问题上。即使是最简单的点对点消息模型,Producer也可以将消息分发到两个主节点进行性能共享,从而减轻单个主节点下的性能压力。

所以如果只是高可靠的话,主+从基本可以满足。然而,为了满足高可靠性和高性能的要求,必须构建由多个主+和多个从组成的集群。

或者管理心跳监视节点。

管理节点的方式有很多种,比如RocketMQ自己实现的名称服务器集群,Redis集群实现的Sentinel Sentinel集群,或者通用Zookeeper集群实现分布式协调等。

但无论哪种方式,都可以看出管理节点通常是三服务器配置模式。

首先,Admin节点一定不能采用单点,即存在单点故障。

所以你需要配置至少两台服务器作为Admin管理节点,但是当你配置两台服务器的时候,你发现了一个新的问题,就是如果两台服务器检测到的节点状态不一致,到底听谁的?

正是因为这个原因引入了第三个服务器,即半数以上的投票机制可以实现文档的集群管理节点。可以看出,像Kurbernetes这样的集群也是需要三台服务器才能实现多主机的高可用配置。

持久存储

我们已经讨论过持久存储。在消息中间件的集群下,实际上每个集群节点都可能接收到大量的消息。消息是存储在本地磁盘还是共享文件中是一个需要考虑的问题。

如果是本地盘,一般需要考虑主从模式,实现消息的实时同步复制,保证主盘宕机时消息的实时获取不受影响。如果是共享存储模式,我们实际上可以看到,从节点是不必配置的,即某个主节点宕机后,另一个节点可以从共享存储重新加载消息。虽然有轻微的延迟,但基本不会影响消息的实时性。

类似于Weblogic JMS集群,基本采用这种方式,即共享文件进行持久化存储。当一个节点失效时,请求信息会漂移到其他非失效节点,完成高可用。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

作者:美站资讯,如若转载,请注明出处:https://www.meizw.com/n/160464.html

发表回复

登录后才能评论