消息服务传递模型

消息中间件(MOM)传递模型:

消息中间件Rabbitmq(02)_消息中间件

MOM:消息中间件,思想就是A和B两个应用程序不直接发送消息。之前A和B直接发送消息有很多效率问题,如A发送之后B没有及时接受,那么A就一直再在那里堵塞并发性不好,A必须等B接受完之后有返结果了A才可以结束。而MOM就是为了解决这样的问题,不让A与B之间交互,在A和B之间加一个消息中间件,A把消息放到消息中间上,就可以走了,去做别的事情,B什么时候来消息中间件取消息A不用知道也不用管。这样就提高了效率提供并发性,等B去走后可以通过状态,通知,回调等方式通知A就可以。市面上实现这种思想的技术有很多,IBM(MQSEVICES)、Microsoft(MSMQ)以及BEA的MessageMQ等。处于百家争鸣阶段都是各自实现各自的,没有统一实现标准。此时SUN为了实现统一标准就出现了JMS统一实现规范。JMS主要有2中消息模型,点到点和发布订阅两种。ActirveMQ是基于JMS技术实现规范实现的最终可以使用的成品,也就是最重的实现者,用户可以直接使用的。

点对点模型

定义:Point to Point 发送者和接收者中有一个消息队列(messages quene),发送者发送消息则把消息加入到队列中,接收者接收消息则把消息从队列中取出;如果接收者没有接收,则这条消息永远保存在队列中(除非已过期)。如下图:

消息中间件Rabbitmq(02)_消息队列_02

特点:


1.每条消息只能有一个接收者2.发送者和接收者之间可以异步(no timing dependencies)3.接收者成功接收答复机制

如果你希望发送的每个消息都应该被成功处理的话,那么你需要P2P模式。

发布订阅模型

定义:发送者把消息挂在一个主题下(类似电子公告板),接收者先订阅这个主题,当这个主题有新消息发布时,接收者就可以接收这个主题下的消息了,这个消息一直保持到所有订阅这个消息的人(在线的)都接收了才删除。如图:

消息中间件Rabbitmq(02)_应用程序_03

特点:


1.一条消息可以有多个接收者接收2.接收者和发送者之间必须同步。

为了弥补这种类型的时间依赖(timing dependencies)劣势,JMS API 提供了创建持久订阅的机制,这样不管接收者是否在线,发送者都可以发送,接收者也可以接收。

JMS是什么

JMS是一系列的接口及相关语义的集合,通过这些接口和和其中的方法,JMS客户端如何去访问消息系统,完成创建、发送、接收和读取企业消息系统中消息。


在JMS之前,每一家MOM厂商都用专有API为应用程序提供对其产品的访问,通常可用于许多种语言,其中包括Java语言。JMS通过MOM为Java程序提供了一个发送和接收消息的标准的、便利的方法。用JMS编写的程序可以在任何实现JMS标准的MOM上运行。


JMS可移植性的关键在于:JMS API是由Sun作为一组接口而提供的。提供了JMS功能的产品是通过提供一个实现这些接口的提供者来做到这一点的。开发人员可以通过定义一组消息和一组交换这些消息的应用程序,建立JMS应用程序,实现异步通讯。


JMS的目标

JMS从提出以来,致力于完成如下几个目标:

•定义一组消息公用概念和实用工具。所有Java应用程序都可以使用JMS中定义的API去完成消息的创建、接收与发送,任何实现了JMS标准的MOM都可以作为消息的中介,完成消息的存储转发。•最大化消息应用程序的可移植性。

MOM提供了有保证的消息发送,应用程序开发人员无需了解远程过程调用(PRC)和网络/通信协议的细节,提供了程序的可移植性。

•最大化降低应用程序与应用系统之间的耦合度。

由于MOM的存在,各个应用程序只关心和MOM之间如何进行消息的接收与发送,而无需关注MOM的另一边,其他程序是如何接收和发送的

各类消息队列

ActiveMQ是Apache出品的、采用Java语言编写的完全基于JMS1.1规范的面向消息的中间件,为应用程序提供高效的、可扩展的、稳定的和安全的企业级消息通信。不过由于历史原因包袱太重,目前市场份额没有后面三种消息中间件多,其最新架构被命名为Apollo,号称下一代ActiveMQ,有兴趣的同学可行了解。

RabbitMQ是采用Erlang语言实现的AMQP协议的消息中间件,最初起源于金融系统,用于在分布式系统中存储转发消息。RabbitMQ发展到今天,被越来越多的人认可,这和它在可靠性、可用性、扩展性、功能丰富等方面的卓越表现是分不开的。

Kafka起初是由LinkedIn公司采用Scala语言开发的一个分布式、多分区、多副本且基于zookeeper协调的分布式消息系统,现已捐献给Apache基金会。它是一种高吞吐量的分布式发布订阅消息系统,以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如Cloudera、Apache Storm、Spark、Flink等都支持与Kafka集成。

RocketMQ是阿里开源的消息中间件,目前已经捐献个Apache基金会,它是由Java语言开发的,具备高吞吐量、高可用性、适合大规模分布式系统应用等特点,经历过双11的洗礼,实力不容小觑。

ZeroMQ号称史上最快的消息队列,基于C语言开发。ZeroMQ是一个消息处理队列库,可在多线程、多内核和主机之间弹性伸缩,虽然大多数时候我们习惯将其归入消息队列家族之中,但是其和前面的几款有着本质的区别,ZeroMQ本身就不是一个消息队列服务器,更像是一组底层网络通讯库,对原有的Socket API上加上一层封装而已。

目前市面上的消息中间件还有很多,比如腾讯系的PhxQueue、CMQ、CKafka,又比如基于Go语言的NSQ,有时人们也把类似Redis的产品也看做消息中间件的一种,当然它们都很优秀,但是本文篇幅限制无法穷极所有,下面会针对性的挑选RabbitMQ和Kafka两款典型的消息中间件来做分析,力求站在一个公平公正的立场来阐述消息中间件选型中的各个要点。

JMS API编程介绍

类图:

消息中间件Rabbitmq(02)_消息中间件_04

API介绍:

ConnectionFactory

创建Connection对象的工厂,针对两种不同的jms消息模型,分别有QueueConnectionFactory和TopicConnectionFactory两种。可以通过JNDI来查找ConnectionFactory对象。

Destination

Destination的意思是消息生产者的消息发送目标或者说消息消费者的消息来源。对于消息生产者来说,它的Destination是某个队列(Queue)或某个主题(Topic);对于消息消费者来说,它的Destination也是某个队列或主题(即消息来源)。

所以,Destination实际上就是两种类型的对象:Queue、Topic可以通过JNDI来查找Destination。

Connection

Connection表示在客户端和JMS系统之间建立的链接(对TCP/IP socket的包装)。Connection可以产生一个或多个Session。跟ConnectionFactory一样,Connection也有两种类型:QueueConnection和TopicConnection。

Session

Session是我们操作消息的接口。可以通过session创建生产者、消费者、消息等。Session提供了事务的功能。当我们需要使用session发送/接收多个消息时,可以将这些发送/接收动作放到一个事务中。同样,也分QueueSession和TopicSession。

消息的生产者

消息生产者由Session创建,并用于将消息发送到Destination。同样,消息生产者分两种类型:QueueSender和TopicPublisher。可以调用消息生产者的方法(send或publish方法)发送消息。

消息消费者

消息消费者由Session创建,用于接收被发送到Destination的消息。两种类型:QueueReceiver和TopicSubscriber。可分别通过session的createReceiver(Queue)或createSubscriber(Topic)来创建。当然,也可以session的creatDurableSubscriber方法来创建持久化的订阅者。

MessageListener

消息监听器。如果注册了消息监听器,一旦消息到达,将自动调用监听器的onMessage方法。EJB中的MDB(Message-Driven Bean)就是一种MessageListener。

JMS可以解决那些问题

1.同步通信:客户发出调用后,必须等待服务对象完成处理并返回结果后才能继续执行;2.客户和服务对象的生命周期紧密耦合:客户进程和服务对象进程都必须正常运行;如果由于服务对象崩溃或者网络故障导致客户的请求不可达,客户会接收到异常;3.点对点通信:客户的一次调用只发送给某个单独的目标对象。

消息中间件Rabbitmq(01)


关注公众号 soft张三丰 

消息中间件Rabbitmq(02)_应用程序_05