JMS全称是Java Message Service.其是JavaEE技术规范中的一个重要组成部分,是一种企业消息处理的规范.它的作用就像一个智能交换机,它负责路由分布式应用中各个组件所发出的消息.
JMS提供了一组通用的Java API,开发者可以通过API来 创建,发送,接收,读取 消息.JMS是一种和具体实现厂商无关的API.它的作用类似于JDBC.不管底层采用何种消息服务器的实现,应用程序总是面向通用的JMS API编程.
用的比较多的是apache的ActiveMQ,以前浮皮开发过ActiveMQ.了解不深,但这个总体国内用的还是非常多的.现在公司采用的都是JBOSS那帮家伙的一套东西,使用了HornetQ,因为JBOSS7采用了这货.google搜了下,据说性能比ActiveMQ还好点.不过想来好的也有限.其他的诸如IBM的MQSeries什么的,基本没见过.新手初学我觉得可以考虑ActiveMQ和HornetQ.一个用的多,一个JBOSS集成并且汉化很彻底.
JMS主要用于分布式应用的各组件之间的通信.它不仅使应用组件之间的通信变得更加松耦合,而且还有以下优势:
1.消息采用异步处理机制,避免客户机等待.
2.JMS可以持久的保存消息,因而提高系统的可靠性.
3.JMS允许一条消息同时发给多个接受者,更具效率.
JMS的架构总体分为3个:
- JMS服务器,路由消息的服务系统,广义上说就是服务器,比如JBOSS,GLASSFISH,WAS8.(都开发过,吐槽下GlassFish,数它麻烦.JBOSS还没试,不过既然集成了,还好吧.WAS8一般般.)
- JMS生产者,负责创建并发送消息的程序组件.
- JMS消费者.负责读取并处理消息的程序组件.
JMS的消息机制模型主要分为两大类:
- 点对点PTP模型:这种消息处理模型为应用中的各个逻辑处理单元提供可靠的通信支持.在PTP通信中,JMS把每一个消息传递给一个消息消费者.JMS系统保证消息传递给消费者,消息不会同时被多个消费者接受.如果消息消费者不在连接范围内,JMS会自动保证消息不会丢失.直到消息消费者进入连接,消息将自动送达.因此JMS需要将消息保存到永久介质上如数据库.
- 发布/订阅 Pub-Sub模型:在这种模型中,每个消息被发送到一个消息主题,该主题可以拥有多个订阅者.JMS系统负责将消息的副本传给该主题的每个订阅者.
JMS的API主要的对象:
- 连接工厂:它由服务器管理员创建,并绑定到JNDI树上,JMS客户端使用JNDI查找,定位连接工厂,然后利用连接工厂创建JMS连接.
- JMS连接:连接表示客户机和服务器之间的活动连接.JMS通过连接工厂创建连接.JMS是一个相当重要的对象.通常,每个客户机使用单独的连接,而每个连接则可以连接多个JMS目的.
- JMS会话:会话表示客户机与JMS服务器之间的通信状态.JMS会话建立在连接之上,表示JMS客户机与服务器之间的通信线程.会话定义了消息的顺序.JMS使用会话进行事务性的消息处理.
- JMS消息目的:即消息生产者发送消息的目的地,也就是消息消费者获取消息的消息源.
- JMS消息生产者:消息生产者负责创建消息并将消息发送到消息目的.
- JMS消息消费者:消息消费者负责接收消息并读取消息内容.
JMS版本
现在大家只需要关注JMS1.1即可,老版本是1.0.2,PTP模型和Pub-Sub模型在1.0.2里有两套不同的API,而1.1统一了这些API.只需关注JMS1.1即可.
接着是一份JMS提供的API接口的图标:
JMS1.1统一域模型的API |
连接工厂 | ConnectionFactory |
JMS连接 | Connection |
消息会话 | Session |
消息目的 | Destination |
消息生产者 | MessageProducer |
消息消费者 | MessageConsumer |
| |
producer: [prə'dʊsɚ] n. 制作人,制片人;生产者;发生器
consumer:[kən'sumɚ] n. 消费者;用户,顾客
下面是一个简单的示例代码:
02 | * @description 下面是要从服务器上获取连接工厂的JNDI和队列地址的JNDI. 然后就是发送信息到服务器端. |
04 | * @param cfJNDI 连接工厂的JNDI |
05 | * @param queueJNDI 队列的JNDI |
07 | * @throws JMSException |
08 | * @throws NamingException |
10 | private boolean getConnectFactory(String msg, String cfJNDI, String queueJNDI) throws JMSException, NamingException { |
11 | Connection connection = null ; |
12 | MessageProducer producer = null ; |
15 | InitialContext ic = new InitialContext(); |
17 | ConnectionFactory connectionFactory = (ConnectionFactory) ic.lookup(cfJNDI); |
19 | Queue queue = (Queue) ic.lookup(queueJNDI); |
21 | connection = connectionFactory.createConnection(); |
23 | Session session = connection.createSession( false , Session.AUTO_ACKNOWLEDGE); |
25 | producer = session.createProducer(queue); |
27 | TextMessage message = session.createTextMessage(); |
30 | producer.send(message); |
32 | this .close(connection, producer); |
33 | } catch (JMSException e) { |
34 | this .close(connection, producer); |
35 | throw new JMSException(e.getMessage()); |
36 | } catch (NamingException e) { |
37 | this .close(connection, producer); |
38 | throw new NamingException(e.getMessage()); |
43 | private void close(Connection connection, MessageProducer producer) throws JMSException { |
45 | if ( null != producer) { |
48 | if ( null != connection) { |
51 | } catch (JMSException e) { |
52 | throw new JMSException(e.getMessage()); |
转载自:http://my.oschina.net/zhaoqian/blog/90121