ActiveMQ简介

2019-03-18 21:46|来源: 网路

什么是消息

Message,即消息。人与人之间通过消息传递信息。言语、眼神、肢体动作都可被视为消息体。当然还有我们经常用到的邮件、短信。计算机系统也由消息来主导运行。每一条指令的执行,每一个数据包的传递。软件系统间的合作也不例外,消息告诉各个系统应该怎样协作。事件处理机制,也是消息传送的过程。消息无处不在。

 消息分为同步消息和异步消息。同步消息在接收到对方的返回前,需要挂起,直到返回或超时。异步消息只需要发送消息,不需要对方系统的立即反馈。

 同步消息如java RPC调用,同步调用依赖于被调用方,如果被调用方失败或网络错误,那么程序就没办法继续执行下去,造成一个系统最薄弱的环节依赖于对方系统。而多个系统通过同步调用方式耦合在一起的时候,那么可靠性取决于最薄弱的一方系统。而异步调用能增强一个系统的健壮性。当然,不是任何情况都适合异步调用,还是那句话,能异步的地方,尽量异步。

 异步消息,如同一个邮箱系统,我们把信件丢入邮桶,邮递员会更具上面的地址,送达到这封信要去的地方。邮箱和信件格式由邮局提供定义,比如邮箱需要有一个口子投递邮件,邮件需要有地址,邮政编码等等。而这些邮箱具体的加工和制作均交由各自的厂商来完成。
在java消息领域,我们也有一个称为消息中间件的东西,来提供这样一个服务。消息的发送、消费接口、消息体的格式等都由JMS来定义,而具体的实现由各个消息中间件厂商来实现。JMS是sun公司对于消息中间件的一个规范。对java领域里的消息起到举足轻重的作用。以前的消息交互,均各自实现一套格式,如同一个国家的人都用不同的方言跟另外来自不同省份的人交流一样。自从规范了普通话,我们的交流成本降低了。这也正如JMS规范在整个java消息领域的作用。


1. JMS简介
 JMS即Java消息服务(Java Message Service),是一个是Java平台上有关面向消息中间件(MOM)的技术规范,它便于消息系统中的Java应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接口简化企业应用的开发,用于在两个应用程序之间或分布式系统中发送消息,进行异步通信。

2. JMS对象模型要素:
 1)连接工厂:连接工厂(ConnectionFactory)是由管理员创建,并绑定到JNDI树中。客户端使用JNDI查找连接工厂,然后利用连接工厂创建一个JMS连接。例如ActiveMQ提供的
ActiveMQConnectionFactory。
 2)JMS连接:JMS连接(Connection)表示JMS客户端和服务器端之间的一个活动的连接,是由客户端通过调用连接工厂的方法建立的。
 3)JMS会话:JMS Session是生产和消费消息的一个单线程上下文。会话用于创建消息生产者(producer)、消息消费者(consumer)和消息(message)等。会话提供了一个事务性的上下文,在这个上下文中,一组发送和接收被组合到了一个原子操作中。
 4)JMS目的地:JMS目的地(Destination),又称为消息队列,是实际的消息源。
 5)JMS生产者和消费者:生产者(Message Producer)和消费者(Message Consumer)对象由Session对象创建,用于发送和接收消息。
 6)JMS消息:JMS消息由以下三部分组成:
     • 消息头:每个消息头字段都有相应的getter和setter方法。
     • 消息属性:如果需要除消息头字段以外的值,那么可以使用消息属性。
     • 消息体:JMS定义的消息类型有TextMessage、MapMessage、BytesMessage、StreamMessage和ObjectMessage。
 7)JMS消息类型:
     点对点(Point-to-Point):在点对点的消息系统中,消息分发给一个单独的使用者。点对点消息往往与队列(javax.jms.Queue)相关联。
     发布/订阅(Publish/Subscribe):发布/订阅消息系统支持一个事件驱动模型,消息生产者和消费者都参与消息的传递。生产者发布事件,而使用者订阅感兴趣的事件,并使用事件。该类型消息一般与特定的主题(javax.jms.Topic)关联。

3. JMS的可靠性机制
 1)确认
   JMS消息只有在被确认之后,才认为已经被成功地消费了。消息的成功消费通常包含三个阶段:客户接收消息、客户处理消息和消息被确认。 在事务性会话中,当一个事务被提交的时候,确认自动发生。在非事务性会话中,消息何时被确认取决于创建会话时的应答模式(acknowledgement mode)。该参数有以下三个可选值:
     Session.AUTO_ACKNOWLEDGE:当客户成功的从receive方法返回的时候,或者从MessageListener.onMessage方法成功返回的时候,会话自动确认客户收到的消息。
     Session.CLIENT_ACKNOWLEDGE: 客户通过消息的acknowledge方法确认消息。需要注意的是,在这种模式中,确认是在会话层上进行:确认一个被消费的消息将自动确认所有已被会话消 费的消息。例如,如果一个消息消费者消费了10个消息,然后确认第5个消息,那么所有10个消息都被确认。
     Session.DUPS_ACKNOWLEDGE: 该选择只是会话迟钝第确认消息的提交。如果JMS provider失败,那么可能会导致一些重复的消息。如果是重复的消息,那么JMS provider必须把消息头的JMSRedelivered字段设置为true。
 2)持久性
   JMS 支持以下两种消息提交模式:
     PERSISTENT:指示JMS provider持久保存消息,以保证消息不会因为JMS provider的失败而丢失。
     NON_PERSISTENT:不要求JMS provider持久保存消息。
 3)优先级
   可以使用消息优先级来指示JMS provider首先提交紧急的消息。优先级分10个级别,从0(最低)到9(最高)。如果不指定优先级,默认级别是4。需要注意的是,JMS provider并不一定保证按照优先级的顺序提交消息。
 4)消息过期
   可以设置消息在一定时间后过期,默认是永不过期。
 5)临时目的地
   可以通过会话上的createTemporaryQueue方法和createTemporaryTopic方法来创建临时目的地。它们的存在时间只限于创建它们的连接所保持的时间。只有创建该临时目的地的连接上的消息消费者才能够从临时目的地中提取消息。
 6)持久订阅
   首先消息生产者必须使用PERSISTENT提交消息。客户可以通过会话上的createDurableSubscriber方法来创建一个持久订阅,该方法的第一个参数必须是一个topic,第二个参数是订阅的名称。 JMS provider会存储发布到持久订阅对应的topic上的消息。如果最初创建持久订阅的客户或者任何其它客户使用相同的连接工厂和连接的客户ID、相同的主题和相同的订阅名再次调用会话上的createDurableSubscriber方法,那么该持久订阅就会被激活。JMS provider会象客户发送客户处于非激活状态时所发布的消息。 持久订阅在某个时刻只能有一个激活的订阅者。持久订阅在创建之后会一直保留,直到应用程序调用会话上的unsubscribe方法。
 7)本地事务
   在一个JMS客户端,可以使用本地事务来组合消息的发送和接收。JMS Session接口提供了commit和rollback方法。事务提交意味着生产的所有消息被发送,消费的所有消息被确认;事务回滚意味着生产的所有消息被销毁,消费的所有消息被恢复并重新提交,除非它们已经过期。 事务性的会话总是牵涉到事务处理中,commit或rollback方法一旦被调用,一个事务就结束了,而另一个事务被开始。关闭事务性会话将回滚其中的事务。 需要注意的是,如果使用请求/回复机制,即发送一个消息,同时希望在同一个事务中等待接收该消息的回复,那么程序将被挂起,因为知道事务提交,发送操作才会真正执行。 需要注意的还有一个,消息的生产和消费不能包含在同一个事务中



1.1   什么是ActiveMQ
  ActiveMQ是一种开源的,实现了JMS1.1规范的,面向消息(MOM)的中间件,为应用程序提供高效的、可扩展的、稳定的和安全的企业级消息通信。ActiveMQ使用Apache提供的授权,任何人都可以对其实现代码进行修改。

  ActiveMQ的设计目标是提供标准的,面向消息的,能够跨越多语言和多系统的应用集成消息通信中间件。ActiveMQ实现了JMS标准并提供了很多附加的特性。这些附加的特性包括,JMX(java Management Extensions,即java管理扩展)管理,主从(master/salve,这是集群模式的一种,主要体现在可靠性方面,当主中介(代理)出现故障,那么从代理会替代主代理的位置,不至于使消息系统瘫痪)管理、消息组通信(同一组的消息,仅会提交给一个客户进行处理)、有序消息管理(确保消息能够按照发送的次序被接受者接收)。消息优先级(优先级高的消息先被投递和处理)、订阅消息的延迟接收(订阅消息在发布时,如果订阅者没有开启连接,那么当订阅者开启连接时,消息中介将会向其提交之前的,其未处理的消息)、接收者处理过慢(可以使用动态负载平衡,将多数消息提交到处理快的接收者,这主要是对PTP(point to point,即点对点消息)消息所说、虚拟接收者(降低与中介的连接数目)、成熟的消息持久化技术(部分消息需要持久化到数据库或文件系统中,当中介崩溃时,信息不会丢失)、支持游标操作(可以处理大消息)、支持消息的转换、通过使用Apache的Camel可以支持EIP、使用镜像队列的形式轻松的对消息队列进行监控等

1.1.1 ActiveMQ 特性

  支持JMS规范:ActiveMQ完全实现了JMS1.1规范。JMS规范提供了同步消息和异步消息投递方式、有且仅有一次投递语义(指消息的接收者对一条消息必须接收到一次,并且仅有一次)、订阅消息持久接收等。如果仅使用JMS规范,表明无论您使用的是哪家厂商的消息代理,都不会影响到您的程序。

  连接方式的多样化:ActiveMQ提供了广泛的连接模式,包括HTTP/S、JGroups、JXTA、muticast、SSL、TCP、UDP、XMPP等。提供了如此多的连接模式表明了ActiveMQ具有较高的灵活性。

   可插入式的持久化和安全:ActiveMQ提供了多种持久化方案,您可以根据实际需要进行选择。同时,也提供了完整的客户授权模式。

  使用Java创建消息应用程序:最常见的使用ActiveMQ的方式就是使用Java程序来发送和接收消息。

   与其他的Java容器紧密集成:ActiveMQ提供了和其它流行的Java容器的结合,包括Apache Geronimo、Apache Tomcat、JBoss、Jetty等。
 
   客户端API:ActiveMQ提供了多种客户端可访问的API,包括Java、C/C++,.NET,Perl、PHP、Python、Ruby等。当然,ActiveMQ中介必须运行在Java虚拟机中,但是使用它的客户端可以使用其他的语言来实现。

支持跨平台跨语言等特点,由于它是用JAVA实现的一套中间件,跨平台不用说。
对于客户端方面,他实现了java,C/C++, .NET, Perl, PHP, Python, Ruby,其他等等语言的客户端API调用。

事件驱动,异步特点,比传统的RPC更具有松耦合特点。

中介集群:多个ActiveMQ中介可以一起协同工作,来完成某项复杂的工作,这被称为网络型中介(network of brokers),这种类型的中介将会支持多种拓扑类型。

1.1.2  为什么使用ActiveMQ
  在设计分布式应用程序时,应用程序间的耦合(或称集成)方式很重要。耦合意味着两个或者多个应用程序或系统的相互依赖关系。一种简单的方式是在所有的应用程序中从架构上设计他们与其他应用程序间的交叉实现。这样必然导致,一个应用程序的改变,直接导致另一个应用程序的改变。按照这种方式集成的应用是一种紧耦合的应用。一个应用的改变不会影响到其他应用的集成方式被称为是松耦合的集成方式。简单的说,松耦合应用程序集成能够更容易的处理不可预见的应用变化。

   像COM、CORBA、DCE和EJB等应用技术使用RPC(Remote Procedural Calls,即远程过程调用)属于紧耦合技术。使用RPC,一个应用程序调用另一个应用程序,调用者必须阻塞,直到被调用者执行结束返回结果信息为止。下图给出了这种紧耦合技术的描述:


  许多系统架构使用RPC,并且获得了巨大的成功,但是,紧耦合的架构有着天生的缺陷。首先,这种架构将会造成系统维护管理上的巨大消费,因为,即使是很小的改动,很可能会波及到整个系统。其次,由于调用者必须阻塞式的等待被调用者返回,如果被调用者处理过程复杂,将会严重影响调用者的执行效率和资源使用率。此外,如果调用失败,整个架构即失败。

下图给出一种松耦合的方式,进行架构设计:

  应用程序1向消息中介(MOM)发送一条消息,很可能一段时间之后,应用程序2调用MOM来收取消息。任何一个应用程序都不知道对方是否存在也不需要阻塞等待。这种通信方式大大缩减了维护开销,因为对于一个应用程序的修改,会对其他应用程序影响极小。

  ActiveMQ就是采用了上面提到的松耦合方式,因此,我们经常说应用程序发送消息仅仅是触发后忘却。应用程序将消息发送给ActiveMQ而并不关心什么时间以何种方式消息投递给接收者。同样的,消息接收者也不会关心消息来源于哪里和消息是怎样投递给ActiveMQ的。对于多语言编写的复杂应用环境中,允许客户端使用不同的编程语言甚至不同的消息包装协议。ActiveMQ作为消息的中间件,允许复杂的多语言应用程序以一种一步的方式集成和交互。

所有说,ActiveMQ是一种好的,提供松散耦合的,能够为多语言交叉应用提供集成的中间件。

1.1.3  什么情况下使用ActiveMQ
  正如前面提到的,紧耦合应用系统存在许多问题,但是,要将紧耦合系统重构成松耦合系统是一件值得但比较繁琐的事情。使用松耦合的主要优势体现在将同步改为异步。使用异步通信,应用程序将从接收者反馈的等待中解放出来,其他的任务可以得到执行,这样提高了应用程序的效率。

  只要是两个应用程序间需要通信的情况,都可以考虑使用JMS,不论这种通信是在本地的(就是通信的两个应用程序在同一台主机上),还是分布在不同机器上。尽管是在同一个主机上的两个应用程序需要通信也可以使用ActiveMQ。ActiveMQ可以确保消息投递成功并采用异步方式通信。

   多个需要通信的应用程序在同一个机器上的情况下,您可以考虑在执行机上独立运行ActiveMQ或者将ActiveMQ嵌入到Java应用服务中。无论采用哪种方式,都可以确保应用程序能够发送和接收消息。您可以选择订阅模式(pub/sub)或者采用PTP(point to point)模式,这两种模式都无需等待执行反馈信息。每一个应用程序都可以简单的将消息发送给ActiveMQ,然后继续做其他的工作;应用程序无需阻塞式等待消息的返回。

  对于分布在多台主机上的应用程序来说,可以使用多种布置策略。主要包括单一ActiveMQ实例和多ActiveMQ实例。单一ActiveMQ实例是一个简单解决方案。所有的应用程序都向同一个ActiveMQ中介发送和接收消息,这与上面提到的单机多服务雷同。单一的ActiveMQ可以布置到一台单独的主机上,也可以和其中的一些服务布置在一起。重要的是,所有的应用必须能够直接与ActiveMQ中介进行交互,所以,你必须考虑到你的网络设计。

  第二种情况比较复杂,但是有ActiveMQ来负责远程通信,而不是应用程序自身。在这种场景下,每一个应用程序都会实例化一个ActiveMQ(无论是嵌入式的还是独立式的),应用程序从其本地的ActiveMQ发送和接收消息。之后这些ActiveMQ实例将会以一种联合的方式协同工作。消息将会基于每一个应用的要求在多个ActiveMQ中介间传递到远程的处理者。在ActiveMQ中,这种模式被称为netWork of brokers。采用这种模式对于处理大量的ActiveMQ消息是可行的,但是,我们往往需要减轻网络拓扑的复杂性,这样直接将消息投递到远程接收者的ActiveMQ是不可行的。在后一种情况下,不同的协议使用可以使ActiveMQ更轻松的传递消息。

整理于网络

相关问答

更多

ActiveMQ 5.2随Linux系统自动启动

终于搞定了activemq的自动启动,主要还是参考了题主的思路。 cp 到/etc/init.d目录下的时候,启动会提示找不到路径等等问题,但是在安装目录启动就可以,所以可以通过软连接来实现启动脚本: ln -s /usr/local/activemq/bin/activemq /etc/init.d/ vi /etc/init.d/activemq --------------------------------------------- # 第二行插入 # chkconfig: 345 63 ...

activemq 怎么实现负载均衡

一、架构和技术介绍 1、简介 ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现 2、activemq的特性 1. 多种语言和协议编写客户端。语言: Java, C, C++, C#, Ruby, Perl, Python, PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP 2. 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息 ...

ActiveMQ和Spring整合的问题

ActiveMQ的服务是随机器启动的(当你安装了他的服务之后,默认是不安装的,不过有时候会不经意安装),这时候你再用 Spring启动ActiveMQ就会报如上的错误。 你可以在运行里输入net stop activemq停止之后再用Spring启动一下看看。

ActiveMQ和Spring整合的问题

ActiveMQ的服务是随机器启动的(当你安装了他的服务之后,默认是不安装的,不过有时候会不经意安装),这时候你再用Spring启动ActiveMQ就会报如上的错误。 你可以在运行里输入net stop activemq停止之后再用Spring启动一下看看。

linux 里面将activemq设置为开机自启动怎么弄,网上找了好多都不行。 带命令啊

vim 你的开机启动文件。将activemq添加上就行了。 vim /etc/fstab(这用Tab补全吧。具体哪个文件名记不太清了)。然后你就按照上面的格式进行挂载就行了。