JMS简介与ActiveMQ实战-程序员宅基地

技术标签: java  网络  数据库  

1. JMS架构

 

Java 消息服务(Java Message Service,简称JMS)是用于访问企业消息系统的开发商中立的API。企业消息系统可以协助应用软件通过网络进行消息交互。JMS 在其中扮演的角色与JDBC 很相似,正如JDBC 提供了一套用于访问各种不同关系数据库的公共API,JMS 也提供了独立于特定厂商的企业消息系统访问方式。

使用JMS 的应用程序被称为JMS 客户端,处理消息路由与传递的消息系统被称为JMS Provider,而JMS 应用则是由多个JMS 客户端和一个JMS Provider 构成的业务系统。发送消息的JMS 客户端被称为生产者(producer),而接收消息的JMS 客户端则被称为消费者(consumer)。同一JMS 客户端既可以是生产者也可以是消费者。

JMS 的编程过程很简单,概括为:应用程序A 发送一条消息到消息服务器(也就是JMS Provider)的某个目得地(Destination),然后消息服务器把消息转发给应用程序B。因为应用程序A 和应用程序B 没有直接的代码关连,所以两者实现了解偶。如下图:


 

消息传递系统的中心就是消息。一条Message 由三个部分组成:

 

消息的组成

 

1. (head)

每条JMS 消息都必须具有消息头。头字段包含用于路由和识别消息的值。可以通过多种方式来设置消息头的值:

a. 由JMS 提供者在生成或传送消息的过程中自动设置

b. 由生产者客户机通过在创建消息生产者时指定的设置进行设置

c. 由生产者客户机逐一对各条消息进行设置

 

2. 属性(property)

消息可以包含称作属性的可选头字段。他们是以属性名和属性值对的形式制定的。可以将属性是为消息头得扩展,其中可以包括如下信息:创建数据的进程、数据的创建时间以及每条数据的结构。JMS提供者也可以添加影响消息处理的属性,如是否应压缩消息或如何在消息生命周期结束时废弃消息。

 

3. 主体(body)

包含要发送给接收应用程序的内容。每个消息接口特定于它所支持的内容类型。JMS为不同类型的内容提供了他们各自的消息类型,但是所有消息都派生自Message接口。

StreamMessage   一种主体中包含Java基元值流的消息。其填充和读取均按顺序进行。

MapMessage     一种主体中包含一组键--值对的消息。没有定义条目顺序。

TextMessage       一种主体中包含Java字符串的消息(例如,XML消息)。

ObjectMessage    一种主体中包含序列化Java对象的消息。

BytesMessage     一种主体中包含连续字节流的消息。

例如:MapMessage 消息格式

 

Json代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=MapMessage%3D%7B%0A%20%20%20%20Header%3D%7B%0A%20%20%20%20%20%20%20%20...%20standard%20headers%20...%0A%20%20%20%20%20%20%20%20CorrelationID%3D%7B123-00001%7D%0A%20%20%20%20%7D%0A%20%20%20%20Properties%3D%7B%0A%20%20%20%20%20%20%20%20AccountID%3D%7BInteger%3A1234%7D%0A%20%20%20%20%7D%0A%20%20%20%20Fields%3D%7B%0A%20%20%20%20%20%20%20%20Name%3D%7BString%3AMark%7D%0A%20%20%20%20%20%20%20%20Age%3D%7BInteger%3A47%7D%0A%20%20%20%20%7D%20%0A%7D" wmode="transparent"> 收藏代码

  1. MapMessage={  

  2.     Header={  

  3.         ... standard headers ...  

  4.         CorrelationID={ 123-00001}  

  5.     }  

  6.     Properties={  

  7.         AccountID={Integer:1234}  

  8.     }  

  9.     Fields={  

  10.         Name={String:Mark}  

  11.         Age={Integer:47}  

  12.     }   

  13. }  

 

消息的传递模型

 

JMS支持两种消息传递模型:点对点(point-to-point,简称PTP)和发布/订阅(publish/subscribe,简称pub/sub)。这两种消息传递模型非常相似,但有以下区别:

a. PTP消息传递模型规定了一条消息之恩能够传递费一个接收方。

b. Pub/sub消息传递模型允许一条消息传递给多个接收方

每个模型都通过扩展公用基类来实现。例如:javax.jms.Queue和Javax.jms.Topic都扩展自javax.jms.Destination类。

 

1. 点对点消息传递

通过点对点的消息传递模型,一个应用程序可以向另外一个应用程序发送消息。在此传递模型中,目标类型时队列。消息首先被传送至队列目标,然后从改对垒将消息传送至对此队列进行监听的某个消费者,如下图:

 

一个队列可以关联多个队列发送方和接收方,但一条消息仅传递给一个接收方。如果多个接收方正在监听队列上的消息,JMS Provider将根据“先来者优先”的原则确定由哪个价售房接受下一条消息。如果没有接收方在监听队列,消息将保留在队列中,直至接收方连接到队列为止。这种消息传递模型是传统意义上的拉模型或轮询模型。在此列模型中,消息不时自动推动给客户端的,而是要由客户端从队列中请求获得

 

2. 发布/订阅消息传递

通过发布/订阅消息传递模型,应用程序能够将一条消息发送到多个接收方。在此传送模型中,目标类型是主题。消息首先被传送至主题目标,然后传送至所有已订阅此主题的或送消费者。如下图:

 

主题目标也支持长期订阅。长期订阅表示消费者已注册了主题目标,但在消息到达目标时改消费者可以处于非活动状态。当消费者再次处于活动状态时,将会接收该消息。如果消费者均没有注册某个主题目标,该主题只保留注册了长期订阅的非活动消费者的消息。与PTP消息传递模型不同,pub/sub消息传递模型允许多个主题订阅者接收同一条消息。JMS一直保留消息,直至所有主题订阅者都接收到消息为止。pub/sub消息传递模型基本上时一个推模型。在该模型中,消息会自动广播,消费者无须通过主动请求或轮询主题的方法来获得新的消息。

 

上面两种消息传递模型里,我们都需要定义消息生产者和消费者,生产者吧消息发送到JMS Provider的某个目标地址(Destination),消息从该目标地址传送至消费者。消费者可以同步或异步接收消息,一般而言,异步消息消费者的执行和伸缩性都优于同步消息接收者,体现在:

1. 异步消息接收者创建的网络流量比较小。单向对东消息,并使之通过管道进入消息监听器。管道操作支持将多条消息聚合为一个网络调用。

2. 异步消息接收者使用线程比较少。异步消息接收者在不活动期间不使用线程。同步消息接收者在接收调用期间内使用线程,结果线程可能会长时间保持空闲,尤其是如果该调用中指定了阻塞超时。

3.对于服务器上运行的应用程序代码,使用异步消息接收者几乎总是最佳选择,尤其是通过消息驱动Bean。使用异步消息接收者可以防止应用程序代码在服务器上执行阻塞操作。而阻塞操作会是服务器端线程空闲,甚至会导致死锁。阻塞操作使用所有线程时则发生死锁。如果没有空余的线程可以处理阻塞操作自身解锁所需的操作,这该操作永远无法停止阻塞。

 

 

2. JMS Provider(ActiveMQ)

 

特性及优势

 

1. 实现JMS1.1规范,支持J2EE1.4以上。

2. 可运行与任何JVM和大部分web容器(ActiveMQ works great in any JVM)

3. 支持多种语言客户端(java, C, C++, Ajax, ActionScript等等)

4. 支持多种协议(stomp, openwire, REST)

5. 良好的Spring支持(ActiveMQ has great Spring Support)

6. 速度很快,JBossMQ的十倍(ActiveMQ is very fast; often 10x faster than JBossMQ)

7. 与OpenJMS、JBossMQ等开源jms provider相比,ActiveMQ有apache的支持,持续发展的优势明显

 

Queue与Topic的比较

 

1. JMS Queue执行load balancer语义

    一条消息仅能被一个consumer收到。如果在message发送的时候没有可用的consumer,那么它讲被保存一直到能处理该message的consumer可用。如果一个consumer收到一条message后却不响应它,那么这条消息将被转到另外一个consumer那儿。一个Queue可以有很多consumer,并且在多个可用的consumer中负载均衡。

 

2. Topic实现publish和subscribe语义

    一条消息被publish时,他将发送给所有感兴趣的订阅者,所以零到多个subscriber将接收到消息的一个拷贝。但是在消息代理接收到消息时,只有激活订阅的subscriber能够获得消息的一个拷贝。

 

3. 分别对应两种消息模式

    Point-to-Point(点对点),Publisher/Subscriber Model(发布/订阅者)

    其中在Publicher/Subscriber模式下又有Nondurable subscription(非持久化订阅)和durable subscription(持久化订阅)两种消息处理方式。

 

Point-to-Point(点对点)消息模式开发流程

 

1. 生产者(producer)开发流程

 

    1.1 创建 Connection

Java代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%2F%2F%20%E6%A0%B9%E6%8D%AEurl%EF%BC%8Cuser%E5%92%8Cpassword%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AAjms%20Connection%E3%80%82%0AActiveMQConnectionFactory%20connectionFactory%20%20%20%3D%20%20%20new%20ActiveMQConnectionFactory%20(user%2C%20password%2C%20url)%3B%0Aconnection%20%3D%20connectionFactory.createConnection()%3B%0Aconnection.start()%3B%0A" wmode="transparent"> 收藏代码

  1. // 根据url,user和password创建一个jms Connection。  

  2. ActiveMQConnectionFactory connectionFactory   =   new ActiveMQConnectionFactory (user, password, url);  

  3. connection = connectionFactory.createConnection();  

  4. connection.start();  

 

    1.2 创建Session

Java代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%2F**%E5%9C%A8connection%E7%9A%84%E5%9F%BA%E7%A1%80%E4%B8%8A%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AAsession%EF%BC%8C%E5%90%8C%E6%97%B6%E8%AE%BE%E7%BD%AE%E6%98%AF%E5%90%A6%E6%94%AF%E6%8C%81%E4%BA%8B%E5%8A%A1ACKNOWLEDGE%E6%A0%87%E8%AF%86%E3%80%82%0A%E2%80%A2%20AUTO_ACKNOWLEDGE%EF%BC%9A%E8%87%AA%E5%8A%A8%E7%A1%AE%E8%AE%A4%E6%A8%A1%E5%BC%8F%E3%80%82%E4%B8%80%E6%97%A6%E6%8E%A5%E6%94%B6%E6%96%B9%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E7%9A%84%E6%96%B9%E6%B3%95%E8%B0%83%E7%94%A8%E4%BB%8E%E5%A4%84%E7%90%86%E6%B6%88%E6%81%AF%E5%A4%84%E8%BF%94%E5%9B%9E%EF%BC%8C%E4%BC%9A%E8%AF%9D%E5%AF%B9%E8%B1%A1%E5%B0%B1%E4%BC%9A%E7%A1%AE%E8%AE%A4%E6%B6%88%E6%81%AF%E7%9A%84%E6%8E%A5%E6%94%B6%E3%80%82%20%0A%E2%80%A2%20CLIENT_ACKNOWLEDGE%EF%BC%9A%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%A1%AE%E8%AE%A4%E6%A8%A1%E5%BC%8F%E3%80%82%E4%BC%9A%E8%AF%9D%E5%AF%B9%E8%B1%A1%E4%BE%9D%E8%B5%96%E4%BA%8E%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E5%AF%B9%E8%A2%AB%E6%8E%A5%E6%94%B6%E7%9A%84%E6%B6%88%E6%81%AF%E8%B0%83%E7%94%A8%E4%B8%80%E4%B8%AAacknowledge()%E6%96%B9%E6%B3%95%E3%80%82%E4%B8%80%E6%97%A6%E8%BF%99%E4%B8%AA%E6%96%B9%E6%B3%95%E8%A2%AB%E8%B0%83%E7%94%A8%EF%BC%8C%E4%BC%9A%E8%AF%9D%E4%BC%9A%E7%A1%AE%E8%AE%A4%E6%9C%80%E5%90%8E%E4%B8%80%E6%AC%A1%E7%A1%AE%E8%AE%A4%E4%B9%8B%E5%90%8E%E6%89%80%E6%9C%89%E6%8E%A5%E6%94%B6%E5%88%B0%E7%9A%84%E6%B6%88%E6%81%AF%E3%80%82%E8%BF%99%E7%A7%8D%E6%A8%A1%E5%BC%8F%E5%85%81%E8%AE%B8%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E4%BB%A5%E4%B8%80%E4%B8%AA%E8%B0%83%E7%94%A8%E6%9D%A5%E6%8E%A5%E6%94%B6%EF%BC%8C%E5%A4%84%E7%90%86%E5%B9%B6%E7%A1%AE%E8%AE%A4%E4%B8%80%E6%89%B9%E6%B6%88%E6%81%AF%E3%80%82%E6%B3%A8%E6%84%8F%EF%BC%9A%E5%9C%A8%E7%AE%A1%E7%90%86%E6%8E%A7%E5%88%B6%E5%8F%B0%E4%B8%AD%EF%BC%8C%E5%A6%82%E6%9E%9C%E8%BF%9E%E6%8E%A5%E5%B7%A5%E5%8E%82%E7%9A%84Acknowledge%20Policy%EF%BC%88%E7%A1%AE%E8%AE%A4%E6%96%B9%E9%92%88%EF%BC%89%E5%B1%9E%E6%80%A7%E8%A2%AB%E8%AE%BE%E7%BD%AE%E4%B8%BA%22Previous%22%EF%BC%88%E6%8F%90%E5%89%8D%EF%BC%89%EF%BC%8C%E4%BD%86%E6%98%AF%E4%BD%A0%E5%B8%8C%E6%9C%9B%E4%B8%BA%E4%B8%80%E4%B8%AA%E7%BB%99%E5%AE%9A%E7%9A%84%E4%BC%9A%E8%AF%9D%E7%A1%AE%E8%AE%A4%E6%89%80%E6%9C%89%E6%8E%A5%E6%94%B6%E5%88%B0%E7%9A%84%E6%B6%88%E6%81%AF%EF%BC%8C%E9%82%A3%E4%B9%88%E5%B0%B1%E7%94%A8%E6%9C%80%E5%90%8E%E4%B8%80%E6%9D%A1%E6%B6%88%E6%81%AF%E6%9D%A5%E8%B0%83%E7%94%A8acknowledge()%E6%96%B9%E6%B3%95%E3%80%82%20%0A%E2%80%A2%20DUPS_OK_ACKNOWLEDGE%EF%BC%9A%E5%85%81%E8%AE%B8%E5%89%AF%E6%9C%AC%E7%9A%84%E7%A1%AE%E8%AE%A4%E6%A8%A1%E5%BC%8F%E3%80%82%E4%B8%80%E6%97%A6%E6%8E%A5%E6%94%B6%E6%96%B9%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E7%9A%84%E6%96%B9%E6%B3%95%E8%B0%83%E7%94%A8%E4%BB%8E%E5%A4%84%E7%90%86%E6%B6%88%E6%81%AF%E5%A4%84%E8%BF%94%E5%9B%9E%EF%BC%8C%E4%BC%9A%E8%AF%9D%E5%AF%B9%E8%B1%A1%E5%B0%B1%E4%BC%9A%E7%A1%AE%E8%AE%A4%E6%B6%88%E6%81%AF%E7%9A%84%E6%8E%A5%E6%94%B6%EF%BC%9B%E8%80%8C%E4%B8%94%E5%85%81%E8%AE%B8%E9%87%8D%E5%A4%8D%E7%A1%AE%E8%AE%A4%E3%80%82%E5%9C%A8%E9%9C%80%E8%A6%81%E8%80%83%E8%99%91%E8%B5%84%E6%BA%90%E4%BD%BF%E7%94%A8%E6%97%B6%EF%BC%8C%E8%BF%99%E7%A7%8D%E6%A8%A1%E5%BC%8F%E9%9D%9E%E5%B8%B8%E6%9C%89%E6%95%88%E3%80%82%E6%B3%A8%E6%84%8F%EF%BC%9A%E5%A6%82%E6%9E%9C%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E6%97%A0%E6%B3%95%E5%A4%84%E7%90%86%E9%87%8D%E5%A4%8D%E7%9A%84%E6%B6%88%E6%81%AF%E7%9A%84%E8%AF%9D%EF%BC%8C%E4%BD%A0%E5%BA%94%E8%AF%A5%E9%81%BF%E5%85%8D%E4%BD%BF%E7%94%A8%E8%BF%99%E7%A7%8D%E6%A8%A1%E5%BC%8F%E3%80%82%E5%A6%82%E6%9E%9C%E5%8F%91%E9%80%81%E6%B6%88%E6%81%AF%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E5%B0%9D%E8%AF%95%E5%A4%B1%E8%B4%A5%EF%BC%8C%E9%82%A3%E4%B9%88%E9%87%8D%E5%A4%8D%E7%9A%84%E6%B6%88%E6%81%AF%E5%8F%AF%E4%BB%A5%E8%A2%AB%E9%87%8D%E6%96%B0%E5%8F%91%E9%80%81%E3%80%82%0A%E2%80%A2%20%20SESSION_TRANSACTED**%2F%0ASession%20session%20%3D%20connection.createSession(%0Atransacted%2C%20Session.AUTO_ACKNOWLEDGE)%3B" wmode="transparent"> 收藏代码

  1. /**在connection的基础上创建一个session,同时设置是否支持事务ACKNOWLEDGE标识。 

  2. • AUTO_ACKNOWLEDGE:自动确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会话对象就会确认消息的接收。  

  3. • CLIENT_ACKNOWLEDGE:客户端确认模式。会话对象依赖于应用程序对被接收的消息调用一个acknowledge()方法。一旦这个方法被调用,会话会确认最后一次确认之后所有接收到的消息。这种模式允许应用程序以一个调用来接收,处理并确认一批消息。注意:在管理控制台中,如果连接工厂的Acknowledge Policy(确认方针)属性被设置为"Previous"(提前),但是你希望为一个给定的会话确认所有接收到的消息,那么就用最后一条消息来调用acknowledge()方法。  

  4. • DUPS_OK_ACKNOWLEDGE:允许副本的确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会话对象就会确认消息的接收;而且允许重复确认。在需要考虑资源使用时,这种模式非常有效。注意:如果你的应用程序无法处理重复的消息的话,你应该避免使用这种模式。如果发送消息的初始化尝试失败,那么重复的消息可以被重新发送。 

  5. •  SESSION_TRANSACTED**/  

  6. Session session = connection.createSession(  

  7. transacted, Session.AUTO_ACKNOWLEDGE);  

 

    1.3 创建Destination对象

Java代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%2F%2F%E9%9C%80%E6%8C%87%E5%AE%9A%E5%85%B6%E5%AF%B9%E5%BA%94%E7%9A%84%E4%B8%BB%E9%A2%98%EF%BC%88subject%EF%BC%89%E5%90%8D%E7%A7%B0%EF%BC%8Cproducer%E5%92%8Cconsumer%E5%B0%86%E6%A0%B9%E6%8D%AEsubject%E6%9D%A5%E5%8F%91%E9%80%81%2F%E6%8E%A5%E6%94%B6%E5%AF%B9%E5%BA%94%E7%9A%84%E6%B6%88%E6%81%AF%0Aif%20(topic)%20%7B%0A%09destination%20%3D%20session.createTopic(subject)%3B%0A%7D%20else%20%7B%0A%09destination%20%3D%20session.createQueue(subject)%3B%0A%7D" wmode="transparent"> 收藏代码

  1. //需指定其对应的主题(subject)名称,producer和consumer将根据subject来发送/接收对应的消息  

  2. if (topic) {  

  3.     destination = session.createTopic(subject);  

  4. else {  

  5.     destination = session.createQueue(subject);  

  6. }  

 

    1.4 创建MessageProducer

Java代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%2F%2F%E6%A0%B9%E6%8D%AEDestination%E5%88%9B%E5%BB%BAMessageProducer%E5%AF%B9%E8%B1%A1%EF%BC%8C%E5%90%8C%E6%97%B6%E8%AE%BE%E7%BD%AE%E5%85%B6%E6%8C%81%E4%B9%85%E6%A8%A1%E5%BC%8F%E3%80%82%20%0AMessageProducer%20producer%20%3D%20session.createProducer(destination)%3B%0Aif%20(persistent)%20%7B%0A%20%20%20%20%20%20producer.setDeliveryMode(DeliveryMode.PERSISTENT)%3B%0A%7D%20else%20%7B%0A%20%20%20%20%20%20producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT)%3B%0A%7D%0Aif%20(timeToLive%20!%3D%200)%20%7B%0A%20%20%20%20%20%20%20producer.setTimeToLive(timeToLive)%3B%0A%7D%26nbsp%3B" wmode="transparent"> 收藏代码

  1. //根据Destination创建MessageProducer对象,同时设置其持久模式。   

  2. MessageProducer producer = session.createProducer(destination);  

  3. if (persistent) {  

  4.       producer.setDeliveryMode(DeliveryMode.PERSISTENT);  

  5. else {  

  6.       producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);  

  7. }  

  8. if (timeToLive != 0) {  

  9.        producer.setTimeToLive(timeToLive);  

  10. }   

 

    1.5 发送消息到队列(Queue)

Java代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%2F%2F%E5%B0%81%E8%A3%85TextMessage%E6%B6%88%E6%81%AF%EF%BC%8C%E4%BD%BF%E7%94%A8MessageProducer%E7%9A%84send%E6%96%B9%E6%B3%95%E5%B0%86%E6%B6%88%E6%81%AF%E5%8F%91%E9%80%81%E5%87%BA%E5%8E%BB%E3%80%82%0ATextMessage%20message%20%3D%20session.createTextMessage(%22createMessageText%22)%3B%0Aproducer.send(message)%3B" wmode="transparent"> 收藏代码

  1. //封装TextMessage消息,使用MessageProducer的send方法将消息发送出去。  

  2. TextMessage message = session.createTextMessage("createMessageText");  

  3. producer.send(message);  

 

2. 消费者(consumer)开发流程

 

    2.1 实现MessageListener接口

Java代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%2F%2F%E6%B6%88%E8%B4%B9%E8%80%85%E7%B1%BB%E5%BF%85%E9%A1%BB%E5%AE%9E%E7%8E%B0MessageListener%E6%8E%A5%E5%8F%A3%EF%BC%8C%E7%84%B6%E5%90%8E%E5%9C%A8onMessage%E6%96%B9%E6%B3%95%E4%B8%AD%E7%9B%91%E5%90%AC%E6%B6%88%E6%81%AF%E5%88%B0%E8%BE%BE%E5%A4%84%E7%90%86%E3%80%82" wmode="transparent"> 收藏代码

  1. //消费者类必须实现MessageListener接口,然后在onMessage方法中监听消息到达处理。  

 

    2.2 创建Connection

Java代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%2F%2F%E6%A0%B9%E6%8D%AEurl%EF%BC%8Cuser%E5%92%8Cpassword%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AAjms%20Connection%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%98%AFdurable%E6%A8%A1%E5%BC%8F%EF%BC%8C%E8%BF%98%E9%9C%80%E8%A6%81%E7%BB%99connection%E8%AE%BE%E7%BD%AE%E4%B8%80%E4%B8%AAclientId%E3%80%82%0AActiveMQConnectionFactory%20connectionFactory%20%3D%20new%20ActiveMQConnectionFactory(user%2C%20password%2C%20url)%3B%0AConnection%20connection%20%3D%20connectionFactory.createConnection()%3B%0Aif%20(durable%20%26%26%20clientId%20!%3D%20null%20%26%26%20clientId.length()%20%3E%200%20%26%26%20!%22null%22.equals(clientId))%20%7B%0A%20%20%20%20%20%20connection.setClientID(clientId)%3B%0A%7D%0Aconnection.setExceptionListener(this)%3B%0Aconnection.start()%3B" wmode="transparent"> 收藏代码

  1. //根据url,user和password创建一个jms Connection,如果是durable模式,还需要给connection设置一个clientId。  

  2. ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user, password, url);  

  3. Connection connection = connectionFactory.createConnection();  

  4. if (durable && clientId != null && clientId.length() > 0 && !"null".equals(clientId)) {  

  5.       connection.setClientID(clientId);  

  6. }  

  7. connection.setExceptionListener(this);  

  8. connection.start();  

 

    2.3 创建Session和Destination

Java代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%2F%2F%E4%B8%8E%E4%BA%A7%E5%93%81%E7%B1%BB%E4%BC%BC" wmode="transparent"> 收藏代码

  1. //与产品类似  

 

    2.4 创建replayProducer【可选】

Java代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%2F%2F%E5%8F%AF%E4%BB%A5%E7%94%A8%E6%9D%A5%E5%B0%86%E6%B6%88%E6%81%AF%E5%A4%84%E7%90%86%E7%BB%93%E6%9E%9C%E5%8F%91%E9%80%81%E7%BB%99producer%E3%80%82%20%0AreplyProducer%20%3D%20session.createProducer(null)%3B%0AreplyProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT)%3B%3Cspan%20style%3D%22white-space%3A%20normal%3B%22%3E%26nbsp%3B%3C%2Fspan%3E" wmode="transparent"> 收藏代码

  1. //可以用来将消息处理结果发送给producer。   

  2. replyProducer = session.createProducer(null);  

  3. replyProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);<span style="white-space: normal;"> </span>  

 

    2.5 创建MessageConsumer

Java代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%2F%2F%E6%A0%B9%E6%8D%AEDestination%E5%88%9B%E5%BB%BAMessageConsumer%E5%AF%B9%E8%B1%A1%E3%80%82%0AMessageConsumer%20consumer%20%3D%20null%3B%0Aif%20(durable%20%26%26%20topic)%20%7B%0A%20%20%20%20%20consumer%20%3D%20session.createDurableSubscriber((Topic)destination%2C%20consumerName)%3B%0A%7D%20else%20%7B%0A%20%20%20%20%20consumer%20%3D%20session.createConsumer(destination)%3B%0A%7D%3Cspan%20style%3D%22white-space%3A%20normal%3B%22%3E%26nbsp%3B%3C%2Fspan%3E" wmode="transparent"> 收藏代码

  1. //根据Destination创建MessageConsumer对象。  

  2. MessageConsumer consumer = null;  

  3. if (durable && topic) {  

  4.      consumer = session.createDurableSubscriber((Topic)destination, consumerName);  

  5. else {  

  6.      consumer = session.createConsumer(destination);  

  7. }<span style="white-space: normal;"> </span>  

 

    2.6 消费message

Java代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%2F%2F%E5%9C%A8onMessage()%E6%96%B9%E6%B3%95%E4%B8%AD%E6%8E%A5%E6%94%B6producer%E5%8F%91%E9%80%81%E8%BF%87%E6%9D%A5%E7%9A%84%E6%B6%88%E6%81%AF%E8%BF%9B%E8%A1%8C%E5%A4%84%E7%90%86%EF%BC%8C%E5%B9%B6%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87replyProducer%E5%8F%8D%E9%A6%88%E4%BF%A1%E6%81%AF%E7%BB%99producer%20%0Aif%20(message.getJMSReplyTo()%20!%3D%20null)%20%7B%20%0A%09replyProducer.send(message.getJMSReplyTo()%2C%20%0A%09session.createTextMessage(%22Reply%3A%20%22%20%2B%20message.getJMSMessageID()))%3B%20%0A%7D%20%20%0A" wmode="transparent"> 收藏代码

  1. //在onMessage()方法中接收producer发送过来的消息进行处理,并可以通过replyProducer反馈信息给producer   

  2. if (message.getJMSReplyTo() != null) {   

  3.     replyProducer.send(message.getJMSReplyTo(),   

  4.     session.createTextMessage("Reply: " + message.getJMSMessageID()));   

  5. }    

 

 

Publish/Subscriber(发布/订阅者)消息开发模式

 

1. 订阅者(Subscriber)开发流程

 

    1.1 实现MessageListener接口

  在onMessage()方法中监听发布者发出的消息队列,并做相应处理。

 

    1.2 创建Connection

          根据url, user和password创建一个jms connection

 

    1.3 创建Session

  在connection的基础上创建一个session,同时设置是否支持和ACKNOWLEDGE标志。

 

    1.4 创建 Topic

          创建两个Topic,topictest.message用于接收发布者发出的消息,topictest.control用于向发布者发送消息,实现双方的交互。

 

    1.5 创建consumer和producer对象

  根据topictest.message创建consumer,根据topictest.control创建producer

 

    1.6 接收处理消息

  在onMessage()方法中,对收到的消息进行处理,可直接简单在本地显示消息,或者根据消息内容不同处理对应的业务逻辑(比如:数据库更新、文件操作等等),并且可以使用   producer对象处理结果返回给发布者。

 

 

2. 发布者(Publisher)开发流程

 

     2.1 实现MessageListener接口 

   在onMessage()方法中接收订阅者的反馈消息。

 

     2.2 创建Connection

   根据url, user和password 创建一个 jms Connection。

 

     2.3 创建session

   在connection的基础上创建一个session,同时设置是否支持事务和ACKNOWLEDGE标志。

 

     2.4 创建Topic

   创建两个Topic,topictest.messages用于向订阅者发布消息,topictest.control用于接收订阅者反馈的消息。这两个Topic与订阅者开发流程中的topic是一一对应的。

 

     2.5 创建consumer和producer对象

   根据topictest.message创建publisher;

   根据topictest.control穿件consumer,同时监听订阅者反馈的消息。

 

3. JMS For Spring

 

      Spring提供了用于简化JMS API使用的抽象框架,并且对用户屏蔽了JMS API中1.0.2和1.1版本的差异。

      JMS的功能大致上分为两块,叫做消息制造和消息消耗。JmsTemplate用于制造消息和同步消息接收。和J2EE的事件驱动Bean风格类似,对于异步接收消息,Spring提供了一些消息监听容器来创建消息驱动的POJO(MDP)。

 

1. Spring 配置 connectionFactory

Xml代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%3C!--%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8%E6%99%AE%E9%80%9A%E4%BC%A0%E8%BE%93%E6%96%B9%E5%BC%8F%EF%BC%9Atcp%3A%2F%2Flocalhost%3A61616%20%0A%09%E6%AD%A4%E5%A4%84%E9%9C%80%E5%8A%A0%E4%BB%A5%E6%B3%A8%E6%84%8F%E7%9A%84%E6%98%AFListener%E7%AB%AF%E7%9A%84borkerURL%E4%BD%BF%E7%94%A8%E4%BA%86failover%E4%BC%A0%E8%BE%93%E6%96%B9%E5%BC%8F%EF%BC%9A%20%0A%09failover%3A(tcp%3A%2F%2Flocalhost%3A61616)%3FinitialReconnectDelay%3D100%26amp%3B%0AmaxReconnectAttempts%3D5%20%0A%09failover%20transport%E6%98%AF%E4%B8%80%E7%A7%8D%E9%87%8D%E6%96%B0%E8%BF%9E%E6%8E%A5%E6%9C%BA%E5%88%B6%EF%BC%8C%E7%94%A8%E4%BA%8E%E5%BB%BA%E7%AB%8B%E5%8F%AF%E9%9D%A0%E7%9A%84%E4%BC%A0%E8%BE%93%E3%80%82%E6%AD%A4%E5%A4%84%E9%85%8D%E7%BD%AE%E7%9A%84%E6%98%AF%E4%B8%80%E6%97%A6ActiveMQ%20broker%E4%B8%AD%E6%96%AD%EF%BC%8CListener%E7%AB%AF%E5%B0%86%E6%AF%8F%E9%9A%94100ms%E8%87%AA%E5%8A%A8%E5%B0%9D%E8%AF%95%E8%BF%9E%E6%8E%A5%EF%BC%8C%E7%9B%B4%E8%87%B3%E6%88%90%E5%8A%9F%E8%BF%9E%E6%8E%A5%E6%88%96%E9%87%8D%E8%AF%955%E6%AC%A1%E8%BF%9E%E6%8E%A5%E5%A4%B1%E8%B4%A5%E4%B8%BA%E6%AD%A2%E3%80%82%0A%09failover%E8%BF%98%E6%94%AF%E6%8C%81%E5%A4%9A%E4%B8%AAborker%E5%90%8C%E6%97%B6%E6%8F%90%E4%BE%9B%E6%9C%8D%E5%8A%A1%EF%BC%8C%E5%AE%9E%E7%8E%B0%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E7%9A%84%E5%90%8C%E6%97%B6%E5%8F%AF%E5%A2%9E%E5%8A%A0%E7%B3%BB%E7%BB%9F%E5%AE%B9%E9%94%99%E6%80%A7%EF%BC%8C%E6%A0%BC%E5%BC%8F%EF%BC%9A%20failover%3A(uri1%2C...%2CuriN)%3FtransportOptions%0A--%3E%0A%3Cbean%20id%3D%22jmsFactory%22%20destroy-method%3D%22stop%22%20class%3D%22org.apache.activemq.pool.PooledConnectionFactory%22%3E%0A%09%09%3Cproperty%20name%3D%22connectionFactory%22%3E%0A%09%09%09%3Cbean%20class%3D%22org.apache.activemq.ActiveMQConnectionFactory%22%3E%0A%09%09%09%09%3Cproperty%20name%3D%22brokerURL%22%20value%3D%22tcp%3A%2F%2Flocalhost%3A61616%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cproperty%20name%3D%22userName%22%20value%3D%22%24%7Bactivemq.username%7D%22%20%2F%3E%0A%09%09%09%09%3Cproperty%20name%3D%22password%22%20value%3D%22%24%7Bactivemq.password%7D%22%20%2F%3E%0A%09%09%09%3C%2Fbean%3E%0A%09%09%3C%2Fproperty%3E%0A%3C%2Fbean%3E%0A" wmode="transparent"> 收藏代码

  1. <!--客户端使用普通传输方式:tcp://localhost:61616   

  2.     此处需加以注意的是Listener端的borkerURL使用了failover传输方式:   

  3.     failover:(tcp://localhost:61616)?initialReconnectDelay=100&amp;  

  4. maxReconnectAttempts=5   

  5.     failover transport是一种重新连接机制,用于建立可靠的传输。此处配置的是一旦ActiveMQ broker中断,Listener端将每隔100ms自动尝试连接,直至成功连接或重试5次连接失败为止。  

  6.     failover还支持多个borker同时提供服务,实现负载均衡的同时可增加系统容错性,格式: failover:(uri1,...,uriN)?transportOptions  

  7. -->  

  8. <bean id="jmsFactory" destroy-method="stop" class="org.apache.activemq.pool.PooledConnectionFactory">  

  9.         <property name="connectionFactory">  

  10.             <bean class="org.apache.activemq.ActiveMQConnectionFactory">  

  11.                 <property name="brokerURL" value="tcp://localhost:61616" />  

  12.                  <property name="userName" value="${activemq.username}" />  

  13.                 <property name="password" value="${activemq.password}" />  

  14.             </bean>  

  15.         </property>  

  16. </bean>  

  

2. Spring JmsTemplate

Xml代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%3C!--%20Spring%20JMS%20Template%0A%09%09JmsTemplate%20%E7%B1%BB%E7%9A%84%E5%AE%9E%E4%BE%8B%20%E4%B8%80%E7%BB%8F%E9%85%8D%E7%BD%AE%E4%BE%BF%E6%98%AF%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%20%E7%9A%84%E3%80%82%20%E8%A6%81%E6%B8%85%E6%A5%9A%E4%B8%80%E7%82%B9%EF%BC%8CJmsTemplate%20%0A%09%09%E6%98%AF%E6%9C%89%E7%8A%B6%E6%80%81%E7%9A%84%EF%BC%8C%E5%9B%A0%E4%B8%BA%E5%AE%83%E7%BB%B4%E6%8A%A4%E4%BA%86%20ConnectionFactory%20%E7%9A%84%E5%BC%95%E7%94%A8%EF%BC%8C%E4%BD%86%E8%BF%99%E4%B8%AA%E7%8A%B6%E6%80%81%E6%97%B6%E4%B8%8D%E6%98%AF%E4%BC%9A%E8%AF%9D%E7%8A%B6%E6%80%81%E3%80%82%0A--%3E%0A%09%3Cbean%20id%3D%22myJmsTemplate%22%0A%09%09class%3D%22org.springframework.jms.core.JmsTemplate%22%3E%0A%09%09%3Cproperty%20name%3D%22connectionFactory%22%20ref%3D%22jmsFactory%22%20%2F%3E%0A%09%09%3Cproperty%20name%3D%22defaultDestinationName%22%20value%3D%22MySubject%22%20%2F%3E%0A%09%09%3C!--JMS%20API%E6%9C%89%E4%B8%A4%E7%A7%8D%E5%8F%91%E9%80%81%E6%96%B9%E6%B3%95%EF%BC%8C%E4%B8%80%E7%A7%8D%E9%87%87%E7%94%A8%E5%8F%91%E9%80%81%E6%A8%A1%E5%BC%8F%E3%80%81%0A%E4%BC%98%E5%85%88%E7%BA%A7%E5%92%8C%E5%AD%98%E6%B4%BB%E6%97%B6%E9%97%B4%E4%BD%9C%E4%B8%BA%E6%9C%8D%E5%8A%A1%E8%B4%A8%E9%87%8F%EF%BC%88QOS%EF%BC%89%E5%8F%82%E6%95%B0%EF%BC%8C%0A%09%09%09%E9%BB%98%E8%AE%A4%7BdeliveryMode%3A2(1)%2Cpriority%3A4%2CtimeToLive%3A0%7D%0A%09%09%09%E5%8F%A6%E4%B8%80%E7%A7%8D%E4%BD%BF%E7%94%A8%E6%97%A0%E9%9C%80QOS%E5%8F%82%E6%95%B0%E7%9A%84%E7%BC%BA%E7%9C%81%E5%80%BC%E6%96%B9%E6%B3%95%E3%80%82%0A%09%09%09%3Cproperty%20name%3D%22explicitQosEnabled%22%20value%3D%22true%22%2F%3E%0A%09%09%09%3Cproperty%20name%3D%22deliveryMode%22%20value%3D%222%22%2F%3E%0A%09%09%09%3Cproperty%20name%3D%22priority%22%20value%3D%224%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cproperty%20name%3D%22timeToLive%22%20value%3D%221000%22%2F%3E%0A%09%09%20--%3E%0A%09%09%3C!--%0A%09%09%20%09%3Cproperty%20name%3D%22receiveTimeout%22%20value%3D%221000%22%20%2F%3E%0A%09%09%20--%3E%0A%09%3C%2Fbean%3E%0A" wmode="transparent"> 收藏代码

  1. <!-- Spring JMS Template  

  2.         JmsTemplate 类的实例 一经配置便是线程安全 的。 要清楚一点,JmsTemplate   

  3.         是有状态的,因为它维护了 ConnectionFactory 的引用,但这个状态时不是会话状态。  

  4. -->  

  5.     <bean id="myJmsTemplate"  

  6.         class="org.springframework.jms.core.JmsTemplate">  

  7.         <property name="connectionFactory" ref="jmsFactory" />  

  8.         <property name="defaultDestinationName" value="MySubject" />  

  9.         <!--JMS API有两种发送方法,一种采用发送模式、  

  10. 优先级和存活时间作为服务质量(QOS)参数,  

  11.             默认{deliveryMode:2(1),priority:4,timeToLive:0}  

  12.             另一种使用无需QOS参数的缺省值方法。  

  13.             <property name="explicitQosEnabled" value="true"/>  

  14.             <property name="deliveryMode" value="2"/>  

  15.             <property name="priority" value="4"/>  

  16.                         <property name="timeToLive" value="1000"/>  

  17.          -->  

  18.         <!-- 

  19.             <property name="receiveTimeout" value="1000" /> 

  20.          -->  

  21.     </bean>  

  

3. 发送的接收消息

Xml代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%3Cbean%20id%3D%22destinationTopic%22%0A%09%09class%3D%22org.apache.activemq.command.ActiveMQTopic%22%3E%0A%09%09%3Cconstructor-arg%20index%3D%220%22%20value%3D%22HelloWorldTopic%22%20%2F%3E%0A%09%3C%2Fbean%3E%0A%09%3C!--%20%E8%AF%BB%E5%8F%96%E4%BF%A1%E6%81%AF%20--%3E%0A%09%3Cbean%20id%3D%22consumer%22%20class%3D%22com.d1xn.jms.demo.Consumer%22%3E%0A%09%09%3Cproperty%20name%3D%22jmsTemplate%22%20ref%3D%22myJmsTemplate%22%20%2F%3E%0A%09%3C%2Fbean%3E%0A%0A%09%3C!--%20%E5%8F%91%E9%80%81%E4%BF%A1%E6%81%AF%20--%3E%0A%09%3Cbean%20id%3D%22producerTopic%22%20class%3D%22com.d1xn.jms.demo.ProducerTopic%22%3E%0A%09%09%3Cproperty%20name%3D%22jmsTemplet%22%20ref%3D%22myJmsTemplate%22%20%2F%3E%0A%09%09%3Cproperty%20name%3D%22destination%22%20ref%3D%22destinationTopic%22%20%2F%3E%0A%09%3C%2Fbean%3E%0A%09%3C!--%20%E6%B6%88%E6%81%AF%E7%9B%91%E5%90%AC%20--%3E%0A%0A%09%3Cbean%20id%3D%22listenerContainerTopic%22%0Aclass%3D%22org.springframework.jms.listener.DefaultMessageListenerContainer%22%3E%0A%09%09%3Cproperty%20name%3D%22connectionFactory%22%20ref%3D%22jmsFactory%22%20%2F%3E%0A%09%09%3Cproperty%20name%3D%22destination%22%20ref%3D%22destinationTopic%22%20%2F%3E%0A%09%09%3Cproperty%20name%3D%22messageListener%22%20ref%3D%22consumer%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%3C!%E2%80%94%E6%8C%81%E4%B9%85%E5%8C%96%E5%AE%A2%E6%88%B7%E7%AB%AFID%20--%3E%0A%09%09%3Cproperty%20name%3D%22clientId%22%20value%3D%22clientId_001%22%20%2F%3E%0A%09%09%3Cproperty%20name%3D%22subscriptionDurable%22%20value%3D%22true%22%20%2F%3E%0A%09%09%3Cproperty%20name%3D%22durableSubscriptionName%22%20value%3D%22My_001%22%20%2F%3E%0A%3C%2Fbean%3E%0A" wmode="transparent"> 收藏代码

  1. <bean id="destinationTopic"  

  2.         class="org.apache.activemq.command.ActiveMQTopic">  

  3.         <constructor-arg index="0" value="HelloWorldTopic" />  

  4.     </bean>  

  5.     <!-- 读取信息 -->  

  6.     <bean id="consumer" class="com.d1xn.jms.demo.Consumer">  

  7.         <property name="jmsTemplate" ref="myJmsTemplate" />  

  8.     </bean>  

  9.   

  10.     <!-- 发送信息 -->  

  11.     <bean id="producerTopic" class="com.d1xn.jms.demo.ProducerTopic">  

  12.         <property name="jmsTemplet" ref="myJmsTemplate" />  

  13.         <property name="destination" ref="destinationTopic" />  

  14.     </bean>  

  15.     <!-- 消息监听 -->  

  16.   

  17.     <bean id="listenerContainerTopic"  

  18. class="org.springframework.jms.listener.DefaultMessageListenerContainer">  

  19.         <property name="connectionFactory" ref="jmsFactory" />  

  20.         <property name="destination" ref="destinationTopic" />  

  21.         <property name="messageListener" ref="consumer" />  

  22.          <!—持久化客户端ID -->  

  23.         <property name="clientId" value="clientId_001" />  

  24.         <property name="subscriptionDurable" value="true" />  

  25.         <property name="durableSubscriptionName" value="My_001" />  

  26. </bean>  

 

 

说明(基于ActiveMQ5.4.2版本):

        1、Web Console 的安全配置可参考      

 

    将conf/jetty.xml下面一段xml配置:

 

Xml代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%3Cbean%20id%3D%22securityConstraint%22%20class%3D%22org.eclipse.jetty.http.security.Constraint%22%3E%0A%20%20%20%20%3Cproperty%20name%3D%22name%22%20value%3D%22BASIC%22%20%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%3Cproperty%20name%3D%22roles%22%20value%3D%22admin%22%20%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%3Cproperty%20name%3D%22authenticate%22%20value%3D%22true%22%20%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%3C%2Fbean%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A" wmode="transparent"> 收藏代码

  1. <bean id="securityConstraint" class="org.eclipse.jetty.http.security.Constraint">  

  2.     <property name="name" value="BASIC" />                                         

  3.     <property name="roles" value="admin" />                                        

  4.     <property name="authenticate" value="true" />                                  

  5. </bean>                                                                            

 

   authenticate值设置为true即可!那用户名/密码的配置是在conf/jetty-realm.properties!

   详细可参考http://activemq.apache.org/web-console.html

 

2、连接安全配置可参考

     将conf/activemq-security.xml中如下的配置

Xml代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%3Cplugins%3E%20%20%20%20%09%09%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%3C!--%20Configure%20authentication%3B%20Username%2C%20passwords%20and%20groups%20--%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%3CsimpleAuthenticationPlugin%20anonymousAccessAllowed%3D%22false%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%3Cusers%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%3CauthenticationUser%20username%3D%22system%22%20password%3D%22%24%7Bactivemq.password%7D%22%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20groups%3D%22admins%22%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%3C!--%3CauthenticationUser%20username%3D%22user%22%20password%3D%22%24%7Bguest.password%7D%22%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20groups%3D%22users%22%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%3CauthenticationUser%20username%3D%22guest%22%20password%3D%22%24%7Bguest.password%7D%22%20groups%3D%22guests%22%2F%3E--%3E%20%0A%20%20%20%20%3C%2Fusers%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%3C%2FsimpleAuthenticationPlugin%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%3C%2Fplugins%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20" wmode="transparent"> 收藏代码

  1. <plugins>                                                                                          

  2.  <!-- Configure authentication; Username, passwords and groups -->                               

  3.  <simpleAuthenticationPlugin anonymousAccessAllowed="false">                                     

  4.     <users>                                                                                      

  5.         <authenticationUser username="system" password="${activemq.password}"                    

  6.             groups="admins"/>                                                                    

  7.         <!--<authenticationUser username="user" password="${guest.password}"                     

  8.             groups="users"/>                                                                     

  9.         <authenticationUser username="guest" password="${guest.password}" groups="guests"/>-->   

  10.     </users>                                                                                     

  11.  </simpleAuthenticationPlugin>                                                                   

  12. </plugins>                                                                                       

            copy至conf/activemq.xml中

Xml代码 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://boy00fly.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=%3CpersistenceAdapter%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%3CkahaDB%20directory%3D%22%24%7Bactivemq.base%7D%2Fdata%2Fkahadb%22%2F%3E%0A%3C%2FpersistenceAdapter%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20" wmode="transparent"> 收藏代码

  1. <persistenceAdapter>                                    

  2.     <kahaDB directory="${activemq.base}/data/kahadb"/>  

  3. </persistenceAdapter>                                   

      的下面(这是简单的用户名、密码的认证方式)!

   用户名、密码的可在conf/credentials.properties配置!

   详细可参考:

     http://activemq.apache.org/security.html

     http://activemq.apache.org/xml-reference.html

转载于:https://my.oschina.net/u/2353726/blog/616750

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34075551/article/details/92249417

智能推荐

c#/asp.net编程电子称连接电脑_.net连接电子秤-程序员宅基地

文章浏览阅读625次。请参考如下文章: 1 http://dev.firnow.com/course/3_program/cshapo/csharpjs/20100714/441346.html 2 http://topic.csdn.net/u/20080826/19/b4658057-12d6-470b-af5c-3e90b628ff04.html?1891073846_.net连接电子秤

TLS协议详解,一文带你了解TLS协议-程序员宅基地

文章浏览阅读7.9k次,点赞6次,收藏38次。本文介绍了TLS的概论、工作原理、发展历史、算法和参考资料。TLS是一种加密协议,用于保护网络通信的安全性和隐私性。它使用公钥加密和对称密钥加密两种加密方式来保护通信的安全性,可以防止黑客窃取用户的敏感信息。TLS的发展历史可以追溯到SSL 1.0,但由于存在安全漏洞而被废弃。TLS 1.0、TLS 1.1和TLS 1.2分别于1999年、2006年和2008年发布,进一步增强了安全性和性能。常用的加密算法包括AES、RSA、MD5等。_tls协议

Keil5使用技巧(一)—— 编译环境配置_keil5修改编译器-程序员宅基地

文章浏览阅读3.6k次。问题在编译过程中找不到自定义的.h文件;添加新编译的.c文件。问题解决设置编译环境,找到.h文件所在路径:将.h文件所在路径添加后即可编译:将现有.c文件直接添加到Keil工程内:在现有的工程内新建一个文件夹:在新文件夹内添加已编辑好的.c文件即可:..._keil5修改编译器

洛谷普及场 (多维动态规划)-程序员宅基地

文章浏览阅读279次。洛谷普及场 (多维动态规划)- P1508 Likecloud-吃、吃、吃简单dp,注意是从矩阵的中间下方开始吃#include <cstdio>#include <algorithm>using namespace std ; const int N = 205 ; int f[N][N] , dp[N][N] ;int m , n ; int main..._多维动态规划

OpenCV的GrabCut函数使用和源码解读_有了算法模型源码怎么用函数表示-程序员宅基地

文章浏览阅读1.2w次。上一文对GrabCut做了一个了解。OpenCV中的GrabCut算法是依据《"GrabCut" - Interactive Foreground Extraction using Iterated Graph Cuts》这篇文章来实现的。现在我对源码做了些注释,以便我们更深入的了解该算法。一直觉得论文和代码是有比较大的差别的,个人觉得脱离代码看论文,最多能看懂70%,剩下20%或者更多就需要_有了算法模型源码怎么用函数表示

ORA-39002/ORA-29070/ORA-29283/ORA-06512/ORA-29283错误-程序员宅基地

文章浏览阅读6.1k次。C:\Documents and Settings\Administrator>expdp bizdata/bizdata@bzdata schemas=bizdata directory=dd dumpfile=test.dmpExport: Release 10.2.0.1.0 - Production on 星期四, 30 7月, 2009 16:37:12Copyrig_ora-29070

随便推点

Chinaren校友录-程序员宅基地

文章浏览阅读5k次。Chinaren校友录链接:http://alumni.chinaren.com/class/class_index.jsp?classuuid=2917034545012452392 ..._chinaren校友录官网

c语言遍历文件夹中的文件_c语言 遍历文件-程序员宅基地

文章浏览阅读442次。文件目录如下,文件夹里还有一些txt文件未展示出来。使用递归实现,深度优先遍历文件夹中的文件。代码如下,用了一点C++的语法。_c语言 遍历文件

设置esxi 虚拟机随宿主机启动而自动启动_配置虚拟机跟随esxi主机自动启动-程序员宅基地

文章浏览阅读5.7k次。目的:让esxi的客户虚拟机随宿主机启动而启动1、选择host主机——&gt;右侧选择“配置”页签——&gt;选择“虚拟机启动/关机”2、点击右侧“属性”——&gt;勾选“允许虚拟机与系统一起启动和停止”3、选择一个虚拟机,然后“上移”到"自动启动"队列中..._配置虚拟机跟随esxi主机自动启动

用于医疗设备的微型线圈绕组 :“超细心微型线圈上面的应用”-程序员宅基地

文章浏览阅读376次。医疗设备的机械设计人员面临的主要挑战之一是对小型化的需求。小型化有多种用途;到达身体原本无法进入的区域,最大限度地减少对正常身体功能的干扰,最大限度地减少能量消耗,并延长植入组件的使用寿命。这些尺寸限制给制造和这些组件之间的连接及其支持系统带来了多重挑战。这些设备的许多设计都依赖于微型线圈,而微型线圈又需要先进的绕组和连接技术。

S32DS Components组件配置-程序员宅基地

文章浏览阅读3.5k次,点赞3次,收藏21次。S32DS Components组件配置_s32ds components

Golang 调用http 文件上传接口 进行上传文件_golang http send file-程序员宅基地

文章浏览阅读6.9k次,点赞2次,收藏5次。远程服务器有一个文件上传接口,文件用于保存到服务器本地,用go如何调用此接口将文件上传至服务器?首先,文件上传请求方 与 接收方 要协调工作(解析等工作)接收方:func UploadFileToLocal(c echo.Context) error { r := c.Request() //无论用的什么路由,原理是要从request获取数据 t := echotools...._golang http send file

推荐文章

热门文章

相关标签