ActiveMQ消息隊列的使用和應用

一、什麼是ActiveMQ

AciveMQ是Apache出品的目前最流行,能力強勁的開源消息總線

消息列隊有兩種消息模式,一種是點對點的消息模式,還有一種就是訂閱的模式.

主要功能:

  1. 解決服務器之間的耦合性
  2. 使用消息隊列,增加系統併發處理量

主要應用場景:

  1. 當系統使用短信平臺、郵件平臺的時候
  2. 當系統使用搜索平臺、緩存平臺的時候你

二、使用外置ActiveMQ流程:

1.官網地址:http://activemq.apache.org/

2.安裝包下載完成後解壓後 就是這個樣子了 (注意一定要解壓到全英文路徑下的包內)

3.打開你的bin目錄,打開你係統對應位數的目錄

4.雙擊啓動activemq.bat

5.點完之後會自動彈出來doc啓動,稍等一下 如果你最後跟我的一樣 說明啓動成功了

6.啓動成功,在瀏覽器中訪問http://localhost:8161/ 就能訪問到activemq的頁面

7.登錄成功後(用戶名和密碼都是admin),會有兩個隊列:topicqueue (後臺創建隊列,這邊會實時顯示)

三、兩種消息模式

1.點對點的實現代碼

項目使用MAVEN來構建(pom.xml)

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.itsiji</groupId>
  <artifactId>activemq</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <!--activemq-->
  <dependencies>
  	<dependency>
		<groupId>org.apache.activemq</groupId>
		<artifactId>activemq-client</artifactId>
		<version>5.13.4</version>
	 </dependency>
  </dependencies>
  
  <build>
	<plugins>			
		<!-- java編譯插件 -->
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-compiler-plugin</artifactId>
			<version>3.2</version>
			<configuration>
				<source>1.7</source>
				<target>1.7</target>
				<encoding>UTF-8</encoding>
			</configuration>
	     </plugin>
	</plugins>
  </build>
</project>

1.1點對點的發送方

需要注意的:連接地址的ip和端口號是 127.0.0.1:61616

                      在頁面管理控制檯查看消息隊列的ip和端口號是 127.0.0.1:8161

package com.itsiji.test.queue;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class TestQueueSend {
	

	
	    //連接賬號
	    private String userName = "";
	    //連接密碼
	    private String password = "";
	    //連接地址
	    private String brokerURL = "tcp://127.0.0.1:61616";
	    //connection的工廠
	    private ConnectionFactory factory;
	    //連接對象
	    private Connection connection;
	    //一個操作會話
	    private Session session;
	    //目的地,其實就是連接到哪個隊列,如果是點對點,那麼它的實現是Queue,如果是訂閱模式,那它的實現是Topic
	    private Destination destination;
	    //生產者,就是產生數據的對象
	    private MessageProducer producer;
	    
	    public static void main(String[] args) {
	         TestQueueSend send = new TestQueueSend();
	        send.start();
	    }
	    
	    public void start(){
	        try {
	            //根據用戶名,密碼,url創建一個連接工廠
	            factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
	            //從工廠中獲取一個連接
	            connection = factory.createConnection();
	            //測試過這個步驟不寫也是可以的,但是網上的各個文檔都寫了
	            connection.start();
	            //創建一個session
	            //第一個參數:是否支持事務,如果爲true,則會忽略第二個參數,被jms服務器設置爲SESSION_TRANSACTED
	            //第二個參數爲false時,paramB的值可爲Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一個。
	            //Session.AUTO_ACKNOWLEDGE爲自動確認,客戶端發送和接收消息不需要做額外的工作。哪怕是接收端發生異常,也會被當作正常發送成功。
	            //Session.CLIENT_ACKNOWLEDGE爲客戶端確認。客戶端接收到消息後,必須調用javax.jms.Message的acknowledge方法。jms服務器纔會當作發送成功,並刪除消息。
	            //DUPS_OK_ACKNOWLEDGE允許副本的確認模式。一旦接收方應用程序的方法調用從處理消息處返回,會話對象就會確認消息的接收;而且允許重複確認。
	            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
	            //創建一個到達的目的地,其實想一下就知道了,activemq不可能同時只能跑一個隊列吧,這裏就是連接了一個名爲"text-msg"的隊列,這個會話將會到這個隊列,當然,如果這個隊列不存在,將會被創建
	            destination = session.createQueue("text-msg");
	            //從session中,獲取一個消息生產者
	            producer = session.createProducer(destination);
	            //設置生產者的模式,有兩種可選
	            //DeliveryMode.PERSISTENT 當activemq關閉的時候,隊列數據將會被保存
	            //DeliveryMode.NON_PERSISTENT 當activemq關閉的時候,隊列裏面的數據將會被清空
	            producer.setDeliveryMode(DeliveryMode.PERSISTENT);
	            
	            //創建一條消息,當然,消息的類型有很多,如文字,字節,對象等,可以通過session.create..方法來創建出來
	            TextMessage textMsg = session.createTextMessage("呵呵");
	            for(int i = 0 ; i < 100 ; i ++){
	                //發送一條消息
	                producer.send(textMsg);
	            }
	            
	            System.out.println("發送消息成功");
	            //即便生產者的對象關閉了,程序還在運行哦
	            producer.close();
	            
	        } catch (JMSException e) {
	            e.printStackTrace();
	        }
	    }
	}

1.2點對點的接收方

package com.itsiji.test.queue;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class TestQueueReceive {
	

	
	    //連接賬號
	    private String userName = "";
	    //連接密碼
	    private String password = "";
	    //連接地址
	    private String brokerURL = "tcp://127.0.0.1:61616";
	    //connection的工廠
	    private ConnectionFactory factory;
	    //連接對象
	    private Connection connection;
	    //一個操作會話
	    private Session session;
	    //目的地,其實就是連接到哪個隊列,如果是點對點,那麼它的實現是Queue,如果是訂閱模式,那它的實現是Topic
	    private Destination destination;
	    //消費者,就是接收數據的對象
	    private MessageConsumer consumer;
	    public static void main(String[] args) {
	        TestQueueReceive receive = new TestQueueReceive();
	        receive.start();
	    }
	    
	    public void start(){
	        try {
	            //根據用戶名,密碼,url創建一個連接工廠
	            factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
	            //從工廠中獲取一個連接
	            connection = factory.createConnection();
	            //測試過這個步驟不寫也是可以的,但是網上的各個文檔都寫了
	            connection.start();
	            //創建一個session
	            //第一個參數:是否支持事務,如果爲true,則會忽略第二個參數,被jms服務器設置爲SESSION_TRANSACTED
	            //第二個參數爲false時,paramB的值可爲Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一個。
	            //Session.AUTO_ACKNOWLEDGE爲自動確認,客戶端發送和接收消息不需要做額外的工作。哪怕是接收端發生異常,也會被當作正常發送成功。
	            //Session.CLIENT_ACKNOWLEDGE爲客戶端確認。客戶端接收到消息後,必須調用javax.jms.Message的acknowledge方法。jms服務器纔會當作發送成功,並刪除消息。
	            //DUPS_OK_ACKNOWLEDGE允許副本的確認模式。一旦接收方應用程序的方法調用從處理消息處返回,會話對象就會確認消息的接收;而且允許重複確認。
	            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
	            //創建一個到達的目的地,其實想一下就知道了,activemq不可能同時只能跑一個隊列吧,這裏就是連接了一個名爲"text-msg"的隊列,這個會話將會到這個隊列,當然,如果這個隊列不存在,將會被創建
	            destination = session.createQueue("text-msg");
	            //根據session,創建一個接收者對象
	            consumer = session.createConsumer(destination);
	            
	            
	            //實現一個消息的監聽器
	            //實現這個監聽器後,以後只要有消息,就會通過這個監聽器接收到
	            consumer.setMessageListener(new MessageListener() {
	                @Override
	                public void onMessage(Message message) {
	                    try {
	                        //獲取到接收的數據
	                        String text = ((TextMessage)message).getText();
	                        System.out.println(text);
	                    } catch (JMSException e) {
	                        e.printStackTrace();
	                    }
	                }
	            });
	            //關閉接收端,也不會終止程序哦
//	            consumer.close();
	        } catch (JMSException e) {
	            e.printStackTrace();
	        }
	    }
	}

2.訂閱/發佈模式的實現代碼

2.1訂閱模式的發佈方

package com.itsiji.test.topic;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class TestTopicSend {
	
//連接賬號
private String userName = "";
//連接密碼
private String password = "";
//連接地址
private String brokerURL = "tcp://127.0.0.1:61616";
//connection的工廠
private ConnectionFactory factory;
//連接對象
private Connection connection;
//一個操作會話
private Session session;
//目的地,其實就是連接到哪個隊列,如果是點對點,那麼它的實現是Queue,如果是訂閱模式,那它的實現是Topic
private Destination destination;
//生產者,就是產生數據的對象
private MessageProducer producer;

public static void main(String[] args) {
    TestTopicSend send = new TestTopicSend();
    send.start();
}

public void start(){
    try {
        //根據用戶名,密碼,url創建一個連接工廠
        factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
        //從工廠中獲取一個連接
        connection = factory.createConnection();
        //測試過這個步驟不寫也是可以的,但是網上的各個文檔都寫了
        connection.start();
        //創建一個session
        //第一個參數:是否支持事務,如果爲true,則會忽略第二個參數,被jms服務器設置爲SESSION_TRANSACTED
        //第二個參數爲false時,paramB的值可爲Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一個。
        //Session.AUTO_ACKNOWLEDGE爲自動確認,客戶端發送和接收消息不需要做額外的工作。哪怕是接收端發生異常,也會被當作正常發送成功。
        //Session.CLIENT_ACKNOWLEDGE爲客戶端確認。客戶端接收到消息後,必須調用javax.jms.Message的acknowledge方法。jms服務器纔會當作發送成功,並刪除消息。
        //DUPS_OK_ACKNOWLEDGE允許副本的確認模式。一旦接收方應用程序的方法調用從處理消息處返回,會話對象就會確認消息的接收;而且允許重複確認。
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //創建一個到達的目的地,其實想一下就知道了,activemq不可能同時只能跑一個隊列吧,這裏就是連接了一個名爲"text-msg"的隊列,這個會話將會到這個隊列,當然,如果這個隊列不存在,將會被創建
        
        
        
        //=======================================================
        //點對點與訂閱模式唯一不同的地方,就是這一行代碼,點對點創建的是Queue,而訂閱模式創建的是Topic
        destination = session.createTopic("topic-text");
        //=======================================================
        
        
        
        
        //從session中,獲取一個消息生產者
        producer = session.createProducer(destination);
        //設置生產者的模式,有兩種可選
        //DeliveryMode.PERSISTENT 當activemq關閉的時候,隊列數據將會被保存
        //DeliveryMode.NON_PERSISTENT 當activemq關閉的時候,隊列裏面的數據將會被清空
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        
        //創建一條消息,當然,消息的類型有很多,如文字,字節,對象等,可以通過session.create..方法來創建出來
        TextMessage textMsg = session.createTextMessage("哈哈");
        long s = System.currentTimeMillis();
        for(int i = 0 ; i < 100 ; i ++){
            //發送一條消息
            producer.send(textMsg);
        }
        long e = System.currentTimeMillis();
        System.out.println("發送消息成功");
        System.out.println(e - s);
        //即便生產者的對象關閉了,程序還在運行哦
                producer.close();
                
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
}

2.2訂閱模式的接收方

package com.itsiji.test.topic;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;
public class TestTopicReceive {

    //連接賬號
    private String userName = "";
    //連接密碼
    private String password = "";
    //連接地址
    private String brokerURL = "tcp://127.0.0.1:61616";
    //connection的工廠
    private ConnectionFactory factory;
    //連接對象
    private Connection connection;
    //一個操作會話
    private Session session;
    //目的地,其實就是連接到哪個隊列,如果是點對點,那麼它的實現是Queue,如果是訂閱模式,那它的實現是Topic
    private Destination destination;
    //生產者,就是產生數據的對象
    private MessageProducer producer;
    
    public static void main(String[] args) {
        TestTopicReceive send = new TestTopicReceive();
        send.start();
    }
    
    public void start(){
        try {
            //根據用戶名,密碼,url創建一個連接工廠
            factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
            //從工廠中獲取一個連接
            connection = factory.createConnection();
            //測試過這個步驟不寫也是可以的,但是網上的各個文檔都寫了
            connection.start();
            //創建一個session
            //第一個參數:是否支持事務,如果爲true,則會忽略第二個參數,被jms服務器設置爲SESSION_TRANSACTED
            //第二個參數爲false時,paramB的值可爲Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一個。
            //Session.AUTO_ACKNOWLEDGE爲自動確認,客戶端發送和接收消息不需要做額外的工作。哪怕是接收端發生異常,也會被當作正常發送成功。
            //Session.CLIENT_ACKNOWLEDGE爲客戶端確認。客戶端接收到消息後,必須調用javax.jms.Message的acknowledge方法。jms服務器纔會當作發送成功,並刪除消息。
            //DUPS_OK_ACKNOWLEDGE允許副本的確認模式。一旦接收方應用程序的方法調用從處理消息處返回,會話對象就會確認消息的接收;而且允許重複確認。
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            //創建一個到達的目的地,其實想一下就知道了,activemq不可能同時只能跑一個隊列吧,這裏就是連接了一個名爲"text-msg"的隊列,這個會話將會到這個隊列,當然,如果這個隊列不存在,將會被創建
            
            
            
            //=======================================================
            //點對點與訂閱模式唯一不同的地方,就是這一行代碼,點對點創建的是Queue,而訂閱模式創建的是Topic
            destination = session.createTopic("topic-text");
            //=======================================================
            
            
            
            
            //從session中,獲取一個消息生產者
            producer = session.createProducer(destination);
            //設置生產者的模式,有兩種可選
            //DeliveryMode.PERSISTENT 當activemq關閉的時候,隊列數據將會被保存
            //DeliveryMode.NON_PERSISTENT 當activemq關閉的時候,隊列裏面的數據將會被清空
            producer.setDeliveryMode(DeliveryMode.PERSISTENT);
            
            //創建一條消息,當然,消息的類型有很多,如文字,字節,對象等,可以通過session.create..方法來創建出來
            TextMessage textMsg = session.createTextMessage("哈哈");
            long s = System.currentTimeMillis();
            for(int i = 0 ; i < 100 ; i ++){
                //發送一條消息
                textMsg.setText("哈哈" + i);
                producer.send(textMsg);
            }
            long e = System.currentTimeMillis();
            System.out.println("發送消息成功");
            System.out.println(e - s);
            //即便生產者的對象關閉了,程序還在運行哦
            producer.close();
            
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
	
}

3.發送消息的數據類型

javax.jms.Message 這個接口,只要是這個接口的數據,都可以被髮送

//純字符串的數據
session.createTextMessage();
//序列化的對象
session.createObjectMessage();
//流,可以用來傳遞文件等
session.createStreamMessage();
 //用來傳遞字節
session.createBytesMessage();
//這個方法創建出來的就是一個map,可以把它當作map來用,當你看了它的一些方法,你就懂了
session.createMapMessage();
//這個方法,拿到的是javax.jms.Message,是所有message的接口
session.createMessage();

 

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