jms activeMQ 應用

來源:互聯網
上載者:User

原帖::http://blog.163.com/zqy216_2008/blog/static/4119371820107253335260/

一、JMS的理解

JMS概述:

jms即JavaMessage Service(Java Message Service)應用程式介面是一個Java平台中關於面向訊息中介軟體(MOM)的API,用於在兩個應用程式之間,或分布式系統中發送訊息,進行非同步通訊。JavaMessage Service是一個與具體平台無關的API,絕大多數MOM供應商都對JMS提供支援。

JMS元素:

JMS有以下元素組成。

  JMS提供者

  串連面向訊息中介軟體的,JMS介面的一個實現。提供者可以是Java平台的JMS實現,也可以是非Java平台的面向訊息中介軟體的適配器

JMS客戶

  生產或消費訊息的基於Java的應用程式或對象。

JMS生產者

  建立並發送訊息的JMS客戶。

JMS消費者

  接收訊息的JMS客戶。

JMS訊息

  包括可以在JMS客戶之間傳遞的資料的對象

JMS隊列

  一個容納那些被發送的等待閱讀的訊息的地區。隊列暗示,這些訊息將按照順序發送。一旦一個訊息被閱讀,該訊息將被從隊列中移走。

JMS主題

  一種支援發送訊息給多個訂閱者的機制。

JMS模型:

JavaMessage Service應用程式結構支援兩種模型:

  點對點或隊列模型

  發行者/訂閱者模型

  在點對點或隊列模型下,一個生產者向一個特定的隊列發布訊息,一個消費者從該隊列中讀取訊息。這裡,生產者知道消費者的隊列,並直接將訊息發送到消費者的隊列。這種模式被概括為:

  只有一個消費者將獲得訊息

  生產者不需要在接收者消費該訊息期間處於運行狀態,接收者也同樣不需要在訊息發送時處於運行狀態。

  每一個成功處理的訊息都由接收者簽收

  發行者/訂閱者模型支援向一個特定的訊息主題發布訊息。0或多個訂閱者可能對接收來自特定訊息主題的訊息感興趣。在這種模型下,發行者和訂閱者彼此不知道對方。這種模式好比是匿名公告板。這種模式被概括為:

  多個消費者可以獲得訊息

  在發行者和訂閱者之間存在時間依賴性。發行者需要建立一個訂閱(subscription),以便客戶能夠購訂閱。訂閱者必須保持持續的活動狀態以接收訊息,除非訂閱者建立了持久的訂閱。在那種情況下,在訂閱者未串連時發布的訊息將在訂閱者重新串連時重新發布。

  使用Java語言,JMS提供了將應用與提供資料的傳輸層相分離的方式。同一組Java類可以通過JNDI中關於提供者的資訊,串連不同的JMS提供者。這一組類首先使用一個串連工廠以串連到隊列或主題,然後發送或發布訊息。在接收端,客戶接收或訂閱這些訊息。

二、        JMS的實現提供者(ActiveMQ):

1.windows版:

    A.在http://activemq.apache.org/ 官網上下載apache-activemq-5.3.0-bin.zip

    B.下載後解壓縮,執行bin檔案夾中的activemq.bat 將啟動預設配置的activemq

    C.通過http://localhost:8161/admin訪問activemq的管理介面。查看隊列(queue)和主題(topic)下的訊息內容。

2.linux版:

   A.在http://activemq.apache.org/ 官網上下載apache-activemq-5.3.0-bin.tar.gz

B.解壓

將下載下來的apache-activemq-5.3.0-bin.tar.gz放置於/usr/local
cd /usr/local/
tar xvfz apache-activemq-5.3.0-bin.tar.gz
則ActiveMQ的安裝目錄為:/usr/local/apache-activemq-5.3.0

C.修改activemq運行檔案的許可權
cd /usr/local/apache-activemq-5.2.0/bin
chmod 755 activemq

D.運行
(1).普通啟動
   bin/activemq
(2).指定記錄檔的啟動方式
   bin/activemq >/tmp/smlog 2>&1 &
(3)後台啟動方式
   nohup bin/activemq >/tmp/smlog 2>&1 &

這裡需要注意:前兩種啟動方式在linix命令列或者通過ssh用戶端啟動時在關閉對應的視窗時activemq會關閉,甚至直接ctrl+c也會導致activemq退出;第三種則不會出現這種情況。

E.驗證服務端是否開啟,有幾種方法
(1).查看控制台輸出或者記錄檔
(2).直接存取activemq的管理頁面:http://localhost:8161/admin/

F.關閉activemq
如果開啟方式是使用(1)或(2),則直接ctrl+c或者關閉對應的終端即可
如果開啟方式是(3),則稍微麻煩一點:
先尋找到activemq對應的進程:
ps -ef | grep activemq
然後把對應的進程殺掉,假設找到的進程編號為 168168
kill 168168

3.ActiveMQ的activemq.xml詳細配置講解

   <beans

xmlns="http://www.springframework.org/schema/beans"

xmlns:amq="http://activemq.org/config/1.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://activemq.org/config/1.0 http://activemq.apache.org/schema/activemq-core.xsd

http://activemq.apache.org/camel/schema/spring>

<!-- persistent="true"表示要持久化儲存訊息,和子項目persistenceAdapter結合使用 -->

<!-- dataDirectory預設的儲存持久化資料的目錄 -->

<!-- brokerName 設定broker的name,在注意在網路上必須是唯一的-->

<broker xmlns="http://activemq.org/config/1.0" brokerName="192.168.1.148" persistent ="true" dataDirectory="${activemq.base}/data" useShutdownHook="false">

<!-- Destination specific policies using destination names or wildcards -->

<!-- wildcards意義見http://activemq.apache.org/wildcards.html -->

<destinationPolicy>

<policyMap>

<policyEntries>

<!-- 這裡使用了wildcards,表示所有以EUCITA開頭的topic -->

<policyEntry topic="EUCITA.>" producerFlowControl="false" memoryLimit="10mb">

<!-- 分發策略 -->

<dispatchPolicy>

<!-- 按順序分發 -->

<strictOrderDispatchPolicy/>

</dispatchPolicy>

<!--  恢複策略-->

<subscriptionRecoveryPolicy>

<!-- 只恢複最後一個message -->

<lastImageSubscriptionRecoveryPolicy/>

</subscriptionRecoveryPolicy>

</policyEntry>

</policyEntries>

</policyMap>

</destinationPolicy>

<!-- The transport connectors ActiveMQ will listen to -->

<transportConnectors>

<transportConnector name="openwire" uri="tcp://192.168.1.148:61616" discoveryUri="multicast://default"/>

<transportConnector name="ssl"     uri="ssl://192.168.1.148:61617"/>

<transportConnector name="stomp"   uri="stomp://192.168.1.148:61613"/>

<transportConnector name="xmpp"    uri="xmpp://192.168.1.148:61222"/>

</transportConnectors>

<!-- 訊息持久化方式 -->

<persistenceAdapter>

<amqPersistenceAdapter directory="${activemq.base}/data"/>

</persistenceAdapter>

</broker>

<!-- lets create a command agent to respond to message based admin commands on the ActiveMQ.Agent topic -->

<commandAgent xmlns="http://activemq.org/config/1.0"/>

<!-- An embedded servlet engine for serving up the Admin console -->

<jetty xmlns="http://mortbay.com/schemas/jetty/1.0">

<connectors>

<nioConnector port="8161" />

</connectors>

<handlers>

<webAppContext contextPath="/admin" resourceBase="${activemq.base}/webapps/admin" logUrlOnStart="true" />

<webAppContext contextPath="/demo" resourceBase="${activemq.base}/webapps/demo" logUrlOnStart="true" />

</handlers>

</jetty>

</beans>

4.ActiveMQ的安全驗證配置

ActiveMQ的安全性,主要表現在兩個方面,一個是它的JMS服務的安全性,一個是它的管理主控台的安全性。在預設情況下,ActiveMQ在這兩個方面都是沒有配置安全性的。

JMS服務安全性

A.如果沒有配置JMS服務的安全性,任何連入網路的人,只要知道ActiveMQ伺服器的具體地址(包括IP地址,連接埠,訊息地址[隊列或者主題地址]),就可以肆無忌憚的發送、接收訊息。那麼要解決JMS服務的安全性,最關鍵的問題就是解決身份認證的問題。

1)增加plugin

<plugins>

    <!--use JAAS to authenticate using the login.config file on the classpath to configure JAAS -->

    <jaasAuthenticationPlugin configuration="activemq-domain" />

    <!--  lets configure a destination based authorization mechanism -->

    <authorizationPlugin>

        <map>

            <authorizationMap>

                <authorizationEntries>

                    <authorizationEntry queue=">" read="admins" write="admins" admin="admins" />

                    <authorizationEntry topic=">" read="admins" write="admins" admin="admins" />

                    <authorizationEntry queue="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins" />

                    <authorizationEntry topic="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins" />

                </authorizationEntries>

            </authorizationMap>

        </map>

    </authorizationPlugin>

</plugins>

2)在conf中增加login.config檔案,內容如下:

    activemq-domain {

        org.apache.activemq.jaas.PropertiesLoginModule required

        debug=true

        org.apache.activemq.jaas.properties.user="users.properties"

        org.apache.activemq.jaas.properties.group="groups.properties";

    };

3)在conf中增加groups.properties檔案,內容如下:

   admins=system

4)在conf中增加users.properties檔案,內容如下:

   system=manager

管理主控台安全性

  ActiveMQ預設的管理是通過內建的jetty伺服器,只要在瀏覽器中輸入http://localhost:8161/admin,不需要登入,就可以對隊列、主題及訊息等進行管理,可以想象這非常不安全。那麼要解決管理主控台的安全性,除了通過修改管理連接埠號碼以及應用程式名稱之外,最關鍵的也是需要進行配置,必須通過身份認證才能登入。本文要說的方式主要是在不改變內建jetty的方式下,通過配置基本認證的方式來實現安全登入。

1)在activemq.xml中增加realm設定

   <userRealms>

       <jaasUserRealm name="adminRealm" loginModuleName="adminLoginModule">

      </jaasUserRealm>

   </userRealms>

2)修改login.config檔案,參考上面已見的login.config檔案

   adminLoginModule {

       org.mortbay.jetty.plus.jaas.spi.PropertyFileLoginModule required

       debug="true"

       file="C:/software/apache-activemq-5.2.0/conf/realm.properties";

   };

3)在lib/web中增加jetty-plus-6.1.9.jar;

4)在conf中增加realm.properties檔案

    system: MD5:1d0258c2440a8d19e716292b231e3190,admins

注意,上面是使用者名稱為system,而密碼為manager,如果使用者密碼不一致,請根據如下命令獲得相關資訊

java -cp jetty-6.1.9.jar;jetty-util-6.1.9.jar org.mortbay.jetty.security.Password system manager

5)修改webapps/admin/WEB-INF/web.xml

   <security-constraint>

       <web-resource-collection>

           <web-resource-name>adminRealm</web-resource-name>

           <url-pattern>/*</url-pattern>

       </web-resource-collection>

       <auth-constraint>

           <role-name>admins</role-name>

       </auth-constraint>

   </security-constraint>

   <login-config>

       <auth-method>BASIC</auth-method>

       <realm-name>adminRealm</realm-name>

   </login-config>

 

總結

經過如上配置後,必須通過使用者安全驗證才能串連上Message Service器並進行訊息發送和接收。當訪問http://localhost:8161/admin/時,將會快顯視窗以讓使用者輸入登入帳號和密碼。特別說明一下,ActiveMQ跟安全相關的有三個地方,分別是上面說的Message Service器本身的身份認證、Web Console的身份認證,還有一個地方是通過Web Console訪問Message Service器的身份認證,也就是conf/credentials.properties,檔案內容如下:

       activemq.username=system

       activemq.password=manager

這三個地方的使用者名稱密碼最好一致,尤其是credentials.properties中的帳號與users.properties中的管理員帳號必須一致。

 

三、        JMS的應用:

1.   JMS應用程式介面

ConnectionFactory 介面(串連工廠)
  使用者用來建立到JMS提供者的串連的被管對象。JMS客戶通過可移植的介面訪問串連,這樣當下層的實現改變時,代碼不需要進行修改。 管理員在JNDI名字空間中配置串連工廠,這樣,JMS客戶才能夠尋找到它們。根據訊息類型的不同,使用者將使用隊列串連工廠,或者主題串連工廠。

Connection 介面(串連)
  串連代表了應用程式和Message Service器之間的通訊鏈路。在獲得了串連工廠後,就可以建立一個與JMS提供者的串連。根據不同的連線類型,串連允許使用者建立會話,以發送和接收隊列和主題到目標。

Destination 介面(目標)
  目標是一個封裝了訊息目標標識符的被管對象,訊息目標是指訊息發布和接收的地點,或者是隊列,或者是主題。JMS管理員建立這些對象,然後使用者通過JNDI發現它們。和串連工廠一樣,管理員可以建立兩種類型的目標,點對點模型的隊列,以及發行者/訂閱者模型的主題。

MessageConsumer 介面(訊息消費者)
  由會話建立的對象,用於接收發送到目標的訊息。消費者可以同步地(阻塞模式),或非同步(非阻塞)接收隊列和主題類型的訊息。

MessageProducer 介面(訊息生產者)
  由會話建立的對象,用於發送訊息到目標。使用者可以建立某個目標的寄件者,也可以建立一個通用的寄件者,在發送訊息時指定目標。

Message 介面(訊息)
  是在消費者和生產者之間傳送的對象,也就是說從一個應用程式創送到另一個應用程式。一個訊息有三個主要部分:

     訊息頭(必須):包含用於識別和為訊息尋找路由的操作設定。

     一組訊息屬性(可選):包含額外的屬性,支援其他提供者和使用者的相容。可以建立定製的欄位和過濾器(訊息選取器)。

     一個訊息體(可選):允許使用者建立五種類型的訊息(簡訊,映射訊息,位元組訊息,流訊息和對象訊息)。

  訊息介面非常靈活,並提供了許多方式來定製訊息的內容。

Session 介面(會話)
  表示一個單線程的上下文,用於發送和接收訊息。由於會話是單線程的,所以訊息是連續的,就是說訊息是按照發送的順序一個一個接收的。會話的好處是它支援事務。如果使用者選擇了事務支援,會話上下文將儲存一組訊息,直到事務被提交才發送這些訊息。在提交事務之前,使用者可以使用復原操作取消這些訊息。一個會話允許使用者建立訊息生產者來發送訊息,建立訊息消費者來接收訊息。

 

四、        JMS封裝介面的應用:

 

    (以下是自己封裝的介面)

Jms訊息管理類:JmsServiceManager.java

1.   public void  sendTextMessage (SmsConfig config1,String content)

是發送 “一般字元串訊息,包含一個String”的方法

參數說明:

A.String content  :要發送的一般字元串訊息

B.SmsConfig config1 :是配置jms發送環境的bean類(常用的參數如下:)

                    1)/*訊息的transacted模式*/ 

         private boolean transacted = false;

//jms事務要用到  預設是false  是否啟用本地事務

                        2) /**

                            * 傳遞模式, 有兩種模式: PERSISTENT(true) 和

                            * NON_PERSISTENT(false)

                            * 訊息的發送模式:persistent或nonpersistent。

                            * 前者表示訊息在被消費之前,如果JMS提供者DOWN了,

                            * 重新啟動後訊息仍然存在。

                            * 後者在這種情況下表示訊息會被丟失。

                            * */

                private boolean durable = false;  //預設是false

                       3) /**

                            * 訊息池d名字

                            * 發送訊息的目的地

                            * */

               private String subject = "TOOL.DEFAULT";  

//預設是TOOL.DEFAULT  

4) /**

                           * 串連url

                           * URL的值為"failover:(tcp://localhost:61616)",

                           * 其中failover關鍵字表示用戶端與ActiveMQ Server的

                           * 串連中斷後(如ActiveMQ Server重新啟動),

                           * 用戶端會自動重新串連,不需要在我們的代碼中處理了。

                          * */

                       private String url = "failover:(tcp://localhost:61616)";       //預設是failover:(tcp://localhost:61616)

5)    /**

                          * 發送訊息或接收訊息時使用的使用者名稱

                          * */

                          private String pwd = "system";   

//預設是system

   

                      6) /**

                           * 發送訊息或接收訊息時使用的密碼

                           * */

private String user = "manager";  

//預設是manager

7) /**

                           * 點對點傳輸模式或訂閱模式 true 訂閱模式,false 點對點模式

                           * */

private boolean topic = false;   //預設是false

8)/**

                         * 表示一個訊息的有效期間。只有在這個有效期間內,

*訊息消費者才可以消費這個訊息。

                         * 預設值為0,表示訊息永不到期。

                         * 可以通過下面的方式設定:有效期間1小時 (1000毫秒 * 60秒 * 60分)

                         * */

private long timeToLive = 0; //預設值為0,表示訊息永不到期。

9)/**

                         * 表示接收到訊息後返回的目的地

                         * */

private String replyTo = ""; 

//預設值為空白,表示接收到訊息不返回。

2.  public void sendObjectMessage(SmsConfig config1,Object object)

是發送 “對象訊息,包含一個可序列化的Java 對象”的方法

參數說明:

Object object : 是繼承了com.jms.tool. ActionBean

     SmsConfig config1 : 和 1 方法中的參數是一樣的

3.   public void sessionCommit()

//提交事務

4.  public void closeSessionAndConnection()

//關閉會話和串連

5.  public void sessionRollback()

//交易回復

6.  public void reciveMessage(SmsConfig config1)

是發送 “接受監聽資訊”的方法

參數說明:

SmsConfig config1 : 和 1 方法中的參數是一樣的

 

Jms訊息接受處理類:JmsReciveAction.java

1.  public static void actionObjectMessage(Object object)

是“接受監聽資訊(對象訊息)”的處理方法

參數說明:

Object object : 是接收到的訊息對象

2.  public static String actionTextMessage(String content)

是“接受監聽資訊(String訊息)”的處理方法

參數說明:

String content : 是接收到的String訊息

並返回處理後的結果。(如果沒有返回結果可以返回Null 字元串””)

 

     調用Jms介面例子:

         1.發送”String訊息”

public static void senderText(){

               JmsServiceManager jmsManager = new JmsServiceManager();

SmsConfig config = new SmsConfig();//jms環境配置bean

               config.setTopic(false); //是 點對點 還是 發布訂閱 發送模式

               config.setDurable(true);

               config.setSubject("127.0.0.1"); //訊息發送目的地

               config.setTransacted(true);//是否啟用本地事務

               config.setUrl("failover:(tcp://localhost:61616)");

               //如果ActiveMQ設定了安全驗證 還需要設定使用者名稱和密碼

               config.setUser("system");

               config.setPwd("manager");

        try{

             jmsManager.sendTextMessage(config, "我是中國人,我愛我的祖國");                      jmsManager.sessionCommit(); //提交事務

        }catch (Exception e) {

             e.printStackTrace();

             jmsManager.sessionRollback();//交易回復

        }finally{

             jmsManager.closeSessionAndConnection(); //關閉會話和串連

        }

  }

 註:如果config.setTransacted(false);//是否啟用本地事務 則不用提交事務

 

2.接收訊息 

          public static void reciverText(){

              JmsServiceManager jmsManager = new JmsServiceManager();

             SmsConfig config = new SmsConfig();

             config.setTopic(false);

             //config.setDurable(true);

           config.setSubject("127.0.0.1"); //訊息接收目的地

             config.setUrl("failover:(tcp://localhost:61616)");

              //如果ActiveMQ設定了安全驗證 還需要設定使用者名稱和密碼

              config.setUser("system");

              config.setPwd("manager");

             jmsManager.reciveMessage(config);

         }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.