当前位置: 首页 > 后端技术 > Java

你了解消息队列MQ-JMS-Kafka吗?

时间:2023-04-01 22:06:24 Java

平时是不是听到了一堆消息队列,JMS,MQ,kafka,等等等等,但是听不懂?关系混乱?今天就让我们一起来看看他们是怎样的吧。消息队列介绍首先我们举个快递的栗子。传统收快递的方式是快递小哥把我们的快递发给我们。他需要什么?快递小哥有时间送,我们有时间来取。快递小哥和我们约定了时间地点。但是,呃。快递小哥有那么多快递要送,可能我送快递的时候我不在家,可能我在家的时候快递小哥在外地送快递。所以嗯,这个时候要么我坐在家里等快递,要么只能从新预约的时间开始发货。那么如何避免这种情况呢?于是快递柜出现了。我在家的时候快递小哥不用管,因为快递小哥有空就把快递放在快递柜里,我有空就去快递柜取我的快递。那么快递柜的功能就是我们今天要接收的消息队列。我们可以把消息队列比作一个存放快件的快递柜。当我们需要取快递时,可以从快递柜取快递。什么是消息队列?我们可以将消息队列比作存储消息的容器。当我们需要使用消息的时候,我们可以把消息取出来自己使用。我们看一下维基百科上的描述:在计算机科学中,消息队列(Messagequeue)是进程之间或同一进程的不同线程之间的一种通信方式。软件的存储栏用于处理一系列输入,通常来自用户。是不是很难理解,换个方式理解,我们可以把消息队列比作一个容器,用来存放消息,当我们需要使用消息的时候,可以把消息取出来自己使用。消息队列有什么用?消息队列是分布式系统中的重要组成部分。使用消息队列的主要目的是提高系统性能,调峰,通过异步处理降低系统耦合度。常用消息中间件17个维度全方位对比通过异步处理(调峰、减少响应时间)提升系统性能。例如:当我们在某网站注册账号时,需要做以下四件事:填写我们的注册信息;提交我们的注册信息;通过我们的电子邮件接收注册信息;通过短信接收注册信息。如果使用同步串行,所需时间为:a+b+c+d如果使用同步并行,所需时间为:a+b+max(c,d)如果使用消息队列,则所需时间为:a+b+消息队列降低系统耦合比如A公司搭建了某个系统,B公司认为A公司的某个功能很好,于是将B公司和A公司的系统集成在一起。这时C公司也觉得A公司的这个功能很好,所以C公司也集成了A公司的系统。以后会有D公司……由于这种情况,A公司的系统与其他公司的耦合度很高。每次整合公司的系统,A公司都需要修改自己的系统。如果使用了消息队列,就变成了这样:不管以后有多少公司的应用要用A公司的程序,都不需要和A公司集成,谁需要这个功能就去消息队列为拿到它,为实现它。消息队列的两种模式点对点模式的应用程序由:消息队列、发送者和接收者组成。每条消息被发送到一个特定的队列,接收者从队列中获取消息。队列保存消息,直到它们被消耗或超时。发布-订阅模型应用程序由:角色主题(Topic)、发布者(Publisher)、订阅者(Subscriber)组成。发布者发布一条消息,该消息通过主题传递给所有客户端。在这种模式下,发布者和订阅者都是匿名的,即发布者和订阅者都不知道对方是谁。并且可以动态发布和订阅Topic。Topic主要用于消息的保存和传递,会一直保存消息,直到消息传递到客户端。介绍完消息队列我们再介绍JMSJMS来介绍JMS,即Java消息服务(JavaMessageService)应用程序编程接口,它是Java平台中面向消息中间件(MOM)的一个API,类似于JDBC。用于在两个应用程序之间或在分布式系统中发送消息以进行异步通信。它提供创建、发送、接收和阅读消息的服务。Sun及其合作伙伴设计的应用程序编程接口和相应的语法使Java程序能够与其他消息传递组件进行通信。JMS是一种消息服务标准或规范,允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信的耦合度降低,消息服务更加可靠和异步。介绍到这里,你应该明白消息队列和JMS的区别了吧?消息队列:在计算机科学中,A和B进行通信的一种方式。JMS:Java平台间分布式通信的标准或规范。也就是说,JMS就是java对消息队列的实现。JSM的消息模型是点对点的,发布订阅,在消息队列中已经说的很清楚了,这里不再赘述。JMS消费者同步(Synchronous)订阅者/接收者通过调用receive()来接收消息。在receive()方法中,线程会阻塞,直到消息到达或者消息在指定时间后还没有到达。异步(Asynchronous)消息订阅者需要注册一个消息监听器,类似于事件监听器,只要消息到达,JMS服务提供者就会通过调用监听器的onMessage()来传递消息。JMS编程模型JMS编程模型与JDBC非常相似。回想一下我们之前讲过的MyBatis。SqlSessionFactoryBuilder构造SqlSessionFactory会话工厂;SqlSessionFactory会话工厂为我们打开SqlSession会话;SqlSession帮我们连接到数据库,然后我们就可以进行增删改查了。sqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream);SqlSessionopenSession=sqlSessionFactory.openSession(true);ProjectMappermapper=openSession.getMapper(ProjectMapper.class);mapper.queryAllTask??ByInit("init");JMS模型如下连接工厂给我创建一个连接连接;Connection连接为我们创建了一个Session会话;Session会话为我们创建了一个消费者和一个生产者;生产者生成消息;消费者消费消息;MQ介绍上文我们提到,JMS并不是一个真正有意义的技术,而是一种接口,一种规范。就像JDBC一样,不管是mybatis,hibernate,还是springJPA,不管你实现什么样的技术,无论如何都要遵守JDBC规范。在Java中,目前常见的基于JMS的消息队列技术有ActiveMQ、RabbitMQ、RocketMQ等。值得注意的是,RocketMQ并不完全遵守JMS规范,Kafka也不是JMS的实现。AMQP协议这里我们以RabbitMQ为例介绍MQ。首先介绍一下AMQPAMQP协议(AdvancedMessageQueuingProtocol,高级消息队列协议),它是一种在进程间传输异步消息的网络协议。AMQP模型AMQP工作流程发布者(Publisher)发布消息(Message),通过交换器(Exchange)。交换机根据路由规则将接收到的消息分发到与交换机绑定的队列(Queue)中。最后由AMQP代理将消息投递给订阅了这个队列的消费者,也可以消费者根据需求自行获取。RabbitMQ是MQ产品的典型代表,是一个基于AMQP协议的可复用的企业消息系统。RabbitMQ模型RabbitMQ由两部分组成,即服务器和应用程序;服务器包括:队列和交换机。客户包括:生产者和消费者。可以在rabbitmq服务器上创建多个虚拟消息代理。每个broker本质上都是一个mini-rabbitmq服务器,分别管理自己的exchange和bindings。Broker相当于一台物理服务器,可以为不同的应用提供边界隔离,让应用可以安全地运行在不同的Broker实例上,互不干扰。生产者和消费者需要指定一个broker来连接rabbitserver。消息队列探索-RabbitMQ消息队列简介Exchange有4种类型:direct(默认)、fanout、topic、headersDirect:直接exchange,工作方式类似于unicast,Exchange会将消息发送到与ROUTING_KEY完全匹配的Queue。扇出:广播是一种开关。无论消息的ROUTING_KEY设置如何,Exchange都会将消息转发给所有绑定的Queue(所谓绑定就是绑定特定的Exchange和特定的Queue。Exchange和Queue的绑定可以是多对多的关系).Topic:主题交换,工作方式类似于组播。Exchange会将消息转发给所有匹配方式与ROUTING_KEY相同的队列。例如ROUTING_KEY为user.stock的Message会被转发到.stock,user.stock,.的绑定匹配模式。和#.user.stock.#队列。(表格是匹配任意一个词组,#表示匹配0个或多个词组)。至于在代码中如何使用RabbitMQ,这里就不碰代码了。本文仅介绍理论知识点。我们在上一章的Kafka中有提到,kafka并不是JMS的实现,所以在MQ一章中并没有提到。现在让我们开始学习kafka。大白话带你认识卡夫卡。先给大家看一下Kafka的示意图。相信当你看到这张图的时候,你的心都会崩溃。我傻了,怎么办。接下来,我们就一点点消化吧。kafka示意图首先介绍上图中的术语。Producer:消息生产者是向kafkabroker发送消息的客户端。Consumer:消息消费者,从kafkabroker中获取消息的客户端。Topic:kafka为消息提供的分类方法。Broker用于存储不同主题的消息数据。一个topic可以认为是一种消息,每个topic会被划分为多个partition(区域),每个partition在存储层面都是一个appendlogfile。发布到该分区的任何消息都将直接附加到日志文件的末尾。每条消息在文件中的位置称为偏移量(offset),offset是一个长数字,它唯一地标记一条消息。它唯一地标记一条消息。Kafka没有提供其他额外的索引机制来存储偏移量,因为在Kafka中几乎不允许消息的“随机读写”。broker:中间件的kafka集群,存储消息,是由多个服务器组成的集群。Partition:为了实现可扩展性,可以将一个非常大的topic分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序队列。分区中的每条消息都将分配一个有序的id(偏移量)。Kafka只保证消息按partition的顺序发送给消费者,不保证topic整体(多个partition之间)的顺序。Offset:kafka的存储文件按照offset.kafka命名。比如要查找2049的位置,只需要找到2048.kafka这个文件即可。当然第一个offset是00000000000.kafka。功能类似于JMS,但不是JMS规范的实现。Kafka在保存消息时,会根据Topic对消息进行分类。消息发送者成为Producer,消息接收者成为Consumer。另外,Kafka集群由多个Kafka实例组成,每个实例(服务器)都成为一个broker。无论是kafka集群,还是生产者和消费者,都依赖zookeeper来保证系统可用性和集群存储信息。Kafka基于文件存储。通过分区,可以将日志内容分布到多台服务器上,避免文件大小达到单机磁盘的上限。每个partiton都会被当前服务器(kafka实例)保存;一个主题可以分成任意数量的分区,以提高消息存储/消费的效率。另外,更多的分区意味着可以容纳更多的消费者,有效提升并发消费的能力。kafka和JMS的区别在于即使消息被消费了,也不会立即删除消息。根据broker中的配置要求,日志文件会在一定时间后被删除。Kafka高可用机制由多个broker组成,每个broker为一个节点;你创建一个topic,它可以分为多个partition,每个partition可以存在于不同的broker上,每个partition存储一部分数据。使用副本副本机制,每个分区的数据都会同步到其他机器上,形成多个副本副本。所有的replica都会选出一个leader,然后生产和消费都会跟这个leader打交道,然后其他的replica都是follower。读数据时从leader读取,写数据时leader将数据同步给所有follower。如果某个broker宕机了,这个broker还在其他broker中保留一份。假设这个broker上有一个leader,那么重新选举一个leader。内容很多,需要结合图片一点一点消化。什么是Kafka,主要应用于哪些场景?至此producer结构图看不清楚,不过相信你还是能分辨出来的吧?整理消息队列:是指计算机领域中A和B之间的一种通信方式;JMS:Java中消息队列的接口规范;ActiveMQ/RabbitMQ:一种实现JMS接口规范的技术;RocketMQ:不完全是JMS接口规范专门实现的一种技术;Kafka:非JMS接口规范专门实现的一种技术;来源:blog.csdn.net/m0_37892044/article/details/106603925