JMS学习心得(一)

学习中的一些心得记录
p2p方式:
概念:queue,QueueSender,QueueReceiver,队列,消息发送者,消息接收者三个角色。发送者向队列中加入消息,接收者从队列取出消息,队列中的消息接收一条少一条,如果有多个接收者连接到队列,一条消息只能被一个接收者取走。
一、 消息发送方式默认不设置的时候是  DeliveryMode.PERSISTENT 方式,也就是持久化方式。该常量值为2。这种方式消息不会丢失,会保存在服务器上。就是说消息发送后,即使你关闭jms服务器(比如用activeMQ, 关闭服务器程序),然后服务重新启动后,这条消息仍然是存在的,而其他使用NON_PERSISTENT方式的消息就丢失了。我想大多数情况下啊我们需要 的是PERSISTENT方式吧!
DeliveryMode.NON_PERSISTENT 常量值为1
DeliveryMode.PERSISTENT 常量值为2
int a = msgp0.getDeliveryMode();
        //msgp0.setDeliveryMode(DeliveryMode.PERSISTENT);

二、消息的消费者接收消息可以采用两种方式:

1、consumer.receive() 或 consumer.receive(int timeout);
2、注册一个MessageListener。

采用第一种方式,即同步方式,遇到receive方法就会阻塞,消息的接收者会一直等待下去,直到有消息到达,或者超时。该方式调用一次方法只接收一条消息。
采用第二种方式,即异步方式,程序会一直监听,只要有消息就会响应onMessage方法,当执行 conn.close()方法时会结束监听器。
MessageConsumer comsumer  =  session.createConsumer(queue);
comsumer.setMessageListener(
new  MessageListener(){
            @Override
            
public   void  onMessage(Message m) {
                TextMessage textMsg 
=  (TextMessage) m;
                
try  {
                    System.out.println(textMsg.getText());
                } 
catch  (JMSException e) {
                    e.printStackTrace();
                }
            }
           
        });
测试发现
conn.close() 方法对这两种方式有些不同,对于监听器方式,只要close方法执行,监听就会终止,估计监听是以后台线程方式执行的。而对于recive接收方式,只要 receive方法只要调用一次,就必须等到有消息到达才会执行下面的语句,是阻塞的方式,即使后面的conn.close()不会执行到。
参考:http://www.cnblogs.com/iloveu/archive/2009/06/10/1500714.html

pub/sub方式
概念:topic,publisher,subscriber,主题,发布者,订阅者三个角色。主题和订阅者是一对多关系,一个主题可以被多个订阅者订阅。当发布者向某个主题发送一条消息时,所有的订阅者都会收到。
如何理解订阅的概念呢,个人理解,分两种情况:
一、 创建一个订阅者时使用session.createDurableSubscriber(topic, clientId )方法创建为持久型订阅者时,该topic和clientId的订阅关系将被保存在服务器上,即产生了订阅关系。这样clientId这个id的订阅者将 在离线的时候,也不会丢失消息。这个订阅关系也可以理解为被持久化在jms服务器上了,使用jmx的监视控制台(我使用的activeMq),可以看到有 一个Subscription的节点,下面有你订阅主题时给定的客户端名字。可以使用unsubscribe 方法 取消订阅关系。
二、 创建一个非持久化方式的订阅者时,只有在客户端订阅者连接到jms服务器时,订阅关系成立,订阅者离线时,订阅关系即取消,不会保存在服务器上,这也是非 持久化方式订阅者不能离线接收消息的原因吧。默认为广播方式,在没有订阅者连接到服务器时,发送的消息将丢失,不会保存在服务器。

对jms规范的理解:
jms 规范是sun提出的java的消息服务统一的api接口规范,规范、标准的好处就不用说了,java能走到今天,规范标准的制定可以说有很大的功劳吧。所 有提供java消息服务的软件提供者都必须针对这个接口实现。我们编写jms程序时,基本可以做到只针对接口编程,不用考虑是那个厂家实现,这是我们的代 码有了很大的灵活行,不绑定某个具体厂商。只要你的代码写的够好,完全可以不修改代码就直接部署到不同厂商的jms服务器上。
举个例子:编写一个基于ActiveMQ的jms程序时有这样的代码:
ActiveMQConnectionFactory factory = new  ActiveMQConnectionFactory("vm://localhost" );
...
Queue queue = new  ActiveMQQueue("testQueue" ); 
等,这样就在代码里绑死了ActiveMQ的api。要做到厂商无关性,应该使用jndi来取得工厂对象以及队列资源。
比如:
ConnectionFactory cf = (ConnectionFactory) ctx.lookup("connectionFactory");
...
Destination dest = (Queue) ctx.lookup("MyQueue");
注意接口也尽量使用jms的大的接口。当然这里需要提供jndi服务支持,ActiveMQ本身提供jndi服务,只要在classpath中有一个jndi.properties文件,在配置文件中对资源做一些配置就可以了
比如:
java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory
connectionFactoryNames = connectionFactory, queueConnectionFactory, topicConnectionFactry
queue.MyQueue = zmQueue
topic.MyTopic = zmTopic
等。

对jms规范1.1的一些理解:
JMS 1.0.2 定义了两种类型的消息传递域(它们是相互独立的),即点对点和发布/订阅。JMS 的最新版本,即版本 1.1,JMS 统一了这两个域。如下图:有了 JMS 1.1,客户机就不再必须专门针对这个或那个域进行实现了。

JMS 公共 PTP 域 Pub/Sub 域
ConnectionFactoryQueueConnectionFactoryTopicConnectionFactory
ConnectionQueueConnectionTopicConnection
DestinationQueueTopic
SessionQueueSessionTopicSession
MessageProducerQueueSenderTopicPublisher
MessageConsumerQueueReceiverTopicSubscriber


参考:http://www.ibm.com/developerworks/cn/java/j-jms11/index.html
就是说,只使用JMS公共域的接口就可以完成jms程序编写。所以推荐尽量使用大的接口,增加代码的灵活性。
比如,写pub/sub方式的消息程序也可以这样:
        Context ctx = new InitialContext();
        ConnectionFactory factory = (ConnectionFactory) ctx
                .lookup("connectionFactory");

        Connection connection = factory.createConnection();
        connection.start();

        // 创建一个Topic
        Destination topic = (Destination) ctx.lookup("MyTopic");
        Session session = connection.createSession(false,
                Session.AUTO_ACKNOWLEDGE);

        MessageConsumer comsumer3 = session.createConsumer(topic);
        Message msg = comsumer3.receive();

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值