JMS ActiveMQ交流学习 演示文稿

合集下载

JMS开源框架ActiveMQ入门

JMS开源框架ActiveMQ入门

JMS开源框架ActiveMQ入门介绍基本的JMS概念与开源的JMS框架ActiveMQ应用,内容涵盖一下几点:1.基本的JMS概念2.JMS的消息模式3.介绍ActiveMQ4.一个基于ActiveMQ的JMS例子程序一:JMS基本概念1. JMS的目标为企业级的应用提供一种智能的消息系统,JMS定义了一整套的企业级的消息概念与工具,尽可能最小化的Java语言概念去构建最大化企业消息应用。

统一已经存在的企业级消息系统功能。

2. 提供者JMS提供者是指那些完全完成JMS功能与管理功能的JMS消息厂商,理论上JMS 提供者完成。

JMS消息产品必须是100%的纯Java语言实现,可以运行在跨平台的架构与操作系统上,当前一些JMS厂商包括IBM,Oracle, JBoss社区 (JBoss Community), Apache 社区(ApacheCommunity)。

3. JMS应用程序, 一个完整的JMS应用应该实现以下功能:∙JMS 客户端– Java语言开发的接受与发送消息的程序∙非JMS客户端–基于消息系统的本地API实现而不是JMS∙消息–应用程序用来相互交流信息的载体∙被管理对象–预先配置的JMS对象,JMS管理员创建,被客户端运用。

如链接工厂,主题等∙JMS提供者–完成JMS功能与管理功能的消息系统∙七七八八网二:JMS的消息模式1.点对点的消息模式(Point to Point Messaging)下面的JMS对象在点对点消息模式中是必须的:a.队列(Queue) –一个提供者命名的队列对象,客户端将会使用这个命名的队列对象b.队列链接工厂(QueueConnectionFactory) –客户端使用队列链接工厂创建链接队列ConnectionQueue来取得与JMS点对点消息提供者的链接。

c. 链接队列(ConnectionQueue) –一个活动的链接队列存在在客户端与点对点消息提供者之间,客户用它创建一个或者多个JMS队列会话(QueueSession)d. 队列会话(QueueSession) –用来创建队列消息的发送者与接受者(QueueSenderandQueueReceiver)e.消息发送者(QueueSender 或者MessageProducer)–发送消息到已经声明的队列f.消息接受者(QueueReceiver或者MessageConsumer) –接受已经被发送到指定队列的消息2.发布订阅模式(publish – subscribe Mode)a.主题Topic(Destination) –一个提供者命名的主题对象,客户端将会使用这个命名的主题对象b.主题链接工厂(TopciConnectionFactory) –客户端使用主题链接工厂创建链接主题ConnectionTopic来取得与JMS消息Pub/Sub提供者的链接。

jms与ActiveMQ实践与应用

jms与ActiveMQ实践与应用

jms与ActiveMQ实践与应用jms与ActiveMQ实践与应用2013-09-23 15:19:32| 分类: ActiveMQ|字号订阅前言这是我自己从不知道JMS为何物到学习如何使用第三方工具实现跨服务器的知识总结,在整个过程中可能考虑不全。

另外,如果想尽快使用JMS,建议直接看实例那一节就可以了。

有问题多交流。

词语解释(有些词可能用的不是很正确,在这里我把自己能意识到的词拿出来解释一下):1、跨服务器:专业术语好像叫“跨实例”。

意思是,可以在多个服务器(可以是不同的服务器,如resin与tomcat)之间相互通信。

与之对应的是单服务器版。

2、消息生产者:就是专门制造消息的类。

3、消息消费者:也叫消息接收者,它主要是实现了消息监听的一个接口,当然,也可以难过Spring提供的一个转换器接口指定任意一个类中的任意方法。

序我们都知道,任何一个系统从整体上来看,其实质就是由无数个小的服务或事件(我们可以称之为单元)有机地组合起来的。

对于系统中任何一个比较复杂的功能,都是通过调用各个独立的单元以实现统一的协调运作而实现的。

现在我们的问题是,如果有两个完全独立的服务(比如说两个不同系统间的服务)需要相互交换数据,我们该如何实现?好吧,我承认,我很傻很天真,我想到的第一个方法就是在需要的系统中将代码再写一遍,但我也知道,这绝对不现实!好吧,那我就应该好好学习学习达人们是如何去解决这样的问题。

第一种方法,估计也是用的最多的,就是rpc模式。

这种方法就是在自己的代码中远程调用其它程序中的代码以达到交换数据的目的。

但是这种方法很显然地存在了一个问题:就是一定要等到获取了数据之后才能继续下面的操作。

当然,如果一些逻辑是需要这些数据才能操作,那这就是我们需要的。

第二种方法就是Hessian,我个人觉得Hessian的实现在本质上与rpc模式的一样,只是它采用了配置,简化了代码。

上面这两个方法,基本上能解决所有的远程调用的问题了。

activeMQ,JMS学习资料

activeMQ,JMS学习资料

1JMSJMS源于企业应用对于消息中间件的需求,使应用程序可以通过消息进行异步处理而互不影响。

Sun公司和它的合作伙伴设计的JMS API定义了一组公共的应用程序接口和相应语法,使得Java程序能够和其他消息组件进行通信。

1.1JMS的基本构件1.1.1连接工厂连接工厂是客户用来创建连接的对象,例如ActiveMQ提供的ActiveMQConnectionFactory。

1.1.2连接JMS Connection封装了客户与JMS提供者之间的一个虚拟的连接。

1.1.3会话JMS Session是生产和消费消息的一个单线程上下文。

会话用于创建消息生产者(producer)、消息消费者(consumer)和消息(message)等。

会话提供了一个事务性的上下文,在这个上下文中,一组发送和接收被组合到了一个原子操作中。

1.1.4目的地目的地是客户用来指定它生产的消息的目标和它消费的消息的来源的对象。

JMS1.0.2规范中定义了两种消息传递域:点对点(PTP)消息传递域和发布/订阅消息传递域。

点对点消息传递域的特点如下:每个消息只能有一个消费者。

消息的生产者和消费者之间没有时间上的相关性。

无论消费者在生产者发送消息的时候是否处于运行状态,它都可以提取消息。

发布/订阅消息传递域的特点如下:每个消息可以有多个消费者。

生产者和消费者之间有时间上的相关性。

订阅一个主题的消费者只能消费自它订阅之后发布的消息。

JMS规范允许客户创建持久订阅,这在一定程度上放松了时间上的相关性要求。

持久订阅允许消费者消费它在未处于激活状态时发送的消息。

在点对点消息传递域中,目的地被成为队列(queue);在发布/订阅消息传递域中,目的地被成为主题(topic)。

1.1.5消息生产者消息生产者是由会话创建的一个对象,用于把消息发送到一个目的地。

1.1.6消息消费者消息消费者是由会话创建的一个对象,它用于接收发送到目的地的消息。

消息的消费可以采用以下两种方法之一:同步消费。

activeMQ学习教程

activeMQ学习教程

ActiveMQ学习教程背景:ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。

选择ActiveMQ作为JMS的入门学习中间件,是因为其拥有以下优点1.多种语言和协议编写客户端。

语言: Java, C, C++, C#, Ruby, Perl, Python, PHP。

应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP2.完全支持JMS1.1和J2EE 1.4规范(持久化,XA消息,事务)3.对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性4.完全支持JMS1.1和J2EE 1.4规范(持久化,XA消息,事务)5.通过了常见J2EE服务器(如Geronimo,JBoss 4, GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上6.支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA7.从设计上保证了高性能的集群,客户端-服务器,点对点8.支持Ajax9.支持与Axis的整合10.可以很容易得调用内嵌JMS provider,进行测试学会了ActiveMQ之后,其它供应商的MQ也可以在短时间内快速上手。

安装:ActiveMQ(本文简称MQ)要求JDK1.5以上,推荐1.6以上版本。

还没安装JDK的朋友,请先安装,在此不赘诉了。

安装完JDK后,从/download.html下载MQ的最新版本,本教程使用版本为5.5。

解压后,可以看到MQ目录下有以下文件和目录activemq-all-5.5.0.jar:所有MQ JAR包的集合,用于用户系统调用bin:其中包含MQ的启动脚本conf:包含MQ的所有配置文件data:日志文件及持久性消息数据example:MQ的示例lib:MQ运行所需的所有Libwebapps:MQ的Web控制台及一些相关的DEMO启动MQ:双击bin目录下的activemq.bat文件即可启动MQ第一个示例:新建一个JAVA工程,引用activemq-all-5.5.0.jar,SLFAPI其及对应版本LOG4J的JAR 包(懒的上网找的到附件里下载)Publisher.javaJava代码1import java.util.Hashtable;2import java.util.Map;34import javax.jms.Connection;5import javax.jms.ConnectionFactory;6import javax.jms.Destination;7import javax.jms.JMSException;8import javax.jms.MapMessage;9import javax.jms.Message;10import javax.jms.MessageProducer;11import javax.jms.Session;1213import org.apache.activemq.ActiveMQConnectionFactory;14import mand.ActiveMQMapMessage;1516public class Publisher {1718protected int MAX_DELTA_PERCENT = 1;19protected Map<String, Double> LAST_PRICES = new Hashtable<String, Double>();20protected static int count = 10;21protected static int total;2223protected static String brokerURL = "tcp://localhost:61616";24protected static transient ConnectionFactory factory;25protected transient Connection connection;26protected transient Session session;27protected transient MessageProducer producer;2829public Publisher() throws JMSException {30factory = new ActiveMQConnectionFactory(brokerURL);31connection = factory.createConnection();32try {33connection.start();34} catch (JMSException jmse) {35connection.close();36throw jmse;37}38session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);39producer = session.createProducer(null);40}4142public void close() throws JMSException {43if (connection != null) {44connection.close();45}46}4748public static void main(String[] args) throws JMSException {49Publisher publisher = new Publisher();50while (total < 1000) {51for (int i = 0; i < count; i++) {52publisher.sendMessage(args);53}54total += count;55System.out.println("Published '" + count + "' of '" + total + "' price56try {57Thread.sleep(1000);58} catch (InterruptedException x) {59}60}61publisher.close();62}6364protected void sendMessage(String[] stocks) throws JMSException { 65int idx = 0;66while (true) {67idx = (int)Math.round(stocks.length * Math.random());68if (idx < stocks.length) {69break;70}71}72String stock = stocks[idx];73Destination destination = session.createTopic("STOCKS." + stock); 74Message message = createStockMessage(stock, session);75System.out.println("Sending: " +((ActiveMQMapMessage)message).getContentMap() + " on destination: " +76producer.send(destination, message);77}7879protected Message createStockMessage(String stock, Session session) throws JMSException {80Double value = LAST_PRICES.get(stock);81if (value == null) {82value = new Double(Math.random() * 100);83}8485// lets mutate the value by some percentage86double oldPrice = value.doubleValue();87value = new Double(mutatePrice(oldPrice));88LAST_PRICES.put(stock, value);89double price = value.doubleValue();9091double offer = price * 1.001;9293boolean up = (price > oldPrice);9495MapMessage message = session.createMapMessage();96message.setString("stock", stock);97message.setDouble("price", price);98message.setDouble("offer", offer);99message.setBoolean("up", up);100return message;101}102103protected double mutatePrice(double price) {104double percentChange = (2 * Math.random() * MAX_DELTA_PERCENT) - MAX_DELTA_PERCENT;105106return price * (100 + percentChange) / 100;107}108109}Consumer.javaJava代码110import javax.jms.Connection;111import javax.jms.ConnectionFactory;112import javax.jms.Destination;113import javax.jms.JMSException;114import javax.jms.MessageConsumer;115import javax.jms.Session;116117import org.apache.activemq.ActiveMQConnectionFactory;118119public class Consumer {120121private static String brokerURL = "tcp://localhost:61616"; 122private static transient ConnectionFactory factory;123private transient Connection connection;124private transient Session session;125126public Consumer() throws JMSException {127factory = new ActiveMQConnectionFactory(brokerURL); 128connection = factory.createConnection();129connection.start();130session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);131}132133public void close() throws JMSException {134if (connection != null) {135connection.close();136}137}138139public static void main(String[] args) throws JMSException {140Consumer consumer = new Consumer();141for (String stock : args) {142Destination destination =consumer.getSession().createTopic("STOCKS." + stock);143MessageConsumer messageConsumer =consumer.getSession().createConsumer(destination);144messageConsumer.setMessageListener(new Listener());145}146}147148public Session getSession() {149return session;150}151152}Listener.javaJava代码153import java.text.DecimalFormat;154155import javax.jms.MapMessage;156import javax.jms.Message;157import javax.jms.MessageListener;158159public class Listener implements MessageListener {160161public void onMessage(Message message) {162try {163MapMessage map = (MapMessage)message;164String stock = map.getString("stock");165double price = map.getDouble("price");166double offer = map.getDouble("offer");167boolean up = map.getBoolean("up");168DecimalFormat df = new DecimalFormat( "#,###,###,##0.00" ); 169System.out.println(stock + "\t" + df.format(price) + "\t" +df.format(offer) + "\t" + (up?"up":"down"));170} catch (Exception e) {171 e.printStackTrace();172}173}174}先运行Consumer.java, 输入参数ORCL,然后运行Publisher.java,输入参数ORCL,就可以看到Publisher在发送消息,Consumer在接收消息了。

JMS与MQ详解

JMS与MQ详解

JMS与MQ详解《一》1.ActiveMQ概述企业消息软件从80年代起就存在,它不只是一种应用间消息传递风格,也是一种集成风格。

因此,消息传递可以满足应用间的通知和互相操作。

但是开源的解决方案是到最近10年才出现的。

Apache ActiveMQ就是其中一种。

它使应用间能以异步,松耦合方式交流。

ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。

ActiveMQ是Apache软件基金下的一个开源软件,它遵循JMS 规范(Java Message Service),是消息驱动中间件软件(MOM)。

它为企业消息传递提供高可用,出色性能,可扩展,稳定和安全保障。

ActiveMQ使用Apache许可协议。

因此,任何人都可以使用和修改它而不必反馈任何改变。

这对于商业上将ActiveMQ用在重要用途的人尤为关键。

MOM的工作是在分布式的各应用之间调度事件和消息,使之到达指定的接收者。

所以高可用,高性能,高可扩展性尤为关键。

2.ActiveMQ特性⒈支持多种语言客户端,如:Java,C,C ,C#,Ruby,Perl,Python,PHP。

应用协议有OpenWire,Stomp REST,WS Notification,XMPP,AMQP。

⒉ 完全支持JMS1.1和J2EE1.4规范,它们包括同步和异步消息传递,一次和只有一次的消息传递,对于预订者的持久消息等等。

依附于JMS规范意味着,不论JMS消息提供者是谁,同样的基本特性(持久化,XA消息,事务)都是有效的。

⒊ 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring 的系统里面去。

⒋ 通过了常见J2EE服务器(如Geronimo,JBoss 4,GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE1.4 商业服务器上。

ActiveMQ学习笔记(6)-JMS消息类型

ActiveMQ学习笔记(6)-JMS消息类型
}
public Message createMessage(Session session) throws JMSException { MapMessage message = session.createMapMessage(); message.setString("name", "小西山"); return message; } }); }
/** * 向默认队列发送 Object 消息 */ public void sendObjectMessage() { jmsTemplate.send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException { Staff staff = new Staff(1, "搬砖工"); // Staff 必须实现序列化 ObjectMessage message = session.createObjectMessage(staff); return message; } }); }
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(msg); } }); }
/** * 向默认队列发送 map 消息 */ public void sendMapMessage() { jmsTemplate.send(new MessageCreator() {
TextMessage tm = (TextMessage) message; System.out.println("ConsumerService 从 队 列 " + destination.toString() + " 收 到 了 消 息 : \t" + tm.getText()); }

一、ActiveMQ学习笔记(基础概念)

一、ActiveMQ学习笔记(基础概念)

⼀、ActiveMQ学习笔记(基础概念)刚准备把使⽤ActiveMQ过程中遇到的问题,以及解决⽅法整理出来的时候,去看了下官⽹,发现ActiveMQ Artemis已经发布好久了。

1、JMS概念JMS即Java消息服务(Java Message Service)应⽤程序接⼝,是⼀个Java平台中关于⾯向消息中间件(MOM)的API,⽤于在两个应⽤程序之间,或分布式系统中发送消息,进⾏异步通信。

JMS是⼀种与⼚商⽆关的 API,绝⼤多数MOM提供商都对JMS提供⽀持,⽤来访问收发系统消息,它类似于JDBC(Java Database Connectivity)。

2、JMS元素提供者(Provider):实现JMS的消息服务中间件服务器。

常⽤的如:Apache ActiveMQ、IBM WebSphere MQ。

客户端:发送或接受消息的应⽤。

⽣产者(Producer):创建并发送消息的JMS客户。

消费者(Consumer):接收并处理消息的JMS客户。

消息(Message):应⽤程序之间传递的数据。

队列(Queue):⼀个容纳那些被发送的等待阅读的消息的区域。

与队列名字所暗⽰的意思不同,消息的接受顺序并不⼀定要与消息的发送顺序相同。

⼀旦⼀个消息被阅读,该消息将被从队列中移⾛。

主题(Topic):⼀种⽀持发送消息给多个订阅者的机制。

3、JMS对象连接⼯⼚(ConnectionFactory):创建Connection对象的⼯⼚。

客户端使⽤JNDI查找连接⼯⼚,然后利⽤连接⼯⼚创建⼀个JMS连接。

连接(Connection):客户端和服务器端之间的⼀个活动的连接,是由客户端通过调⽤连接⼯⼚的⽅法建⽴的。

会话(Session):表⽰客户与服务器之间的会话状态。

会话建⽴在连接上,表⽰客户与服务器之间的⼀个会话线程。

⽬的(Destination):消息⽣产者的消息发送⽬标或者说消息消费者的消息来源。

⽣产者(Message Producer):消息⽣产者由Session创建,并⽤于将消息发送到Destination。

ActiveMQ学习笔记(4)-通过ActiveMQ收发消息.

ActiveMQ学习笔记(4)-通过ActiveMQ收发消息.

1.队列和主题1.1概念在MQ中,消息模型有两种,一种是队列(Queue,一种是主题(Topic。

队列是Point-To-Point的,队列中的消息,仅能被消费一次。

主题是Pub/Sub模型,主题中的消息,可以由多个订阅者消费;订阅者只能消费它订阅以后的消息。

这是遵循的JMS规范。

1.2收发消息对象创建过程如上图所示,JMS规范中,收发消息的对象创建过程如下,下面的示例代码中也将注释这些过程:1. 初始化ConnetionFactory2. ConnetionFactory创建Connection3. Connection创建Session4. Session创建Destination(包括Queue 和Topic两种5.发:Session创建消息生产者MessageProducer(收:Session创建消息消费者MessageConsumer6.Seesion创建Message,(发:MessageProducer发送到Destination,(收: MessageConsumer从Destination接受消息。

1.3接口间的关系JMS规范定义了通用接口(JMS Common Interfaces、队列接口(PTP-specificInterfaces和主题接口(Pub/Sub-specific Interfaces,队列接口和主题接口分别继承于通用接口,具体关系如下表所示。

ActiveMQ对这些规范接口都有相应的实现。

在实际的编程过程中,声明通用接口基本就够用了。

如何区分Queue和Topic也很简单,参看下面的代码。

?1 2 3 4 5 //Queue,队列Destination destination = session.createQueue(subject;//Topic,主题Destination destination = session.createTopic(subject;2.通过队列发送和接受消息运行代码的时候,可以先run起来接受消息的程序,再run发送消息的程序,来观察消息发送的过程。

消息中间件系列一:入门、JMS规范、ActiveMQ使用

消息中间件系列一:入门、JMS规范、ActiveMQ使用

消息中间件系列⼀:⼊门、JMS规范、ActiveMQ使⽤⼀、⼊门1. 消息中间件的定义没有标准定义,⼀般认为,采⽤消息传送机制/消息队列的中间件技术,进⾏数据交流,⽤在分布式系统的集成2. 为什么要⽤消息中间件解决分布式系统之间消息的传递。

电商场景:⽤户下单减库存,调⽤物流系统。

随着业务量的增⼤,需要对系统进⾏拆分(服务化和业务拆分),拆分后的系统之间的交互⼀般⽤RPC(远程过程调⽤)。

如果系统扩充到有⼏⼗个接⼝,就需要⽤消息中间件来解决问题。

3. 消息中间件和RPC有什么区别3.1 功能特点:在架构上,RPC和Message的差异点:Message有⼀个中间结点Message Queue,可以把消息存储。

3.2 消息的特点Message Queue把请求的压⼒保存⼀下,逐渐释放出来,让处理者按照⾃⼰的节奏来处理。

Message Queue引⼊⼀下新的结点,让系统的可靠性会受Message Queue结点的影响。

Message Queue是异步单向的消息。

发送消息设计成是不需要等待消息处理的完成。

所以对于有同步返回需求,⽤Message Queue则变得⿇烦了。

3.3 PRC的特点同步调⽤,对于要等待返回结果/处理结果的场景,RPC是可以⾮常⾃然直觉的使⽤⽅式。

# RPC也可以是异步调⽤。

由于等待结果,Consumer(Client)会有线程消耗。

如果以异步RPC的⽅式使⽤,Consumer(Client)线程消耗可以去掉。

但不能做到像消息⼀样暂存消息/请求,压⼒会直接传导到服务Provider。

3.4 适⽤场合说明希望同步得到结果的场合,RPC合适。

希望使⽤简单,则RPC;RPC操作基于接⼝,使⽤简单,使⽤⽅式模拟本地调⽤。

异步的⽅式编程⽐较复杂。

不希望发送端(RPC Consumer、Message Sender)受限于处理端(RPC Provider、Message Receiver)的速度时,使⽤Message Queue。

ActiveMQ消息中间件实战教程PPT模板

ActiveMQ消息中间件实战教程PPT模板

第2章activemq框架整合
2-3点对点消息消费者 点对点消息消费者
2-2点对点消息生产者 点对点消息生产者
2-1activemq回顾 activemq回顾
2-4发布-订阅模式整合 发布-订阅模式整合
2-5springboot的生产 者整合springboot的生 产者整合
2-6springboot整合 activemq消费者springboot 整合activemq消费者
activemq消息中间件实



演讲人
2 0 2 x - 11 - 11
目录
01. 第1章activemq基础 02. 第2章activemq框架整合 03. 第3章activemq实战
01
第1章activemq基础
第1章activemq基础
1-1消息中间件概念消息 中间件概念
1-2什么是jms什么是 jms
消息
1-7发布-订阅模式发布 -订阅模式
1-10objectmessage类 型消息objectmessage类 型消息
1-11bytesmessage类型 的消息bytesmessage类 型的消息
1-12streammessage类型的 消息streammessage类型的消 息
02
第2章activemq框架整合
感谢聆听
1-3jms消息传递类型 jms消息传递类型
1-4activemq使用场景 activemq使用场景
1-5activemq下载与安装 activemq下载与安装
1-6点对点模式点对点模 式
第1章activemq基础
1-9mapmessage类型 的消息mapmessage类

《JMS框架学习》word版

《JMS框架学习》word版

Jms使用步骤:1.首先需要得到ConnectionFactory和Connection:ConnectionFactory factory = new ActiveMQConnectionFactory(“vm://localhost”); Connection connection = factory.createConnection();2.由Connection创建一个session:Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);3.由Connection创建一个Destination,Destination是指消息发送的目的地,也就是前面说的Queue和Topic,创建好了一个消息后,只需要把这个消息发送到目的地,消息的发送者就可以继续做自己的事情,而不用等待消息被处理完成。

至于这个消息什么时候,会被哪个消费者消费,完全取决于消息的接收者。

Destination destination = session.createQueue(“testObject”);//点到点(P2P)模型//Destination destination = session.createTopic(“testObject”);//发布/订阅(Pub/Sub)模型4.创建需要发送的Message:Message message = session.createTextMessage(“Hello,JMS”);5.需要由Session和Destination创建一个消息生产者、发送消息:MessageProducer producer = session.createProducer(Queue);Producer.send(message);6.创建一个消息消费者来接收这个消息,并使用消息:MessageConsumer comsumer = session.createConsumer(queue);Message recyMessage = comsumer.receive();System.out.println(((TextMessage)recyMessage).getText());消息接收可以使用设置消息监听接口comsumer.setMessageListener(new MessageListener());来实现;Developing JMS applicationsYou can create a JMS application using either the point-to-point or the publish/subscribe messaging model. Both models support applications that are capable of:•Creating a JMS InitialContext object•Looking up a ConnectionFactory object•Creating permanent destinations•Creating connections•Creating sessions•Creating message producers•Creating message consumers•Implementing and installing message listeners•Creating messages•Sending messages•Publishing messages•Receiving messages•Browsing messages•Enabling JMS tracing•Closing connections, sessions, consumers, and producersYou can download a copy of the JMS 1.0.2 API documentation from the Java Web site.Creating a JMS InitialContext objectA JMS client application must instantiate a JMS InitialContext object and set these properties:•InitialContext factory – set java.naming.factory.initial to “com.sybase.jms.InitialContextFactory”.•URL – set java.naming.provider.url to the location where the client can connect to EAServer.•User name – valid for a connection with EAServer.•Password – valid for the user name.When instantiating a JMS InitialContext from a base client, specify the user name with the SECURITY_PRINCIPAL property, and specify the password with the SECURITY_CREDENTIALS property. The default for both properties is an empty string.This example runs the JMS client application JMSClientClass and sets the InitialContext factory, URL, user name, and password properties at runtime:java -Djava.naming.factory.initial=com.sybase.jms.InitialContextFactory-Djava.naming.provider.url=iiop://stack:9000-DSECURITY_PRINCIPAL=”jagadmin” -DSECURITY_CREDENTIALS=”sybase”JMSClientClassLooking up a ConnectionFactory objectA connection factory allows you to create JMS connections and specify a set of configuration properties that define the connections. EAServer provides two types of connection factories, one to create queue connections and one to create topic connections. Queue connections allow you to send and receive messages using the PTP messaging model. Topic connections allow you to publish and receive messages using the Pub/Sub messaging model. EAServer provides two preconfigured connection factories that you can use javax.jms.QueueConnectionFactory and javax.jms.TopicConnectionFactory. To create connection factories, use EAServer Manager—see Chapter 8, “Setting up the Message Service,” in the EAServer System Administration Guide for details. Once you have created a connection factory, client applications must look up a ConnectionFactory object using JNDI, as in this example:// Look up a queue connection factoryQueueConnectionFactory queueCF =(QueueConnectionFactory) ctx.lookup(“MyTestQueueCF”);// Look up a topic connection factoryTopicConnectionFactory topicCF =(TopicConnectionFactory) ctx.lookup(“MyTestTopicCF”);If the connection factory cannot be found, EAServer throws ajavax.naming.NamingException.Creating permanent destinationsPermanent destinations are message queues or topics whose configuration properties are stored in a database. You can create permanent destinations two ways. The recommended way is to use EAServer Manager to create and configure message queues and topics. See Chapter 8, “Setting up the Message Service,” in the EAServer System Administration Guide for information on how to do this. You can also create permanent destinations using the JMS APIs createQueue and createTopic. Sybase suggests that you use this option only when client applications need the ability to dynamically change the provider-specific destination name; applications using this technique are not portable.When you create message queues and topics using EAServer Manager, client applications can use their InitialContext object to look up the destinations; for example:// Look up a message queuejavax.jms.Queue queue =(javax.jms.Queue) ctx.lookup(“MyQueue”);// Look up a topicjavax.jms.Topic topic =(javax.jms.Topic) ctx.lookup(“MyTopic”);To create permanent destinations using the JMS APIs, you must first create a session; see “Creating sessions” for details. Once you have access to a session object, use this syntax to create a destination:javax.jms.Queue queue =queueSession.createQueue(“MyQueue”);javax.jms.Topic topic =topicSession.createTopic(“MyTopic”);Temporary destinationsYou can also create temporary destination objects that are active only during the lifetime of a session. When the session is closed, temporary destination objects and their associated messages are discarded. These two lines illustrate how to create temporary message queue and topic destinations:// Create a temporary queuejavax.jms.Queue queue =queueSession.createTemporaryQueue();// Create a temporary topicjavax.jms.Topic topic = topicSession.createTemporaryTopic();By default, temporary message queues time out after 60 seconds of inactivity. To increase this value, you can do one of two things:•Set the connection factory’s CONFIG_QUEUE property to the name ofa message queue with a reasonably high timeout value. Subsequently,each temporary message queue you create that uses this connection factory inherits the properties of the queue assigned toCONFIG_QUEUE.•Set the value at the global level so all temporary message queues use the same timeout value. To do this, edit theMessageServiceConfig.props file, located in the EAServer/Repository/Component/CtsComponents directory, and set thesession.timeout property to the appropriate number of seconds. Chapter 8, “Setting up the Message Service,” in the EAServer System Administration Guide describes these settings in detail.Creating connectionsJMS provides two types of connections, one for message queues and one for topics. To create a connection from a JMS client application to EAServer, you must have access to a ConnectionFactory object. See “Looking up a ConnectionFactory object”. Once you have created a connection, you must explicitly start it before EAServer can deliver messages on the connection. To avoid message delivery before a client has finished setting up, you may want to delay starting the connection. This code fragment creates a QueueConnection object and starts the connection:QueueConnection queueConn =queueCF.createQueueConnection();// other setup proceduresqueueConn.start();This sample creates a connection object for a topic and starts the connection:TopicConnection topicConn =topicCF.createTopicConnection();// other setup procedurestopicConn.start();You can also stop delivery of messages using the QueueConnection.stop method, then use start to resume delivery. While a connection is stopped, receive calls do not return with a message, and messages are not delivered to message listeners. Any calls to receive or message listeners that are in progress when stop is called, complete before the stop method returns.With a single connection to EAServer, the message service can send and receive multiple messages. Therefore, a JMS client usually only needs one connection.Setting the client IDA connection for a durable topic subscriber must have a client ID associated with it so that EAServer can uniquely identify a client if it disconnects and later reconnects. You can use EAServer Manager to set the client ID when you create the topic connection factory; see Chapter 8, “Setting up the Message Service,”in the EAServer System Administration Guide. If you do not set the client ID in the connection factory, you must set it immediately after creating the connection and before performing any other action on the connection. After this point, attempting to set the client ID throws an IllegalStateException. This code fragment illustrates how to set a topic connection’s client ID:topicConn.setClientID(“Client ID String”);For more information about topic subscribers, see “Creating message consumers”.ExceptionListenerTo enable EAServer to asynchronously notify clients of serious connection problems, create and register an ExceptionListener. Thejavax.jms.ExceptionListener must implement this method:void onException(JMSException exception);To register a listener, call the Connection::setExceptionListener method, for example:queueConn.setExceptionListener(MyExceptionListener);If an exception occurs and a listener has been registered, EAServer calls the onException method and passes the JMSException, which describes the problem.Creating sessionsOnce a client has established a connection with EAServer, it needs to create one or more sessions. A session serves as a factory for creating message producers, message consumers, and temporary destinations. JMS provides two types of session objects, one for queue connections and one for topic connections. To create a QueueSession object, use a previously created QueueConnection object as follows:QueueSession queueSession = queueConn.createQueueSession(true,Session.AUTO_ ACKNOWLEDGE);To create a TopicSession object, use a previously created TopicConnection object as follows:TopicSession topicSession = topicConn.createTopicSession(true,Session.AUTO_ ACKNOWLEDGE);When you create a session, set the first parameter to true if you want a transacted session. When you publish or send a message in a transacted session, the transaction begins automatically. Once a transacted session starts, all messages published or sent in the session become part of the transaction until the transaction is committed or rolled back. When a transaction is committed, all published or sent messages are delivered. If a transaction is rolled back, any messages produced in the session are destroyed, and any consumed messages are recovered. When a transacted session is committed or rolled back, the current transaction ends and the next transaction begins. See Chapter 2, “Understanding Transactions and Component Lifecycles” for more information about transactions.Set the first parameter to false when you do not want a transacted session. If a client has an active transaction context, it can still determine transactional behavior, even if it does not create a transacted session.The second parameter indicates whether the message producer or the consumer will acknowledge messages. This parameter is valid only for nontransacted sessions. In transacted sessions, acknowledgment is determined by the outcome of the transaction.Session::recoverTo stop message delivery within a session and redeliver all the unacknowledged messages, you can use the Session.recover method. When you call recover for a session, the message service:•Stops message delivery within the session.•Marks all unacknowledged messages “redelivered”, including those that have been delivered.•Restarts sending all unacknowledged messages, beginning with the oldest message.The method can be called only by a non-transacted session; it throws an IllegalStateException if it is called by a transacted session.Creating message producersCreate message producers for sending and publishing messages. JMS defines two message producer objects, a QueueSender, used to send messages, and a TopicPublisher, used to publish messages. To create a QueueSender object, use a previously created QueueSession object and this syntax:javax.jms.QueueSender sender = queueSession.createSender(queue);To create a TopicPublisher object, use a previously created TopicSession object and this syntax:javax.jms.TopicPublisher publisher =topicSession.createPublisher(topic)Creating message consumersMessage consumers can be either QueueReceiver or TopicSubscriber objects. Create a QueueReceiver to retrieve messages that are sent using the PTP messaging model. Use previously created Queue and QueueSession objects, as follows:javax.jms.QueueReceiver receiver =queueSession.createReceiver(queue);A TopicSubscriber object receives published messages and can be either durable or nondurable. A nondurable subscriber can only receive published messages while it is connected to EAServer. If you want guaranteed message delivery, make the subscriber durable. For example, if you create a durable subscription on a topic, EAServer saves all published messages for the topic in a database. If a durable subscriber is temporarily disconnected from EAServer, its messages will be delivered when the subscriber is reconnected. The messages are deleted from the database only after they are delivered to the durable subscriber.This example illustrates how to create both durable and nondurable topic subscribers. In both cases, you need to reference previously created Topic and TopicSession objects:// Create a durable subscriberjavax.jms.TopicSubscriber subscriber =topicSession.createDurableSubscriber(topic, “subscriptionName”)// Create a non-durable subscriberjavax.jms.TopicScuscriber subscriber =topicSession.createSubscriber(topic);To remove a durable topic subscription, call the TopicSession.unsubscribe method, and pass in the subscription name; for example:topicSession.unsubscribe(“subscriptionName”);Filtering messages using selectorsYou can use selectors to specify which messages you want delivered to a message queue. Once you add a selector to a queue, the message servicedelivers only those messages whose message topic matches the selector. You can create message selectors using EAServer Manager—seeChapter 8, “Setting up the Message Service,” in the EAServer System Administration Guide. You can also create message selectors programmatically. This example illustrates how to create a message selector and use it when you are creating a new QueueReceiver:// Create a selector to receive only Text messages// whose value property equals 100.String selector = “value = 100 and Type = TextMessage”;// Create a queue receiver using the selector.QueueReceiver receiver =queueSession.createReceiver(queue, selector);This code sample sends two messages to the message queue we just created. T he properties of the first message match those of the message queue’s selector. The properties of the second message do not.// Create and send a message whose properties match// the message queue selector.TextMessage textMsg =queueSession.createTe xtMessage(“Text Message”);textMsg.setIntProperty(“Value”, 100);textMsg.setStringProperty(“Type”, “TextMessage”);sender.send(textMsg);// Create and send a Bytes message, whose value// property equals 200.BytesMessage bytesMsg =queueSession.createBytesMessage();bytesMsg.setIntProperty(“Value”, 200);bytesMsg.setStringProperty(“Type”, “BytesMessage”);sender.send(bytesMsg);When we retrieve messages from the message queue, the Text message will be returned but the Bytes message will not.Implementing and installing message listenersMessage listeners allow you to receive messages asynchronously. Once you have implemented a listener, install it on a message consumer. When a message is delivered to the message consumer, the listener can send the message to other consumers or notify one or more components.JMS message listeners implement the javax.jms.MessageLintener interface and can be either client-side listener objects or EJB 2.0 message-driven beans (MDB). The MessageListener interface contains only the onMessage method. This example illustrates the skeleton code for a message listener:class QueueMessageListener implements MessageListener{public void onMessage(javax.jms.Message msg){// process message, notify component}}You can use EAServer Manager to install a message listener on a message queue or topic—see “Installing and configuring an MDB”. You can also install a message listener within your application. First create a message consumer, see “Creating message consumers”, then install the listener, using this syntax:receiver.setMessageListener(new QueueMessageListener());Message-driven beansAn MDB is a type of Enterprise JavaBean (EJB) specifically designed as a JMS message consumer. You can install an MDB as a message listener on a message queue or topic.When an MDB is installed as a listener on a message consumer and a JMS message arrives, EAServer instantiates the MDB to process the message. An MDB must implement the MessageDrivenBean interface, which consists of these methods:An MDB instance with container-managed transactions can call these MessageDrivenContext interface methods:Unlike other EJBs, message-driven Beans do not have a home or remote interface, and clients cannot directly access an MDB. EAServer calls the onMessage method of the javax.jms.MessageListener interface to notify an MDB that a message has been delivered to the queue or topic on which it is installed. To prevent client access to the onMessage method, this component property is set automatically when you install and configure an MDB:ponent.roles =onMessage(security-roles=ServiceControl)Installing and configuring an MDB1.Create a new EJB component, as described in Chapter 7, “CreatingEnterprise JavaBeans Components.”You do not need to define remote or local interfaces.2.On the General tab, supply these values:o Description –summarize the bean’s purpose.o Component Type – select EJB - Message Driven Bean from the drop-down list.o EJB Version – choose 2.0.o MDB Class –enter the name of the Java class that implements the MDB; for example com.sybase.jaguar.myPkg.MyBeanImpl.3.On the MDB Type tab, enter:o Destination Type – choose either Queue or Topic.o Name – enter the name of the destination queue or topic.o Listener –enter the package and component name for the MDB listener; for example, MyPkg/MyBeanImpl. To specify a threadpool, append the thread pool name in square brackets, forexample, MyPkg/MyBeanImpl[MyThreadPool].You can create thread pools in EAServer Manager as describedin Chapter 8, “Setting up the Message Service,” in theEAServer System Administration Guide. The thread pool musthave one or more worker threads. A thread pool with multipleworker threads enables the message listener to processmultiple messages at the same time. If you do not specify thename of a thread pool, the message listener uses the <system>default thread pool, which has a single worker thread.o Acknowledge Mode – choose either Auto or Dups-ok. For an explanation of the acknowledgment modes, see “Creatingsessions”.o Message Selector –if the destination type is a queue, entera message selector to filter incoming messages; for example,to receive all published messages with the topic“StockPrice.SY”, enter:o topic = ‘StockPrice.SY’o Subscription/Durability –if the destination type is a topic, select either Durable or Non-durable. For a description ofthese options, see “Creating message consumers”.4.On the Transactions tab:o Select one of Not Supported, Required, or Bean Managed.o Optionally, select Automatic Failover.“Component properties: Transactions” describes the options on this tab.5.On the Run-As Mode tab, define the identity properties used forintercomponent calls. “Component properties: Run-As Mode”describes this tab in detail. If you do not specify a Run As Mode, the default value for an MDB is “System.”6.Optionally specify a retry timeout. If your MDB throws an exceptionwhile processing a message, EAServer can retry delivery for the time period you specify. By default, EAServer does not retry delivery.To configure this setting:a.Enable the Automatic Failover option on the Transactions tab.b.On the Advanced tab, set the propertyponent.retry.timeout to the number ofseconds that EAServer should retry delivery. EAServerretries at intervals that increase by about one second aftereach failure; that is, after one second, again after 3 seconds,again after 6 seconds, and so forth.7.Similar to other EJBs, you can enter information on these tabs, butit is not required. For more information, see:Running the sample JMS client and MDBEAServer includes a sample JMS client and MDB listener. For more information, see “Using message-driven beans and JMS” in Chapter 5, “Using the EAServer Samples,” in the EAServer Cookbook.Related chaptersFor information about Enterprise JavaBeans, see these chapters: •Chapter 6, “Enterprise JavaBeans Overview”•Chapter 7, “Creating Enterprise JavaBeans Components”Creating messagesTo create a message, you must first create an instance of either a queue or topic session. See “Creating sessions”for details. To create a text message, use this syntax:// Create a text message using a QueueSessionjavax.jms.TextMessage queueTextMsg =queueSession.createTextMessage(“Text message”);// Create a text message using a TopicSessionjavax.jms.TextMessage topicTextMsg =topicSession.createTextMessage(“Text message”);EAServer supports six message types that a message producer can send or publish. Table 31-1describes the message types and the javax.jms.Session interface APIs used to create instances of each.To improve interoperability with non-Java clients or components and to improve message receivers’ ability to filter messages, Sybase recommends that you use either plain messages or text messages. Selectors allow you to filter messages based on the text in the message properties. You cannot filter messages based on the text in the message body. Therefore, message text in the message properties, instead of the message body, enables the message receivers to filter messages more efficiently.For more information about the message types, see the JMS API documentation.Sending messagesTo send a message, you must specify the destination message queue. The message service notifies listeners that are registered for the queue and the message remains in the queue until it is received and acknowledged.Figure 31-1: Send message flowFigure 31-1illustrates the message flow that occurs when a client or component sends a message.This example notifies a client of a completed order; it creates a new message, constructs the message text, and sends the message to the client’s queue:public void notifyOrder(QueueSession qSession,Queue queue,int orderNo,String product){String time = new java.util.Date().toString();String text = "Order " + orderNo + " for product " + product + " was completed at " + time;javax.jms.QueueSender sender = qSession.createSender(queue);javax.jms.TextMessage textMsg =qSession.createTextMessage(text);textMsg.setStringProperty(“ProductDescription”, product);textMsg.setIntProperty(“OrderNumber”, order No);sender.send(textMsg);}Publishing messagesWhen you publish a message, a copy is sent to all topic subscribers that have a message selector registered with the specified topic. Figure 31-2illustrates the message flow when a client or component publishes a message.Figure 31-2: Publish message flowThis example publishes a message that notifies clients of changes in a stock value; it creates the message text, creates a TopicPublisher and the message using the TopicSession object, and publishes the message:public void notifyStockValue(TopicSession tSession,Topic topic,String stock,double value){String time = new java.util.Date().toString();String text = time + ": The stock " + stock + " has value " + value;// Create the publisher and message objects.javax.jms.TopicPublisher publisher =tSession.createPublisher(topic);javax.jms.TextMessage textMsg =tSession.createTextMessage(text);// Publish a non-persistent message with a priority of 9 and a // lifetime of 5000 milliseconds (5 seconds)publisher.publish(textMsg, DeliveryMode.NON_PERSISTENT, 9, 5000);}To publish a persistent message using the default priority (4) and timeout (never expires) values, use this syntax:publisher.publish(textMsg);Receiving messagesYou can receive messages either synchronously or asynchronously. To receive messages synchronously (get all the messages at one time), call the receive method for the message consumer. The following code samples illustrate how to receive all the messages from a queue, using three different timeout options:// Get all the messages from the queue. If none exists,// wait until a message arrives.javax.jms.TextMessage queueTextMsg =(javax.jms.TextMessage) receiver.receive();// Get all the messages from the queue. If none exists,// wait 5000 milliseconds (5 seconds) or until a message// arrives, whichever comes first.javax.jms.TextMessage queueTextMsg =(javax.jms.TextMessage) receiver.receive(5000);// Get all the messages from the queue. If none exists,// return NULL.javax.jms.TextMessage queueTextMsg =(javax.jms.TextMessage) receiver.receiveNoWait();To receive messages asynchronously, implement a message listener and install it on the message consumer, either a topic or a queue. See “Implementing and installing message listeners”.For information about creating message queues and topics, see “Creating message consumers”.Browsing messagesYou can look at messages in a queue without removing them using the QueueBrowser interface. You can browse through all the messages in a queue,or through a subset of the messages. To browse through a queue’s messages, create an instance of aQueueBrowser object using a previously created QueueSession object. To create a browser for viewing all the messages in a queue, call createBrowser and pass the message queue:javax.jms.QueueBrowser qbrowser =queueSession.createBrowser(queue);To create a browser for viewing a subset of the messages in a queue, call createBrowser and pass the message queue and a message selector string:javax.jms.QueueBrowser qbrowser =queueSession.createBrowser(queue, selector);For information about message selectors, see “Filtering messages using selectors”.Once you have access to the QueueBrowser object, call getEnumeration, which returns an Enumeration that allows you to view the messages in the order that they would be received:java.util.Enumeration enum = qbrowser.getEnumeration();Enabling JMS tracingTo help debug your JMS client application, you can enable tracing by setting the com.sybase.jms.debug property to true in the InitialContext object. When you enable tracing, diagnostic messages are printed in the console window. By default, tracing is disabled. This code sample illustrates how to set the tracing property:Properties prop = new Properties();prop.put(“com.sybase.jms.debug”, “true”);javax.naming.Context ctx =new javax.naming.InitialContext(prop);Closing connections, sessions, consumers, and producers。

理解面向消息中间件及JMS 以及 ActiveMQ例子

理解面向消息中间件及JMS 以及 ActiveMQ例子

为了帮助你理解ActiveMQ的意义,了解企业消息传送背景和历史是很重要的。

讨论完企业消息传送,你将可以通过一个小例子了解JMS及其使用。

这章的目的是简要回顾企业消息传送及JMS规范。

如果你已经熟悉这些主题,你可以跳过直接到下一章去。

软件开发者经常需要在两个系统之间交流或搬运数据。

这种问题有很多解决办法。

但限于你的条件和需求,选择一种解决方案是一个大决定。

商业需求往往有严格的限制条件,直接影响你的决定的有性能,扩展性,稳定性等。

我们日常使用的很多系统都有这样的要求,比如ATM系统,航班预订系统,信用卡系统,单点销售系统,通信系统等。

如果我们的日常生活没有这些系统会怎样?用一小会的时间想一下这些服务给我们的生活带来了怎样的便利。

这些及其它类似应用能够方便我们的生活在于他们的稳定和安全性。

在这些应用场景背后,是很多应用组合起来的,通常是分布式的,它们之间相互传递事件或消息。

即使是最复杂的金融交易系统也是用这种方式集成的,完全通过消息传送来发送和接收商业信息。

由于各种各样的理由,很多产品都提供消息传送。

必要性是发明之母,这就是消息中间件产生的原因。

当时需要一种软件,能够在各种不同的数据类型,操作系统,协议甚至是不同的编程语言中交流数据。

并且,复杂的消息路由和转移也成为这种解决方案的一部分必备能力。

ActiveMQ就是一个MOM产品,它为上面提到的商业系统提供异步消息传送。

ActiveMQ通过实现JMS规范提供了这样一种可靠性和扩展性。

2.1介绍企业消息传送向上面提及的大多数系统是由许多大型的计算机一起构建的,并且到今天仍然在使用。

那么,这些系统怎么可靠地运作呢?要回答这个问题,我们先简要回顾下这种解决方案的历史及企业消息传送是怎么产生的。

从上世纪60年代开始,许多大型的组织使用大型机来处理一些诸如数据处理,财务处理,静态分析等关键功能。

大型机为商业提供包括高可用性,冗余备份,可靠性,可扩展性,无中断升级等许多关键特性。

ActiveMQ学习笔记(1)-JMS的概念

ActiveMQ学习笔记(1)-JMS的概念

1.面向消息的中间件1.1什么是MOM面向消息的中间件,Message Oriented Middleware,简称MOM,中文简称消息中间件,利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。

一个MOM系统,通常会包括客户端(Clients)、消息(Message)和MOM,客户端是发送或者接受消息的应用程序,消息封装了要传递的内容,MOM可以存储和转发消息。

如下图所示,系统A和系统B之间的消息传递,不是直接通信,而是通过中间件来间接的传递。

1.2MOM的好处∙降低系统间通信复杂度有了MOM,系统间的通信,不用考虑系统是什么语言开发的,也不用考虑复杂的网络编程,各个系统只需要关心自身和MOM之间如何进行消息的接受和发送即可,这些操作通过简单的API就可以完成。

∙提高了消息的灵活性系统A通过MOM向系统B发送消息,消息可以存储在MOM中,并由MOM转发。

即使是系统B不在线,MOM会持有这个消息,直到系统B连接并处理消息。

这就是说,系统A发完消息后,就可以执行其它操作,而不必阻塞等待,尤其是对那些时间无关或者并行处理的操作,非常适用。

∙松散耦合有了MOM的存在,对于系统B而言,只要发送的消息没有变化,就不必考虑系统A的变化。

A系统的代码改变,不会影响到B系统,反之亦然。

2.JMS概念2.1 JMS是什么Java消息服务(Java Message Service,JMS)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS 提供支持。

Java消息服务的规范包括两种消息模式,点对点和发布者/订阅者。

Java消息服务支持同步和异步的消息处理。

一个JMS系统,通常包括了以下部分:∙JMS Client,java语言编写的客户端,用于发送和接受消息。

JMS详解-ActiveMQ

JMS详解-ActiveMQ

JMS是java的消息服务,JMS的客户端之间可以通过JMS服务进行异步的消息传输。

消息模型○ Point-to-Point(P2P)○ Publish/Subscribe(Pub/Sub)即点对点和发布订阅模型P2PP2P模式图涉及到的概念消息队列(Queue)发送者(Sender)接收者(Receiver)每个消息都被发送到一个特定的队列,接收者从队列中获取消息。

队列保留着消息,直到他们被消费或超时。

P2P的特点每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列接收者在成功接收消息之后需向队列应答成功如果你希望发送的每个消息都应该被成功处理的话,那么你需要P2P模式。

Pub/SubPub/Sub模式图涉及到的概念发布者(Publisher)订阅者(Subscriber)客户端将消息发送到主题。

多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。

Pub/Sub的特点每个消息可以有多个消费者发布者和订阅者之间有时间上的依赖性。

针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息,而且为了消费消息,订阅者必须保持运行的状态。

为了缓和这样严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。

这样,即使订阅者没有被激活(运行),它也能接收到发布者的消息。

如果你希望发送的消息可以不被做任何处理、或者被一个消息者处理、或者可以被多个消费者处理的话,那么可以采用Pub/Sub模型消息的消费在JMS中,消息的产生和消息是异步的。

对于消费来说,JMS的消息者可以通过两种方式来消费消息。

○ 同步订阅者或接收者调用receive方法来接收消息,receive方法在能够接收到消息之前(或超时之前)将一直阻塞○ 异步订阅者或接收者可以注册为一个消息监听器。

ActiveMQ 的JMS教程

ActiveMQ 的JMS教程

ActiveMQ的安装和使用总结一、ActiveMQ 安装与配置一.window下安装activeMQ1、下载/activemq-510-release.html,下载5.1.0 Windows Distribution版本2、安装直接解压至任意目录(如:d:\ apache-activemq-5.1.0)3、启动ActiveMQ服务器方法1:直接运行bin\activemq.bat方法2(在JVM中嵌套启动):cd exampleant embedBroker4、ActiveMQ消息管理后台系统:http://localhost:8161/admin二.linux下安装ActiveMQ1.下载/download.html2.解压将下载下来的apache-activemq-5.2.0-bin.tar.gz放置于/usr/localtar zxvf apache-activemq-5.2.0-bin.tar.gz3. 进入apache-activemq-5.2.0/bin目录下:运行./activemq start 命令即可启动activemq ,使用ps –ef|grep activemq 查看activemq的进程。

修改持久化配置JMS消息传递是一种异步过程,如果没有接受者JMS Provider应该选择将消息持久化,策略主要有文件持久化和基于数据库的持久化两种,下文是关于将未消费的消息持久化到Oarcle数据库的。

1. 我们要做的是将Oracle数据库的驱动包(oracle-jdbc-driver-14.jar)放置到ActiveMQ的安装目录下的lib(/activeMQ/apache-activemq-5.5.0/lib)里。

2.其次,我们需要改写activemq.xml文件,它在ActiveMQ的conf目录中(也可以修改conf/activemq-jdbc.xml配置文件中的数据源配置实现,通过bin/activemq start xbean:conf/activemqjdbc.xml 命名启动,试过但没成功希望大家有兴趣可以研究下)。

JMS学习三(ActiveMQ消息的可靠性)

JMS学习三(ActiveMQ消息的可靠性)

下面我们来学习一下消息接受确认和发送持久化消息、消息的过期、消息的选择器和消息的优先级。

一、消息接收确认1、jms消息只有在被确认之后才认为成功消费了这条消息。

消息的成功消费通常包括三个步骤:(1)、client 接收消息(2)、client处理消息(3)、消息被确认(也就是client给一个确认消息)不管是事务性会话还是非事务性会话,第一步和第二步都一样但第三步有所不同2、在事务性会话中当一个事务被提交的时候,确认自动发生,和应答模式没关系,这个值可以随便写。

(这里多提一句异步消息接收中不能使用事务性会话)3、在非事务性会话中消息何时被确认取决于创建的session中设置的消息应答模式(acknowledge model)该参数有三个值:(1)、Session.AUTO_ACKNOWLEDGE:当client端成功的从receive方法或从onMessage(Message message) 方法返回的时候,会话自动确认client收到消息。

(2)、Session.CLIENT_ACKNOWLEDGE: 客户单通过调用acknowledge方法来确认客户端收到消息。

但需要注意在这种应答模式下,确认是在会话层上进行的,确认一个被消费的消息将自动确认所有已消费的其他消息。

比如一个消费者已经消费了10条消息,然后确认了第5条消息被消费,则这10条都被确认消费了。

acknowledge()通知方法是在Message对象上同步接收,调用acknowledge()方法进行确认:1、生产者,设置签收模式为Session.CLIENT_ACKNOWLEDGE// 通过Connection对象创建Session会话(上下文环境对象),// 参数一,表示是否开启事务// 参数二,表示的是签收模式,一般使用的有自动签收和客户端自己确认签收Session session = connection.createSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE);2、消费者,设置签收模式为Session.CLIENT_ACKNOWLEDGE// 通过Connection对象创建Session会话(上下文环境对象),// 参数一,表示是否开启事务// 参数二,表示的是签收模式,一般使用的有自动签收和客户端自己确认签收Session session = connection.createSession(Boolean.FALSE,Session.CLIENT_ACKNOWLEDGE);3、消费者,在消费消息的时候,返回一个确认// 使用Session来创建消息对象的生产者或者消费者MessageConsumer createConsumer = session.createConsumer(destination);while (true) { TextMessage textMessage = (TextMessage) createConsumer.receive();//同步方式接收 if (textMessage == null) break; // 客户端的签收模式, textMessage.acknowledge(); System.out.println("收到的内容为" + textMessage.getText());}异步接受,调用acknowledge()方法进行确认:consumer.setMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message) {TextMessage textMessage = (TextMessage) message;try {String value = textMessage.getText();System.out.println("value: " + value);message.acknowledge(); //消息消费确认通知} catch (JMSException e) {e.printStackTrace();}}});(3)、Session.DUPS_ACKNOWLEDGE:不是必须签收,消息可能会重复发送。

JMS学习七(ActiveMQ之Topic的持久订阅)

JMS学习七(ActiveMQ之Topic的持久订阅)

非持久化订阅持续到它们订阅对象的生命周期。

这意味着,客户端只能在订阅者活动时看到相关主题发布的消息。

如果订阅者不活动,它会错过相关主题的消息。

如果花费较大的开销,订阅者可以被定义为durable(持久化的)。

持久化的订阅者注册一个带有JMS保持的唯一标识的持久化订阅(subscription)。

带有相同标识的后续订阅者会再续前一个订阅者的订阅状态。

如果持久化订阅没有活动的订阅者,JMS会保持订阅消息,直到消息被订阅接收或者过期。

生产者:package cn.slimsmart.activemq.demo.topic;import javax.jms.Connection;import javax.jms.DeliveryMode;import javax.jms.JMSException;import javax.jms.MessageProducer;import javax.jms.Session;import javax.jms.TextMessage;import javax.jms.Topic;import org.apache.activemq.ActiveMQConnectionFactory;public class Producer {public static void main(String[] args) throws JMSException {// 连接到ActiveMQ服务器ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.18.43:61616"); Connection connection = factory.createConnection();connection.start();Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);// 创建主题Topic topic = session.createTopic("slimsmart.topic.test");MessageProducer producer = session.createProducer(topic);// NON_PERSISTENT 非持久化 PERSISTENT 持久化,发送消息时用使用持久模式producer.setDeliveryMode(DeliveryMode.PERSISTENT);TextMessage message = session.createTextMessage();message.setText("topic 消息。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

简单的说,JMS制定了一个发消息的规范。是一个与具体平台无关的
API,绝大多数MOM提供商都对JMS提供支持。
ActiveMQ是Apache出品的开源项目,它是JMS规范的一个实现,
JMS的作用
在不同应用之间进行通信或者从一个系统传输数据到 另外一个系统。两个应用程序之间,或分布式系统中发送消息,进行异 步通信。
Jms消息订阅者流程图
JMS消息的事务
1.创建事务createSession(paramA,paramB);
paramA是设置事务的,paramB设置acknowledgment mode(应答模式) paramA设置为false时:paramB的值可为Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE, DUPS_OK_ACKNOWLEDGE其中一个。
MOM在系统中的位置
JMS模型
Java消息服务应用程序结构支持两种模型: 1.点对点模型(基于队列)
每个消息只能有一个消费者。消息的生产者和消费者之间没有时间上的 相关性.可以由多个发送者,但只能被一个消费者消费。 • 一个消息只能被一个接受者接受一次 • 生产者把消息发送到队列中(Queue),这个队列可以理解为电视机频道(channel) • 在这个消息中间件上有多个这样的channel • 接受者无需订阅,当接受者未接受到消息时就会处于阻塞状态
JMS定义的消息类型有TextMessage、MapMessage、BytesMessage、 StreamMessage和ObjectMessage。
目的地:Destination,消息的目的地,是用来指定生产的消息的目标和 它消费的消息的来源的对象。 消息队列:Queue 点对点的消息队列 消息主题:Tipic 发布订阅的消息队列
JMS的基本构件
连接工厂: 连接工厂是客户用来创建连接的对象,例如ActiveMQ提供的 ActiveMQConnectionFactory。
连接: JMS Connection封装了JMS 客户端到JMS ProS Session是生产和消费消息的一个单线程上下文。会话用于创建
2.事务的应答确认
A)paramA设置为true时: paramB的值忽略, acknowledgment mode被jms服务器设置 SESSION_TRANSACTED 。 当一个事务被提交的时候,消息确认就会自动发生。 B) paramA设置为false时: Session.AUTO_ACKNOWLEDGE为自动确认,当客户成功的从receive方法返回的时候,或者从 MessageListener.onMessage方法成功返回的时候,会话自动确认客户收到的消息。 Session.CLIENT_ACKNOWLEDGE 为客户端确认。客户端接收到消息后,必须调用javax.jms.Message的 acknowledge方法。jms服务器才会删除消息。(默认是批量确认) DUPS_OK_ACKNOWLEDGE 允许副本的确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会 话对象就会确认消息的接收,而且允许重复确认。如果是重复的消息,那么JMS provider必须把消息头 的JMSRedelivered字段设置为true。
JMS 的通信机制

activeMQ支持多种通讯协议TCP/UDP等,我们选取最常用的TCP来分析activeMQ的通讯 机制。首先我们来明确一个概念: 客户(Client):消息的生产者、消费者对activeMQ来说都叫作客户。 消息中转器(Message broker):它是activeMQ的核心,它接收信息并进行相关处理后分 发给消息消费者。 为了能清楚的描述出activeMQ的核心通讯机制,我们选择3个部分来进行说明,它们 分别是建立链接、关闭链接、心跳。 一、Client跟activeMQ的TCP通讯的初始化过程分析如下: 1. activeMQ初始化时,通过TcpTransportServer类根据配置打开TCP侦听端口,客户通 过该端口发起建立链接的动作。 2. 把accept的Socket放入阻塞队列中。 3. 另外一个线程Socket handler阻塞着等待队列中是否有新的Socket,如果有则取出来。 4. 生成一个TransportConnection的实例。TransportConnection类的主要作用是处理链路 的状态信息,并实现CommandVisitor接口来完成各类消息的处理。 5. TransportConnection会使用一个由多个TransportFilter实例组成的消息处理链条,负 责对接收到的各类消息进行处理并发送相应的应答。这个链条的典型组成顺序: MutexTransport->WireFormatNegotiator->InactivityMonitor->TcpTransport。在这条链条中 最后的一环就是TcpTransport类,它是实际和Client获取和发送数据的地方,该类的重要 6. 建链完成,可以进行通讯操作。方法有run()和oneway(),一个负责读取,一个负责 发送。
Jms消息发送时序图
Jms消息发送开发流程
1、生产者(producer)开发流程(ProducerTool.java): 1.1 创建Connection: 根据url,user和password创建一个jms Connection。 1.2 创建Session: 在connection的基础上创建一个session,同时设置是否支持事务和ACKNOWLEDGE标识。 1.3 创建Destination对象: 需指定其对应的主题(subject)名称,producer和consumer将根据subject来发送/接收对应的消息。 1.4 创建MessageProducer: 根据Destination创建MessageProducer对象,同时设置其持久模式。 1.5 发送消息到队列(Queue): 封装TextMessage消息,使用MessageProducer的send方法将消息发送出去。 2、消费者(consumer)开发流程(ConsumerTool.java): 2.1 实现MessageListener接口: 消费者类必须实现MessageListener接口,然后在onMessage()方法中监听消息的到达并处理。 2.2 创建Connection: 根据url,user和password创建一个jms Connection,如果是durable模式,还需要给connection设置一个 clientId。 2.3 创建Session和Destination: 2.4创建replyProducer【可选】: 可以用来将消息处理结果发送给producer。 2.5 创建MessageConsumer: 根据Destination创建MessageConsumer对象。 2.6 消费message: 在onMessage()方法中接收producer发送过来的消息进行处理,并可以通过replyProducer反馈信息给 producer
消费者的消费方式
• 下两种方法之一: • 同步消费。通过调用消费者的receive方法从目的地中显式提取消息。 receive方法可以一直阻塞到消息到达。 • 异步消费。客户可以为消费者注册一个消息监听器,以定义在消息到 达时所采取的动作。 实现MessageListener接口,在MessageListener()方法中实现消息的 处理逻辑。
ActiveMQ模型分析
首先介绍该模型中每个领域类的作用,然后再介绍它们之间的关系。 Broker:activeMQ的一个整体代表
RegionBroker:负责分发broker的操作到相应的消息区域
二、关闭链接 activeMQ发现TCP链接的关闭,最关键的代码在TcpBufferedInputStream类中的 int n = in.read(buffer, position, buffer.length - position);
三、心跳 为了更好的维护TCP链路的使用,activeMQ采用了心跳机制作为判断双方链路的健康 情况。activeMQ使用的是双向心跳,也就是activeMQ的Broker和Client双方都进行相互心 跳,但不管是Broker或Client心跳的具体处理情况是完全一样的,都在InactivityMonitor 类中实现,下面具体介绍。 心跳会产生两个线程“InactivityMonitor ReadCheck”和“InactivityMonitor WriteCheck”, 它们都是Timer类型,都会隔一段固定时间被调用一次。ReadCheck线程主要调用的方法 是readCheck(),当在等待时间内,有消息接收到,则该方法会返回true。WriteCheck线 程主要调用的方法是writeCheck(),这有个小技巧,大家可以参考一下,那就是当 WriteCheck线程休眠时,有任何数据发送成功,则该线程被唤醒后,不用通过TCP向对 方真的发送心跳消息,这样可以从一定程度上减少网络传输的数据量。
这类问题有很多解决方案 ,比如DB、SOA、Socket通信、RMI,等,但我 们需要根据项目的限制以及功能和性能的需要作出选择。 JMS的应用场景:规模和复杂度较高的分布式系统。 (1)同步通信:客户发出调用后,必须等待服务对象完成处理并返回结 果后才能继续执行; (2)客户和服务对象的生命周期紧密耦合:客户进程和服务对象进程都 必须正常运行;如果由于服务对象崩溃或者网络故障导致客户的请求 不可达,客户会接收到异常; (3)点对点通信:客户的一次调用只发送给某个单独的目标对象。
JMS学习交流
JMS介绍
Java Message Service(JMS)是SUN提出的旨在统一各种MOM (Message-Oriented Middleware )系统接口的规范,它包含点对点 (Point to Point,PTP)和发布/订阅(Publish/Subscribe,pub/sub)两 种消息模型,提供可靠消息传输、事务和消息过滤等机制。
相关文档
最新文档