通過 ActiveMQ 演示如何使用 JMS API

出處:http://www.oschina.net/question/12_57749#tags_nav


消息機制是軟件組件和應用程序之間通訊的一種方法,一個消息系統是一個點對點的服務:消息客戶端可以發送消息也可以接收消息,每一個客戶端連接到一個消息代理,這個代理提供了消息的創建、發送、接收和讀取的功能。

因爲是鬆散耦合的架構使得消息機制很適合用在分佈式通訊。組件將消息發送到目的地,而接收者從目的地獲取所發送的消息。但是不要求發送者和接收者都同時有效。事實上,發送者不需要知道接收者的信息,而接收者也不知道了解發送者信息。發送者和接收者唯一需要一致的是消息的格式,以及使用哪個目標地址。消息機制跟一些緊耦合的技術例如 RMI 遠程方法調用是完全不同的,因爲 RMI 必須知道遠端應用所提供的方法。

點對點消息域

一個點對點 (PTP) 的產品或者應用是基於消息隊列、發送者和接收者的概念來構建的。每個消息被定爲到一個特定的隊列,接收者從隊列中提取發送給它的消息,隊列將保留所有的消息直到消息被取走或者過期。

JMS

每個消息只有唯一一個接收者(消費者)

  • 消息的發送者和接收者沒有時間上的依賴,接收者可在消息過期前的任意時間內去獲取消息,而不一定得發送者是在線的
  • 接收者需要確認成功的處理了消息
  • 使用 PTP 消息機制可確保一個消息只有一個接收者

發佈/訂閱消息域

publishSubscribe

在一個基於發佈/訂閱模型的應用或者產品中,客戶端根據主題來訂閱消息,有點像公告牌。發佈者和訂閱者一般都是匿名的,而且可以動態的發佈或者訂閱內容。消息系統會謹慎處理消息的分發到訂閱了某個主題的所有訂閱者,消息只會發送給當前訂閱者,然後就失效,新的訂閱者無法接收到剛剛失效的消息。

發佈和訂閱的消息機制具有以下特徵:

  • 每個消息可以有多個消費者
  • 發佈者和訂閱者是有時間依賴,只有當前訂閱了某個主題的訂閱者才能收到消息,訂閱者必須保持活躍以獲取消息

當一個消息可能會有多於1個的接收者是,請使用發佈/訂閱消息機制。

接下來我們使用 ActionMQ 來簡單演示消息的發送和接收。

首先下載 ActiveMQ for windows (HERE)

下載後解壓到任意目錄,然後執行 apache-activemq-5.5.1\bin 目錄下的 activemq 程序。

運行的提示信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
.............
 
.............
 
-0:1) started
 INFO | jetty-7.1.6.v20100715
 INFO | ActiveMQ WebConsole initialized.
 INFO | Initializing Spring FrameworkServlet 'dispatcher'
 INFO | ActiveMQ Console at http://0.0.0.0:8161/admin
 INFO | ActiveMQ Web Demos at http://0.0.0.0:8161/demo
 INFO | RESTful file access application at http://0.0.0.0:8161/fileserver
 INFO | Started [email protected]:8161

這樣 ActiveMQ 服務器就已經啓動成功了,你可以按 Ctrl+C 來關閉它,但先別急,因爲我們馬上要寫一些程序來做測試。ActiveMQ 提供一個很不錯的管理控制檯,你可以在瀏覽器上打開 http://localhost:8161/admin/ 來訪問它。

這裏是發送消息的代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import javax.jms.*;
 
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
 
public class Producer {
    // URL of the JMS server. DEFAULT_BROKER_URL will just mean
    // that JMS server is on localhost
    private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;
 
    // Name of the queue we will be sending messages to
    private static String procon = "QUEUETOTEST";
 
    public static void main(String[] args) throws JMSException {
        // Getting JMS connection from the server and starting it
        ConnectionFactory connectionFactory =
            new ActiveMQConnectionFactory(url);
        Connection connection = connectionFactory.createConnection();
        connection.start();
 
        // JMS messages are sent and received using a Session. We will
        // create here a non-transactional session object. If you want
        // to use transactions you should set the first parameter to 'true'
        Session session = connection.createSession(false,
            Session.AUTO_ACKNOWLEDGE);
 
        // Destination represents here our queue 'QUEUETOTEST' on the
        // JMS server. You don't have to do anything special on the
        // server to create it, it will be created automatically.
        Destination destination = session.createQueue(procon);
 
        // MessageProducer is used for sending messages (as opposed
        // to MessageConsumer which is used for receiving them)
        MessageProducer producer = session.createProducer(destination);
 
        // We will send a small text message
        TextMessage message = session.createTextMessage("I am First Message");
 
        // Here we are sending the message!
        producer.send(message);
        System.out.println("Sent message '" + message.getText() + "'" + " On Queue - "+ procon);
 
        connection.close();
    }
}

下面是 Consumer 類的代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import javax.jms.*;
 
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
 
public class Consumer {
    // URL of the JMS server
    private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;
 
    // Name of the queue we will receive messages from
    private static String procon = "QUEUETOTEST";
 
    public static void main(String[] args) throws JMSException {
        // Getting JMS connection from the server
        ConnectionFactory connectionFactory
            = new ActiveMQConnectionFactory(url);
        Connection connection = connectionFactory.createConnection();
        connection.start();
 
        // Creating session for sending messages
        Session session = connection.createSession(false,
            Session.AUTO_ACKNOWLEDGE);
 
        // Getting the queue 'QUEUETOTEST'
        Destination destination = session.createQueue(procon);
 
        // MessageConsumer is used for receiving (consuming) messages
        MessageConsumer consumer = session.createConsumer(destination);
 
        // Here we receive the message.
        // By default this call is blocking, which means it will wait
        // for a message to arrive on the queue.
        Message message = consumer.receive();
 
        // There are many types of Message and TextMessage
        // is just one of them. Producer sent us a TextMessage
        // so we must cast to it to get access to its .getText()
        // method.
        if (message instanceof TextMessage) {
            TextMessage textMessage = (TextMessage) message;
            System.out.println("Received message '"
                + textMessage.getText() + "'" + " On Queue - "+ procon);
        }
        connection.close();
    }
}

你可以在 ActiveMQ 的管理控制檯 http://localhost:8161/admin/queues.jsp 中看到在 QUEUETOTEST 的隊列中有一個消息。

首先運行上面的 Producer 程序,我們可以看到如下輸出:

JMS producer

JMS producer

然後運行 Consumer 程序,輸出如下:

jms consumer

consumer

現在運行 Consumer 程序,將會在 Queues 中得到如下結果:

consumer_first

consumer_first

Java Message Service (JMS) API 是 Java EE 平臺上用於處理消息的標準。

如果你想了解更多關於 JMS 技術,可以訪問 JMS Tutorial on Sun’s webpage.

英文原文OSCHINA原創翻譯

發佈了46 篇原創文章 · 獲贊 23 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章