ActiveMQ實戰(簡單)

 ActiveMQ是JMS規範的一個實現產品,即對JMS的一套接口進行了實現。所以下面我們先對JMS與ActiveMQ進行一個簡單介紹,然後再介紹ActiveMQ的P2P與PubSub兩種開發模式。


一、    JMS簡介


       JMS即Java消息服務,是J2EE的13規範之一,是一套面向消息中間件(MOM)的應用程序接口。用在兩個程序之間,或分佈式系統中發送消息,進行異步通信。

       JMS使我們能夠通過消息收發服務(也可以稱爲,消息中介程序或路由器)從一個JMS客戶機向另一個JMS客戶機發送消息。消息是JMS中的一種類型對象,由兩部分組成:報頭和消息主體。報頭由路由信息以及有關該消息的元數據組成。消息主體則攜帶着應用程序的數據或有效負載。根據有效負載的類型來劃分,消息可分爲多種,它們分別攜帶:簡單文本消息、可序列化的對象、屬性集合、字節流、原始值流、無有效負載消息。


二、    ActiveMQ簡介


       ActiveMQ出身名門,是Apache門下的最流行的,能力強勁的開源消息總線。完全支持JMS1.1和J2EE1.4規範的JMS Provide實現。它從設計上保證了高性能的集羣,當然實現了JMS的P2P與PubSub兩種開發模式。


三、    安裝運行ActiveMQ


       首先下載ActiveMQ的穩定版:http://activemq.apache.org ,如下圖,我下載的是apache-activemq-5.11.1-bin:



  然後進入到bin/win64文件夾下,並啓動activemq.bat:



出現如下提示表示ActiveMQ啓動成功:



然後在瀏覽器輸入:http://localhost:8161/即可看到ActiveMQ的管理界面:



 然後我們點擊:Manage ActiveMQ broker登錄管理後臺:(用戶名、密碼默認都爲admin)




登錄進去以後我們可以點擊Queues看到消息隊列以及消費者情況等:


四、    P2P開發模式實戰


       建立JavaProject:ActiveMQ-p2p,並導入ActiveMQ的核心jar包,只需要導入根目錄下的activemq-all.jar即可:


 然後建立一個消息生產者類:JMSProducer;一個消息消費者類:JMSConsumer:

       源碼如下:

       消息生產者類:JMSProducer

package com.tgb.jms.ActiveMQ;  
  
import javax.jms.Connection;  
import javax.jms.ConnectionFactory;  
import javax.jms.Destination;  
import javax.jms.JMSException;  
import javax.jms.MessageProducer;  
import javax.jms.Session;  
import javax.jms.TextMessage;  
  
import org.apache.activemq.ActiveMQConnection;  
import org.apache.activemq.ActiveMQConnectionFactory;  
  
/** 
 * 消息生產者 
 *  
 * @author Administrator 
 *  
 */  
public class JMSProducer {  
  
    private static final String USERNAME = ActiveMQConnection.DEFAULT_USER; // 默認的連接用戶名  
    private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD; // 默認的連接密碼  
    private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL; // 默認的連接地址  
    private static final int SENDNUM = 10; // 發送的消息數量  
  
    public static void main(String[] args) {  
  
        ConnectionFactory connectionFactory; // 連接工廠  
        Connection connection = null; // 連接  
        Session session; // 會話 接受或者發送消息的線程  
        Destination destination; // 消息的目的地  
        MessageProducer messageProducer; // 消息生產者  
  
        // 實例化連接工廠  
        connectionFactory = new ActiveMQConnectionFactory(JMSProducer.USERNAME, JMSProducer.PASSWORD, JMSProducer.BROKEURL);  
  
        try {  
            connection = connectionFactory.createConnection(); // 通過連接工廠獲取連接  
            connection.start(); // 啓動連接  
            session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); // 創建Session,第一個參數爲是否開啓事務  
            destination = session.createQueue("FirstQueue1"); // 創建消息隊列  
            messageProducer = session.createProducer(destination); // 創建消息生產者  
            sendMessage(session, messageProducer); // 發送消息  
            session.commit();  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            if (connection != null) {  
                try {  
                    connection.close();  
                } catch (JMSException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }  
  
    /** 
     * 發送消息 
     *  
     * @param session 
     * @param messageProducer 
     * @throws Exception 
     */  
    public static void sendMessage(Session session, MessageProducer messageProducer) throws Exception {  
        for (int i = 0; i < JMSProducer.SENDNUM; i++) {  
            TextMessage message = session.createTextMessage("ActiveMQ 發送的消息" + i);  
            System.out.println("發送消息:" + "ActiveMQ 發送的消息" + i);  
            messageProducer.send(message);  
        }  
    }  
}  

消息消費者類:JMSConsumer


package com.tgb.jms.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;

/**
 * 消息消費者
 * 
 * @author wangzhipeng
 * 
 */
public class JMSConsumer {
	private static final String USERNAME = ActiveMQConnection.DEFAULT_USER; // 默認的連接用戶名
	private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD; // 默認的連接密碼
	private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL; // 默認的連接地址

	public static void main(String[] args) {
		ConnectionFactory connectionFactory; // 連接工廠
		Connection connection = null; // 連接
		Session session; // 會話 接受或者發送消息的線程
		Destination destination; // 消息的目的地
		MessageConsumer messageConsumer;// 消息消費者

		// 實例化連接工廠
		connectionFactory = new ActiveMQConnectionFactory(JMSConsumer.USERNAME, JMSConsumer.PASSWORD, JMSConsumer.BROKEURL);

		try {
			connection = connectionFactory.createConnection();// 通過工廠獲取連接
			connection.start();// 啓動連接
			session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);// 第一個參數爲是否開啓事務
			destination = session.createQueue("FirstQueue1");// 創建消息隊列
			messageConsumer = session.createConsumer(destination);// 創建消息消費者
			/*
			 * 實際應用中,不會這麼用,會註冊一個監聽
			 */
			while (true) {
				TextMessage textMessage = (TextMessage) messageConsumer.receive(100000);
				if (textMessage != null) {
					System.out.println("收到的消息:" + textMessage.getText());
				} else {
					break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 然後我們運行JMSProducer的main方法來生產10條消息,成功執行後,我們刷新一下後臺頁面,可以看到我們剛纔創建的消息隊列:FirstQueue1,消息個數爲10,沒有消費者,進入隊列的消息爲10,出列消息個數爲0:




然後我們運行JMSConsumer類的main方法,來接收FirstQueue1的消息,成功執行後,我們再刷新後臺頁面,發現消息已被接收:




 P2P開發模式優化

  上面的實例中我們接收消息的方式爲,寫了一個死循環while (true) 來不停的接收消息,這樣很浪費cpu資源,實際生產中不會這麼做。這裏,我們可以註冊一個監聽器,當監聽到有消息入隊列後,纔去接收消息。所以,改動如下:

  首先,新建一個監聽類Listener,需要實現MessageListener接口:


package com.tgb.jms.ActiveMQ2;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

/**
 * 消息監聽
 * 
 * @author zhipeng
 * 
 */
public class Listener implements MessageListener {

	@Override
	public void onMessage(Message message) {
		// TODO Auto-generated method stub
		try {
			System.out.println("收到的消息:" + ((TextMessage) message).getText());
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

然後我們將消息接收者類JMSConsumer的while (true)死循環代碼替換爲messageConsumer.setMessageListener

(newListener());即可,如下圖:



 這樣一來我們就符合我們人爲的思維操作了,會節省很多cpu資源。


五、    PubSub開發模式實戰


       P2P的模式相當於一個消息生產者一個消費者,PubSub中可以有一個消息發佈者多個消息訂閱者,開發與P2P幾乎一樣,只是將createQueue(創建消息隊列)改爲了createTopic(創建主題);生產消息改爲了發佈消息;接收消息改爲了訂閱消息。代碼這裏就不再貼出來了。有需要的同志到這裏下載http://download.csdn.net/detail/wang379275614/9023177

       這裏需要注意的是,訂閱者必須先訂閱,然後發佈者發送消息後,訂閱者才能自動收到消息。


六、    總結


       ActiveMQ是JMS規範的一個實現產品,主要用在兩個程序之間,或分佈式系統中發送消息,進行異步通信。我們可以用它來解決高併發的問題,或者分佈式事務的問題等。


轉載地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章