ActiveMQ 三

第三章:ActiveMQ例子

本章內容

·         介紹本書每一個示例

·         使用Maven來編譯和運行這些例子

·         怎樣使用這些例子與ActiveMQ進行交互

ActiveMQ提供JMS規範要求的所有特性並且在這之上,提供了很多有用的特性。這些都在圖3.1裏描繪出來,並在本書剩下章節討論。爲了說明這些特性,我們提供了兩個例子,這兩個例子都是從真實商用領域得來的。相比前面的例子,這些例子更完整和簡潔地展示ActiveMQ的特性。

其中一個例子是基於股票投資的,另一個例子是基於工作隊列。這兩個例子比ActiveMQ自帶的例子更廣泛地展現ActiveMQ。我們先介紹這些例子的使用場景,接着詳細討論如何使用它們。在你閱讀這本書的任何時候,如果你需要回顧這些例子,你都可以回來閱讀這一章。

    股票投資例子演示了發佈/訂閱到消息傳送領域。發佈者向許多對該消息感興趣的訂閱者廣播消息。消息發佈到一個叫做主題的JMS目標,在線的訂閱者客戶端則接收消息。通過這種方式,代理器向每一個訂閱者發送消息而不用訂閱者去拉消息。每一個在線的訂閱者接收到一條消息的副本。除非使用持久訂閱,否則訂閱者必須在線等待接收消息。在一個主題中,將使用發佈/訂閱模式將消息的副本發送給每一個訂閱者。

    工作隊列例子演示裏點對點消息傳送領域。消息生產者發送消息到一個JMS隊列,接收者則從這個隊列接收消息。在點對點領域,消息的發送者和接收者沒有時序性要求。隊列會保存消息直到消費者準備好接收它們。如果消費者準備好,消息將發送給所有消費者,但是不會有兩個或以上消費者接收到同一條消息。在點對點領域,隊列裏的消息通過循環方式發送到消費者。

    不只是不同例子關注的消息傳送領域不同,它們對應的使用場景也不同。另外,雖然接下來的例子看起來差不多,但是它們有一個很重要的不同就是應用於不同的消息傳送領域。股票投資使用發佈/訂閱消息傳送,而工作隊列使用點對點的消息傳送。這些例子的代碼可以從Manning網站下載,URLhttp://manning.com/snyder/activemq-in-action-examples-src.zip

    在這一章,首先我們會下載Maven並安裝它,然後用它來編譯和運行示例。之後,我們將回顧每一個例子並解釋每一個例子的行爲。在完成這些練習後,你將對這些例子有足夠的瞭解可以在本書的其它部分認出它們,並且看看它們是如何被用來演示ActiveMQ特性。

 

3.1 下載Maven並編譯例子

下面是下載和安裝Maven的步驟:

1.    Apache Sofeware Foundation下載MavenURLhttp://maven.apache.org/Maven提供tarzip包,依據你操作系統選擇不同的包。

2.    在你的計算機上將壓縮包解壓到一個永久路徑。

3.    創建一個環境變量M2_HOME,並讓它指向Maven目錄

4.    Unix上,將$M2_HOME/bin目錄添加到環境變量(在Windows上,將$M2_HOME/bin目錄添加到%PATH%變量裏)

5.    通過運行如下命令確認Maven正確安裝。

         $ mvn -version
         Apache Maven 2.2.1 (r801777; 2009-08-06 13:16:01-0600)
         Java version: 1.5.0_19
         Java home: /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home
         Default locale: en_US, platform encoding: MacRoman
         OS name: "mac os x" version: "10.6.2" arch: "i386" Family: "unix"

         如果Maven正確安裝,你將看到與上面相似的輸出。如果沒看到相似輸出,你必須先使它正確再進入下一步。你  

         可以在下面的地址獲取更多關於安裝Maven的說明.http://maven.apache.org/download.html#Installation

 

你必須有因特網連接

要使用這些例子,你必須有因特網連接。因爲Maven必須爲這些例子下載必須的依賴包。

 

如果你已經成功安裝Maven,現在必須解壓和編譯這些例子了。在把包含源代碼的例子解壓後,你就可以編譯了。現在移動到amq-in-action-example-src目錄,然後運行下面的命令。爲了將命令與輸出區分開,下面的命令將用粗體字顯示。

[amq-in-action-example-src] $ mvn clean install 
[INFO] Scanning for projects...
[INFO] -------------------------------------------------------------------
-----
[INFO] Building ActiveMQ in Action Examples
[INFO] task-segment: [clean, install]
[INFO] -------------------------------------------------------------------
-----
Downloading: http://localhost:8081/nexus/content/groups/public/org/apache/
maven/plugins/maven-clean-plugin/2.2/maven-clean-plugin-2.2.pom
3K downloaded (maven-clean-plugin-2.2.pom)
...
[INFO] [install:install {execution: default-install}]
[INFO] Installing /private/tmp/amq-in-action-example-src/target/
activemq-in-action-examples.jar to /Users/bsnyder/.m2/repository/org/
apache/activemq/book/activemq-in-action-examples/1.0-SNAPSHOT/

activemq-in-action-examples-1.0-SNAPSHOT.jar
[INFO] Installing /private/tmp/amq-in-action-example-src/target/
activemq-in-action-examples-src.zip to /Users/bsnyder/.m2/repository/org/
apache/activemq/book/activemq-in-action-examples/1.0-SNAPSHOT/
activemq-in-action-examples-1.0-SNAPSHOT-src.zip
[INFO] -------------------------------------------------------------------
-----
[INFO] BUILD SUCCESSFUL
[INFO] -------------------------------------------------------------------
-----
[INFO] Total time: 57 seconds
[INFO] Finished at: Fri Dec 04 22:35:57 MST 2009
[INFO] Final Memory: 24M/44M
[INFO] -------------------------------------------------------------------
-----

由於輸出信息太多,上面省略了一些。上面的信息說明了編譯成功。當你看到BUILD SUCCESSFUL信息的時候,你就可以進入下面的學習了。如果你看到BUILD FAILURE,你必須找出出錯原因並且解決後才能進入下一步。

3.2用例一:股票投資例子

就像之前提到的,我們第一個用例是使用股票投資的例子來展示發佈/訂閱的消息傳送機制。這個例子使用一個Publisher類來發送一條股票價格消息到一個主題,同時,註冊了ListenerConsumer類用異步方式從主題消費消息。這三個類體現瞭如何產生不停變換的股票消息併發送到被消費者訂閱到主題上。

    在這個例子中,股票價格被髮布的任意數量的主題上。主題的數量是由命令行攜帶給發佈者和消費者的參數數量決定的。每一個類會動態地向/從主題發送或接收消息。圖3.23.3在一個高層次上展示了這些例子要達到的目的。

    爲了這個演示,兩個主題將被使用。Publisher類使用一個單獨的JMS MessageProducer以每次10條的方式去發送1000虛擬的股票消息,並隨機地發送到由命令行參數所指明的各個主題上。發送完1000條消息,它將被關閉。Consumer類對每個主題都創建了一個MessageConsumer並且註冊一個JMS MessageListener。因爲這個例子是演示發佈/訂閱消息的,所以消費者必須在線消費消息(這個例子不使用持久訂閱。)。下一步是真正地運行這個例子,這樣你就能看到它們的動作了。

3.2.1運行股票投資例子

運行例子有以下步驟:

1.    啓動ActiveMQ

2.    運行Consumer

3.    運行Publisher

這些步驟看起來很簡單。要注意的是,Consumer類必須比Publisher類先啓動,這樣它才能接收到所有的消息。這是因爲這個例子是用來演示發佈/訂閱消息模式的,所以主題並不會爲客戶端保存消息(我們沒有用持久訂閱)。現在讓我們開始這個例子吧。

    首先,我們要打開一個終端或者命令行來運行ActiveMQ。這個只需一條命令,如下所示:

Listing 3.2 Start up ActiveMQ

[apache-activemq-5.4.1] $ ./bin/activemq console 
INFO: Using default configuration
(you can configure options in one of these file:
/etc/default/activemq /Users/bsnyder/.activemqrc)
INFO: Invoke the following command to create a configuration file
./bin/activemq setup [/etc/default/activemq | /Users/bsnyder/.activemqrc]
INFO: Using java
'/System/Library/Frameworks/JavaVM.framework/Home/bin/java'
INFO: Starting in foreground, this is just for debugging purposes
(stop process by pressing CTRL+C)
Java Runtime: Apple Inc. 1.6.0_20
/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home
Heap sizes: current=258880k free=253105k max=258880k
JVM args: -Xms256M -Xmx256M

-Dorg.apache.activemq.UseDedicatedTaskRunner=true
-Djava.util.logging.config.file=logging.properties
-Dcom.sun.management.jmxremote
-Dactivemq.classpath=/Users/bsnyder/amq/apache-activemq-5.4.1/conf;
-Dactivemq.home=/Users/bsnyder/amq/apache-activemq-5.4.1
-Dactivemq.base=/Users/bsnyder/amq/apache-activemq-5.4.1
ACTIVEMQ_HOME: /Users/bsnyder/amq/apache-activemq-5.4.1
ACTIVEMQ_BASE: /Users/bsnyder/amq/apache-activemq-5.4.1
Loading message broker from: xbean:activemq.xml
...
INFO | Started [email protected]:8161

 

下一個任務是打開第二個終端(或命令行)來運行Consumer類。我們使用maven-exec-plugin來運行Consumer類。使用這個plugin時我們通過exec.args屬性來傳遞一些系統參數。運行Consumer的例子如下:

Listing 3.3 Run the stock portfolio consumer

[amq-in-action-example-src] $ mvn exec:java \ -
Dexec.mainClass=org.apache.activemq.book.ch3.portfolio.Consumer \ -
Dexec.args="CSCO ORCL"
 
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'exec'.
[INFO] org.apache.maven.plugins: checking for updates from central
[INFO] org.codehaus.mojo: checking for updates from central
[INFO] artifact org.codehaus.mojo:exec-maven-plugin: checking for
updates from central
[INFO] snapshot org.codehaus.mojo:exec-maven-plugin:1.1.2-SNAPSHOT:
checking for updates from public-snapshots
[INFO] snapshot org.codehaus.mojo:exec-maven-plugin:1.1.2-SNAPSHOT:
checking for updates from central
Downloading:
http://localhost:8081/nexus/content/groups/public/org/codehaus/mojo/
exec-maven-plugin/1.1.2-SNAPSHOT/
exec-maven-plugin-1.1.2-20091120.114446-3.pom
4K downloaded (exec-maven-plugin-1.1.2-20091120.114446-3.pom)
Downloading:
http://localhost:8081/nexus/content/groups/public/org/codehaus/mojo/
mojo-parent/22/mojo-parent-22.pom
18K downloaded (mojo-parent-22.pom)
Downloading:
http://localhost:8081/nexus/content/groups/public-snapshots/org/codehaus/
mojo/exec-maven-plugin/1.1.2-SNAPSHOT/
exec-maven-plugin-1.1.2-20091120.114446-3.jar
36K downloaded (exec-maven-plugin-1.1.2-20091120.114446-3.jar)
[INFO] -------------------------------------------------------------------
-----
[INFO] Building ActiveMQ in Action Examples
[INFO] task-segment: [exec:java]
[INFO] -------------------------------------------------------------------
-----
[INFO] Preparing exec:java
[INFO] No goals needed for project - skipping

[WARNING] POM for 'woodstox:wstx-asl:pom:3.2.7:compile' is invalid.
Its dependencies (if any) will NOT be available to the current build.
Downloading:
http://localhost:8081/nexus/content/groups/public/org/apache/commons/
commons-exec/1.0.1/commons-exec-1.0.1.pom
7K downloaded (commons-exec-1.0.1.pom)
Downloading:
http://localhost:8081/nexus/content/groups/public/org/apache/commons/
commons-exec/1.0.1/commons-exec-1.0.1.jar
48K downloaded (commons-exec-1.0.1.jar)
[INFO] [exec:java {execution: default-cli}]

 

在列表3.3你可以看到Maven下載了一些運行例子必須的組件。當Consumer啓動完畢,我們就可以啓動Publisher並開始發送股票消息到兩個有命令行參數指定的目標CSCOORCL。這兩個名字是隨機取的,你可以改爲其它任意字符串。重要的是ConsumerPublisher必須使用相同的參數。

運行Consumer時構建錯誤

當你運行Consumer類時,如果你看到BUILD ERROR,那麼你必須先編譯源代碼,然後再運行它。下面的命令可以用來編譯源代碼:$ mvn clean install    這個命令編譯並打包源代碼。之後你可以用原先的命令來運行Consumer類了。

注意,現在輸出已經停了,看起來就像Consumer掛起來。這是正常的,因爲它正在等待消息。當Publisher開始發送消息,Consumer就會開始消費它們。

 

在輸出窗口爲什麼看到所有的組件都是從本地下載?

3.1接如果Maven正確安裝,那麼它會下載運行例子所需要所有組件。在第一個輸出窗口你可以看到它在下載組件。注意到所有的組件都是從本地下載而不是從遠程Maven庫下載。這是因爲這些例子已經被配置爲使用一個叫做Nexus的位於本地計算機的Maven庫。Nexus提供很多好處,其中一個是它可以作爲遠程Maven庫的代理緩存所有已下載組件。在Maven第一次下載組件後,它們都被保存到本地緩存裏。如果多次編譯,Nexus從本地緩存提供組件,這加快了編譯速度。更多關於Nexus的消息請看:http://nexus.sonatype.org/

 

接下來我們打開第三個終端來運行Publisher類。注意在exec.args中必須使用與原來運行Consumer相同的參數,因爲maven-exec-plugin也會用這些參數來運行Publisher。下面是運行Publisher的例子。

Listing 3.4 Running the stock portfolio publisher

[amq-in-action-example-src] $ mvn exec:java \
-Dexec.mainClass=org.apache.activemq.book.ch3.portfolio.Publisher \
-Dexec.args="CSCO ORCL"
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'exec'.
[INFO] -------------------------------------------------------------------
-----
[INFO] Building ActiveMQ in Action Examples
[INFO] task-segment: [exec:java]
[INFO] -------------------------------------------------------------------
-----
[INFO] Preparing exec:java
[INFO] No goals needed for project - skipping
[WARNING] POM for 'woodstox:wstx-asl:pom:3.2.7:compile' is invalid.
Its dependencies (if any) will NOT be available to the current build.
[INFO] [exec:java {execution: default-cli}]
Sending: {offer=62.6861410176471, price=62.62351750014696, up=true,
stock=ORCL} on destination: topic://STOCKS.ORCL
Sending: {offer=55.508573596887715, price=55.45312047641131, up=true,
stock=CSCO} on destination: topic://STOCKS.CSCO
Sending: {offer=62.527946513790205, price=62.46548103275745, up=false,
stock=ORCL} on destination: topic://STOCKS.ORCL
Sending: {offer=55.78778713074073, price=55.73205507566507, up=true,
stock=CSCO} on destination: topic://STOCKS.CSCO
Sending: {offer=55.593918646251986, price=55.53838026598601, up=false,
stock=CSCO} on destination: topic://STOCKS.CSCO
Sending: {offer=55.83360390719586, price=55.777826081114746, up=true,
stock=CSCO} on destination: topic://STOCKS.CSCO
Sending: {offer=55.99233608275527, price=55.93639968307221, up=true,
stock=CSCO} on destination: topic://STOCKS.CSCO
Sending: {offer=62.006501598331475, price=61.94455704129019, up=false,
stock=ORCL} on destination: topic://STOCKS.ORCL
Sending: {offer=55.53698948617822, price=55.48150797820003, up=false,
stock=CSCO} on destination: topic://STOCKS.CSCO
Sending: {offer=61.43866500377897, price=61.377287716062916, up=false,
stock=ORCL} on destination: topic://STOCKS.ORCL
Published '10' of '10' price messages
Sending: {offer=55.466945358331216, price=55.41153382450671, up=false,
stock=CSCO} on destination: topic://STOCKS.CSCO
Sending: {offer=61.27694222131968, price=61.215726494824864, up=false,
stock=ORCL} on destination: topic://STOCKS.ORCL
...
Published '10' of '30' price messages
...

 

運行Publisher時,由於Maven在之前運行Consumer時已經下載了所有的依賴組件,所以無需再下載了。在輸出窗口下半部分可以看到,股票價格消息每10條一組發送到了兩個主題。由於輸出太多,部分沒有顯示在上面,但是要知道Publisher將會一直運行直到發送完1000條消息。

    運行完Publisher,現在切換到第二個終端,你可以看到Consumer正在從主題上消費消息。

...
[INFO] [exec:java {execution: default-cli}]
ORCL 62.62 62.69 up
CSCO 55.45 55.51 up
ORCL 62.47 62.53 down
CSCO 55.73 55.79 up
CSCO 55.94 55.99 up
CSCO 55.41 55.47 down
ORCL 61.22 61.28 down
ORCL 61.42 61.48 up
...

輸出的前綴是註冊到ORCLCSCO主題上的監聽器打印出來的。這個輸出說明了現在正在消費由Publisher發送到兩個主題的消息。當Publisher發送我1000條消息後,它將被關閉。但是Consumer仍會繼續運行並掛起等待更多的消息。你可以在第二個終端按CTRL-C來關閉Consumer

    現在你已經看到ActiveMQ怎樣以發佈/訂閱模式運行,下一節將展示它如何以點對點消息傳送方式運行。

3.3用例二:工作隊列

第二個例子通過工作隊列來演示點對點的消息傳送。這個例子使用Producer類來向工作隊列發送消息,而註冊了ListenerConsumer類則用異步的方式從隊列消費消息。這3個類展示了基本的JMS點對點消息傳送是如何工作的。這些類和上一個例子很相似,區別就是用在不同的消息傳送領域。

    Producer類發送消息到JOBS.suspendJOBS.delete隊列,Consumer則消費它們。圖3.3在一個高層次描述了這個過程。

Producer使用一個單獨的MessageProducer來發送1000條工作消息,每次10條,隨機地發送到兩個隊列。發完1000條消息後關閉。Consumer類對每一個隊列使用一個MessageConsumer並註冊一個JMS MessageListener來使用消息並輸出相關信息。

 

3.3.1 運行工作隊列例子

運行工作隊列的步驟幾乎和前一個例子的步驟一樣:

1.    啓動ActiveMQ

2.    運行Producer

3.    運行Consumer

這些步驟都很簡單,但有一個地方要注意。我們現在使用的是點對點消息傳送,隊列會保存消息直到它們被消費或者過期。所以即使Produce先於Consumer啓動,Consumer也不會錯失任何消息。

    就像股票投資例子一樣,第一個步驟是啓動ActiveMQ。這個步驟就不再詳述了,因爲它和之前完全一樣。

    接上來,打開第二個終端或命令行窗口來運行Producer

Listing 3.5 Running the job queue publisher

[amq-in-action-example-src] $ mvn exec:java \
-Dexec.mainClass=org.apache.activemq.book.ch3.jobs.Publisher
 
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'exec'.
[INFO] -------------------------------------------------------------------
-----
[INFO] Building ActiveMQ in Action Examples
[INFO] task-segment: [exec:java]
[INFO] -------------------------------------------------------------------
-----
[INFO] Preparing exec:java
[INFO] No goals needed for project - skipping
[WARNING] POM for 'woodstox:wstx-asl:pom:3.2.7:compile' is invalid.

Its dependencies (if any) will NOT be available to the current build.
[INFO] [exec:java {execution: default-cli}]
Sending: id: 1000000 on queue: queue://JOBS.delete
Sending: id: 1000001 on queue: queue://JOBS.delete
Sending: id: 1000002 on queue: queue://JOBS.delete
Sending: id: 1000003 on queue: queue://JOBS.delete
Sending: id: 1000004 on queue: queue://JOBS.delete
Sending: id: 1000005 on queue: queue://JOBS.delete
Sending: id: 1000006 on queue: queue://JOBS.delete
Sending: id: 1000007 on queue: queue://JOBS.delete
Sending: id: 1000008 on queue: queue://JOBS.delete
Sending: id: 1000009 on queue: queue://JOBS.delete
Published '10' of '10' job messages
Sending: id: 1000010 on queue: queue://JOBS.delete
Sending: id: 1000011 on queue: queue://JOBS.suspend
...
Published '10' of '30' job messages
...

 

注意運行Producer時並不需要傳遞任何參數。Publisher類包含了兩個隊列deletesuspend。這清楚地顯示在輸出內容上。Producer會發送1000條消息然後關閉。

    接下來的任務是打開另一個終端或命令行窗口來運行ConsumerConsumer會從兩個隊列消費消息。這個命令如下:

Listing 3.6 Running the job queue consumer

[amq-in-action-example-src] $ mvn exec:java \
-Dexec.mainClass=org.apache.activemq.book.ch3.jobs.Consumer
 
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'exec'.
[INFO] -------------------------------------------------------------------
-----
[INFO] Building ActiveMQ in Action Examples
[INFO] task-segment: [exec:java]
[INFO] -------------------------------------------------------------------
-----
[INFO] Preparing exec:java
[INFO] No goals needed for project - skipping
[WARNING] POM for 'woodstox:wstx-asl:pom:3.2.7:compile' is invalid.
Its dependencies (if any) will NOT be available to the current build.
[INFO] [exec:java {execution: default-cli}]
suspend id:1000003
suspend id:1000010
suspend id:1000012
suspend id:1000013
suspend id:1000015
suspend id:1000022
suspend id:1000025
suspend id:1000027
delete id:1000000
delete id:1000001

delete id:1000002
delete id:1000004
delete id:1000005
...

 

一開始,Consumer會運行得很快,消費完隊列裏所有的消息。當它趕上Producer時,Consumer開始慢下來,然後和Producer同步,直到Producer發送完1000條消息。當所有的消息發送完後,Producer自動終止,而Consumer不會,你需要在第三個終端上按CTRL-C來停止它。

    工作隊列的例子結束了。現在你看到了ActiveMQ是如何以點對點消息傳送方式工作的。

 

3.4總結

對本書例子的簡單介紹的目的在於--快速和專注。工作和投資的例子在商業領域是很常見的,但這只是消息傳送領域大量例子中的兩個。雖然這兩個例子只是在一個較高層次演示了兩種消息傳送領域,但它們還有其它作用。通過使用ActiveMQ提供的特性,這兩個例子將在本書剩下部分被修改。所以你會經常看到這兩個例子,不過稍有不同而已。

    本書的第一部分(13章)先向你介紹了ActiveMQ,使你對ActiveMQ有一個高層次的理解。接下來是關注面向消息中間件和JMS規範。雖然這些主題不只是與ActiveMQ有關,但對於理解ActiveMQ很有幫助。你也看了一些例子,這些例子將在整本書中使用。第一部分的內容是掌握ActiveMQ的熱身,第二部分你將學會對ActiveMQ的連接,持久化,安全等各個方面進行配置。

第二部分:配置標準ActiveMQ組件

使用ActiveMQ看起來很簡單直接:啓動它,發送消息,接收消息。但是你沒有看到隱藏在這些步驟後面的細節。理解這些細節和自定義配置需要更多的例子來說明。雖然ActiveMQ提供了大量的配置選項,但是理解一些核心的選項對於大多數應用是很必要的。

    第二部分深入到ActiveMQ關鍵的配置選項,包括連接,消息持久化,安全。這三個主題是你使用ActiveMQ最先遇到的問題,所以率先理解它們很重要。
發佈了41 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章