activemq入门

     今天调研了一下activemq,了解了jms原理

   原理大致如下:

  消息中间件一般有两种传递模型:点对点模型(PTP)和发布-订阅模型(Pub/Sub)。

  1. 点对点模型(PTP)

  点对点模型用于消息生产者和消息消费者之间点到点的通信。消息生产者将消息发动到由某个名字标识的特定消费者。这个名字实际上对应于消息服务中的一个队列(Queue),在消息传动给消费者之前它被存储在这个队列中。队列可以是持久的,以保证在消息服务出现故障时仍然能够传递消息。

  2. 发布-订阅模型(Pub/Sub)

  发布-订阅模型用称为主题(topic)的内容分层结构代替了PTP模型中的惟一目的地,发送应用程序发布自己的消息,指出消息描述的是有关分层结构中的一个主题的信息。希望接收这些消息的应用程序订阅了这个主题。订阅包含子主题的分层结构中的主题的订阅者可以接收该主题和其子主题发表的所有消息。

  多个应用程序可以就一个主题发布和订阅消息,而应用程序对其他人仍然是匿名的。MOM 起着代理(broker)的作用(activemq)将一个主题已发表的消息路由给该主题的所有订阅者。

以下是入门代码

1.点对点代码实现

发送者

package com.joygame.activemq;


import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Sender {
    private static final int SEND_NUMBER = 5;

    public static void main(String[] args) {
        // ConnectionFactory :连接工厂,JMS 用它创建连接
        ConnectionFactory connectionFactory;
        // Connection :JMS 客户端到JMS Provider 的连接
        Connection connection = null;
        // Session: 一个发送或接收消息的线程
        Session session;
        // Destination :消息的目的地;消息发送给谁.
        Destination destination;
        // MessageProducer:消息发送者
        MessageProducer producer;
        // TextMessage message;
        // 构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar
        connectionFactory = new ActiveMQConnectionFactory(
                ActiveMQConnection.DEFAULT_USER,
                ActiveMQConnection.DEFAULT_PASSWORD,
                Constans.MQ_URL);
        try {
            // 构造从工厂得到连接对象
            connection = connectionFactory.createConnection();
            // 启动
            connection.start();
            // 获取操作连接
            session = connection.createSession(Boolean.TRUE,
                    Session.AUTO_ACKNOWLEDGE);
            // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
            destination = session.createQueue("FirstQueue");
            // 得到消息生成者【发送者】
            producer = session.createProducer(destination);
            // 设置不持久化,此处学习,实际根据项目决定
            producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
            // 构造消息,此处写死,项目就是参数,或者方法获取
            sendMessage(session, producer);
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != connection)
                    connection.close();
            } catch (Throwable ignore) {
            }
        }
    }

    public static void sendMessage(Session session, MessageProducer producer)
            throws Exception {
        for (int i = 1; i <= SEND_NUMBER; i++) {
            TextMessage message = session
                    .createTextMessage("ActiveMq 发送的消息" + i);
            // 发送消息到目的地方
            System.out.println("发送消息:" + "ActiveMq 发送的消息" + i);
            producer.send(message);
        }
    }
}


接收者代码如下

package com.joygame.activemq;


import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Receiver {
    public static void main(String[] args) {
        // ConnectionFactory :连接工厂,JMS 用它创建连接
        ConnectionFactory connectionFactory;
        // Connection :JMS 客户端到JMS Provider 的连接
        Connection connection = null;
        // Session: 一个发送或接收消息的线程
        Session session;
        // Destination :消息的目的地;消息发送给谁.
        Destination destination;
        // 消费者,消息接收者
        MessageConsumer consumer;
        connectionFactory = new ActiveMQConnectionFactory(
                ActiveMQConnection.DEFAULT_USER,
                ActiveMQConnection.DEFAULT_PASSWORD,
                Constans.MQ_URL);
        try {
            // 构造从工厂得到连接对象
            connection = connectionFactory.createConnection();
            // 启动
            connection.start();
            // 获取操作连接
            session = connection.createSession(Boolean.FALSE,
                    Session.AUTO_ACKNOWLEDGE);
            // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
            destination = session.createQueue("FirstQueue");
            consumer = session.createConsumer(destination);
            while (true) {
                //设置接收者接收消息的时间,为了便于测试,这里谁定为100s
                TextMessage message = (TextMessage) consumer.receive(100000);
                if (null != message) {
                    System.out.println("收到消息" + message.getText());
                } else {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != connection)
                    connection.close();
            } catch (Throwable ignore) {
            }
        }
    }
}


2.发布订阅

发布者

package com.joygame.activemq;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import javax.naming.NamingException;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class ChatTop{
	private TopicSession pubSession;
	private TopicPublisher pub;
	private TopicConnection conn;
	
	public ChatTop(String username)
			throws NamingException, JMSException {
		
		// 1. 创建 TopicConnectionFacotry
		TopicConnectionFactory factory = new ActiveMQConnectionFactory(
	                ActiveMQConnection.DEFAULT_USER,
	                ActiveMQConnection.DEFAULT_PASSWORD,
	                Constans.MQ_URL);
		//2. 创建 TopicConnection
		TopicConnection connection = factory.createTopicConnection();
		// 3. 根据 Connection 创建 JMS 会话
		TopicSession pubSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
		// 4. 创建 Topic
		Topic topic = pubSession.createTopic("topic.chat");
		// 5. 创建 发布者 和 订阅者
		TopicPublisher pub = pubSession.createPublisher(topic);	
		// 7. 开启JMS连接
		connection.start();
		this.conn = connection;
		this.pub = pub;
		this.pubSession = pubSession;
		
	}
	
	/***
	 * @description 读取控制台消息
	 * @author <a href="mailto:ruiyong.hu@daw.so">胡瑞永</a>
	 * @param txt 
	 * @since activemq1.0.0
	 */
	protected void writeMessage(String txt) {
		try {
			TextMessage message = pubSession.createTextMessage();
			message.setText(txt);			
			//发布者发布消息
			pub.setDeliveryMode(DeliveryMode.PERSISTENT);
			pub.setDisableMessageID(true);
			pub.publish(message);
		} catch (JMSException e) {
			e.printStackTrace();
		}

	}

	public void close() throws JMSException {
		this.conn.close();
	}

	public static void main(String[] args1) throws NamingException,
			JMSException, IOException {

		ChatTop chat = new ChatTop("hury");

		BufferedReader cmd = new BufferedReader(
				new InputStreamReader(System.in));

		while (true) {
			String s = cmd.readLine();
			if (s.equalsIgnoreCase("exit")) {
				chat.close();
				System.exit(0);
			} else {
				chat.writeMessage(s);
			}
		}
	}
}


订阅者

 

/*
 * Copyright (c) Joygame 2013
 * <a href="www.cmge.com">中国手游</a>
 * Create Date : 2013-9-13
 */

package com.joygame.activemq;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

/**
 * @description 订阅者
 * @author  <a href="mailto:ruiyong.hu@daw.so">胡瑞永</a>
 * @version 1.0, 2013-9-13
 * @see     
 * @since   activemq1.0
 */
public class SubTop implements MessageListener{
	
	private TopicSession subSession;
	private TopicSubscriber sub;
	private TopicConnection conn;
	
	/**
	 * @description 构造函数
	 * @author <a href="mailto:ruiyong.hu@daw.sa">胡瑞永</a>  
	 * @throws Exception 
	 * @since activemq1.0.0
	 */
	public SubTop() throws Exception {
		//1.jms connectfactory
		TopicConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
                ActiveMQConnection.DEFAULT_PASSWORD,
                Constans.MQ_URL);
		//2.connection
		conn = factory.createTopicConnection();
		/**/
		conn.setClientID("huryclientID3");      
		//3 jms session 
		subSession = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
		//4.topic
		Topic topic = subSession.createTopic("topic.chat");
		//订阅者
		sub = subSession.createDurableSubscriber(topic, "huryid1");
//		sub =subSession.createSubscriber(topic);
		sub.setMessageListener(this);
		conn.start();
	}
	/**
	 * @description  当收到消息服务器转送过来的消息触发次此方法
	 * @author <a href="mailto:ruiyong.hu@daw.so">胡瑞永</a>
	 * @param arg0 
	 * @since activemq1.0.0 
	 */
	@Override
	public void onMessage(Message message) {
		if(message instanceof TextMessage)
		{
			try {
				System.out.println(this.toString()+":"+((TextMessage)message).getText());
			} catch (JMSException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) throws Exception {
		SubTop sub = new SubTop();
	}
	
}


最点一点要说明是:

DeliveryMode.NON_PERSISTENT和DeliveryMode.PERSISTENT的效果

首先生产主代码为

 public static void main(String[] args) throws Exception {  
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");  
        Connection connection = factory.createConnection();  
        connection.start();  
        Queue queue = new ActiveMQQueue("testQueue");  
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);  
        MessageProducer producer = session.createProducer(queue);  
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);  
        producer.send(session.createTextMessage("A persistent Message"));  
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);  
        producer.send(session.createTextMessage("A non persistent Message"));  
        System.out.println("Send messages sucessfully!");  
    }  


运行上面的程序,当输出“Send messages sucessfully!”时,说明两个消息都已经发送成功,然后我们结束它,来停止JMS Provider。

接下来我们重新启动JMS Provicer,和消费者,消费者会接到JMS Provicer重启之前的消息

 

总结:消息中间件在分布式联机事务处理环境中,它担当通讯资源管理器(CRM)的角色,为分布式应用提供实时、高效、可靠的、跨越不同操作系统、不同网络的消息传递服务,同时消息中间件减少了开发跨平台应用程序的复杂性。在要求可靠传输的系统中可以利用消息中间件作为一个通讯平台,向应用提供可靠传输功能来传递消息和文件。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值