是不是平常听到说消息队列啊,JMS啊,MQ啊 、kafka等一堆术语,听不懂?关系混乱?今天就让我们来一起来看看他们都是什么吧。
- 消息队列介绍 -
首先举个收快递的栗子,传统的收快递,快递小哥把我们的快递送到我们的手里。他需要什么条件嗯?
但是嗯。快递小哥有那么多的快递需要送,可能送我快递的时候,我不在家,可能我在家的时候,快递小哥送其他的地方的快递。所以嗯,这个时候,要么就是坐在家里等快递,要么就只能从新约个时间点在送。那怎么办去避免这个情况?
于是嗯快递柜出现了。快递小哥不用关心我什么时候在家,因为快递小哥有时间了,就把快递放快递柜,而我有时间了,我就去快递柜取我的快递。
那么快递柜所起到的作用就是我们今天要收的消息队列。我们可以把消息队列比作是一个存放快递的的快递柜,当我们需要获取我们快递的时候就可以从快递柜里面拿到属于我们的快递。
我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用。我们看看维基百科上的描述:在计算机科学中,消息队列(Message queue)是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。
是不是很难理解,我们换个说法来理解
我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用。
消息队列是分布式系统中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。
通过异步处理提高系统性能(削峰、减少响应所需时间)。
举个例子:我们在某个网站进行注册账号,我们需要做如下四件事:
如果采用同步串行,所需要的时间是: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。Topic主要用于保存和传递消息,且会一直保存消息直到消息被传递给客户端。
介绍完了消息队列,接着我们介绍JMS。
- JMS 介绍 -
JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,类似于JDBC。用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
它提供创建、发送、接收、读取消息的服务。由Sun公司和它的合作伙伴设计的应用程序接口和相应语法,使得Java程序能够和其他消息组件进行通信。
JMS是一个消息服务的标准或者说是规范,允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。
介绍到这里,应该明白了消息队列和JMS的区别了吧?
换句话说,JMS就是java对于消息队列的一种实现方式。
点对点,发布订阅,消息队列中已经说的很清楚了,这里就不重复说了。
订阅者/接收方通过调用 receive()来接收消息。在receive()方法中,线程会阻塞直到消息到达或者到指定时间后消息仍未到达。
消息订阅者需注册一个消息监听者,类似于事件监听器,只要消息到达,JMS服务提供者会通过调用监听器的onMessage()递送消息。
JMS编程模型非常类似于JDBC。回忆一下,我们之前讲到的MyBatis。
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession openSession = sqlSessionFactory.openSession(true);
ProjectMapper mapper = openSession.getMapper(ProjectMapper.class);
mapper.queryAllTaskByInit("init");
JMS模型如下
- 3MQ 介绍 -
上文中,我们说到了,JMS他并不是一种真正意义的技术,而是一种接口,一种规范。就想JDBC一样,无论是mybatis、hibernate,还是springJPA,不管你是那种技术实现,反正你得遵守JDBC的规范。
在Java中,目前基于JMS实现的消息队列常见技术有ActiveMQ、RabbitMQ、RocketMQ。值得注意的是,RocketMQ并没有完全遵守JMS规范,并且Kafka不是JMS的实现。
这里我们以RabbitMQ为例介绍MQ,首先介绍下AMQP。
AMQP协议(Advanced Message Queuing Protocol,高级消息队列协议)是一个进程间传递异步消息的网络协议。
- AMQP 模型 -
发布者(Publisher)发布消息(Message),经由交换机(Exchange)。
交换机根据路由规则将收到的消息分发给与该交换机绑定的队列、(Queue)。
最后 AMQP 代理会将消息投递给订阅了此队列的消费者,或者消费者按照需求自行获取。
RabbitMQ是MQ产品的典型代表,是一款基于AMQP协议可复用的企业消息系统。
RabbitMQ由两部分组成,分别是服务端和应用端;
在rabbitmq server上可以创建多个虚拟的message broker。每一个broker本质上是一个mini-rabbitmq server,分别管理各自的exchange,和bindings。
broker相当于物理的server,可以为不同app提供边界隔离,使得应用安全的运行在不同的broker实例上,相互之间不会干扰。producer和consumer连接rabbit server需要指定一个broker。
Exchange有4种类型:direct(默认),fanout, topic, 和headers
至于如何在代码中使用RabbitMQ,这里我们先不撸代码,本文目前只介绍理论梳理知识点。
- Kafka -
上完中我们提到过,kafka不是JMS的实现,因此在MQ章节中,我们没有提及到它。现在我们开始学习kafka吧。
先来放张kafka的原理图,相信你看到这个图片时,内心是奔溃的。我草,啥玩意。接下来我们就一点一点的消化吧。
先介绍上图中的术语。
类似于JMS的特性,但不是JMS规范的实现。kafka对消息保存时根据Topic进行归类,发送消息者成为Producer,消息接受者成为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)成为broker。无论是kafka集群,还是producer和consumer都依赖于zookeeper来保证系统可用性集群保存信息。
kafka基于文件存储。通过分区,可以将日志内容分散到多个server上,来避免文件尺寸达到单机磁盘的上限,每个partiton都会被当前server(kafka实例)保存;可以将一个topic切分多任意多个partitions,来消息保存/消费的效率.此外越多的partitions意味着可以容纳更多的consumer,有效提升并发消费的能力。
kafka和JMS不同的是:即使消息被消费,消息仍然不会被立即删除。日志文件将会根据broker中的配置要求,保留一定的时间之后删除。
- Kafka 高可用机制 -
内容有点多,需要结合图片一点一点消化。
至此,虽然看的云里雾里,不过相信你们还是能区分了吧?
整理一下:
作者:歪桃 来源: blog.csdn.net/m0_37892044/article/details/106603925