Java Message Service(JMS)
JMS主要用于分布式应用的各组件之间的通信,可使组件之间通信变得更加松耦合。
优势:
1:异步处理消息;
2:持久地保存消息;
3:允许将一条消息同时发送给多个接受者;
JMS架构组成:
1:服务器;
2:生产者;
3:消费者;
JMS消息机制模型主要分类:
1:PTP(Peer To Peer,点对点);
2:Pub-Sub(Publish/Subscribe,发布/订阅);
JMS的基本对象:
名称 | 对象 | 作用 |
---|---|---|
连接工厂 | ConnectionFactory | 用于创建JMS连接,由服务器管理员创建,并绑到JNDI上,客户端使用JNDI查找、定位连接工厂。 |
JMS连接 | Connection | 用于连接客户端和服务器,通常每个客户端使用单独的连接,而每个连接可连接多个JMS目的。 |
消息会话 | Session | 表示客户端与服务器的通信状态,其建立在连接之上。 |
消息目的 | Destination | 消息的目的地,获取消息的消息源。 |
消息生产者 | MessageProducer | 创建并发送消息。 |
消息消费者 | MessageConsumer | 接收并读取消息。 |
面向消息架构都需要消息服务器都支持,因此JMS需要JMS服务器支持,通常应用服务器都提供JMS服务器支持。
发送消息步骤:
1:通过JNDI查找来获取JMS连接工厂;
2:JMS连接工厂创建JMS连接;
3:JMS连接创建JMS消息会话;
4:JMS消息会话创建消息生产者;
5:JMS消息会话创建空的JMS消息;
6:JMS消息调用自身的方法填充内容;
7:通过JNDI查找JMS的消息目的;
8:消息生产者发送消息到指定的JMS消息目的;
9:关闭JMS资源。
接收消息步骤:
1:通过JNDI查找来获取JMS连接工厂;
2:JMS连接工厂创建JMS连接;
3:JMS连接创建JMS消息会话;
4:通过JNDI查找JMS的消息目的;
5:JMS会话根据指定的JMS消息目的来创建一个JMS消息消费者;
6:JMS消息消费者接收消息;
7:关闭JMS资源。
PTP模型有两种接收消息的方式:同步和异步。
同步接收策略,可使用 Message receive()、Message receive(long timeout)、Message receiveNoWait()、等方法接收。
异步接受策略,必须实现MessageListener接口,且要实现该接口的 public void onMessage(Message m)方法,该方法会在消息抵达时自动触发。
PTP消息目的是一个消息队列(Queue)。
Pub-Sub消息目的是一个消息主题(Topic)。
WebLogic提供了默认的ConnectionFactory,其JNDI名为weblogic.jms.ConnectionFactory,JBoss默认连接工厂JNDI为ConnectionFactory。
在Pub-Sub模型中,为了让消息消费者接收离线信息,客户端必须为其提供一个唯一的标识符,之后在使用Session创建一个可靠的消息订阅者。
//设置客户端ID
connection.setClientID("id");
//创建可靠的消息订阅者 TopicSubscriber receiver = session.createDurableSubscriber(destination, "id"); //删除订阅主题 session.unsubscriber(java.lang.String name);
JMS事务
为了提高消息的可靠性,JMS也提供了事务功能。
JMS提供了两种事务控制方式:
1:使用Session接口的事务;
2:在JTA中使用JMS。
Connection接口提供如下方法创建Session:
Session createSession(boolean transacted, int acknowledgeMode):transacted指定是否是事务性Session,当transacted是true时,忽略acknowledgeMode。
e.g.
Session session = connection.createSession(true, Session.AUTO_ACKNOWlEDGE);
使用JTA全局事务控制JMS操作与控制JDBC操作一样。UserTransaction tx = (UserTransaction)context.lookup("javax.transaction.UserTransaction); tx.begin(); ... tx.commit();
JMS服务器的异常监听JMS提供了一种异常监听器机制,其可以使JMS客户端接收到JMS服务器上的异常信息。
异常监听器需要实现javax.jms.ExceptionListener接口的on Exception(JMSException exception)方法。
客户端可以通过该方法的JMSException对象来访问JMS服务器上的异常。
还需要在Connection对象上使用setExceptionListener(ExceptionListener listener)方法绑定异常监听器。
send()方法不会触发监听器,因为它本身会以抛出异常的方式直接向消息生产者反馈。
ConnectionFactory connFactory = (Connectionfactory)context.lookup(CONNECTION_FACTORY_JNDI); Connection connection = connFactory.createConnection(); //为JMS绑定异常监听器 connection.setExceptionListener(new ExceptionListener { public void onException(javax.jms.JMSException exception) { } }