JMS學習之理論基礎

来源:http://www.cnblogs.com/jalja/archive/2017/04/06/6651153.html
-Advertisement-
Play Games

JMS(Java Message Service,Java消息服務)是一組Java應用程式介面(Java API),它提供創建、發送、接收、讀取消息的服務。它給消息中間件生產商提供了一個統一API的標準。 ...


本文代碼使用ActiveMq5.6

一、什麼是JMS

JMS(Java Message Service,Java消息服務)是一組Java應用程式介面(Java API),它提供創建、發送、接收、讀取消息的服務。它給消息中間件生產商提供了一個統一API的標準。
第一個版本1998年,目前最新的2.0版本(2013年第一季度發佈)
JMS規範地址:
http://www.oracle.com/technetwork/java/docs-136352.html(1.1版本)
http://download.oracle.com/otndocs/jcp/jms-2_0-fr-eval-spec/index.html(2.0版本)

中間件:中間件是一種獨立的系統軟體或服務程式,分散式應用軟體藉助這種軟體在不同的技術之間共用資源。也就是應用程式A與應用程式B之間不是直接交互,而是通過中間件進行資源共用。

二、JMS消息模型

1、JMS元素

  • JMS provider:An implementation of the JMS interface for a Message Oriented Middleware (MOM)  面向消息中間件的JMS介面的實現

  • JMS client:An application or process that produces and/or receives messages. 產生和/或接收消息的應用程式或過程

  • JMS producer/publisher:A JMS client that creates and sends messages. 創建和發送消息的JMS客戶端。

  • JMS consumer/subscriber:A JMS client that receives messages. 接收消息的JMS客戶機。

  • JMS message(header/payload):An object that contains the data being transferred between JMS clients. 包含JMS客戶機之間傳輸數據的對象

  • JMS queue:A staging area that contains messages that have been sent and are waiting to be read. A JMS queue only guarantees that each message is processed only once.包含已發送並等待被讀取的消息的暫存區域。JMS隊列只保證每個消息只處理一次。

  • JMS topic:A distribution mechanism for publishing messages that are delivered to multiple subscribers. 發佈消息傳遞給多個訂閱伺服器的分發機制。

2、JMS消息模型

a、點對點的消息模型: 每個消息只能有一個消費者。

 

消息的生產者和消費者之間沒有時間上的相關性。無論消費者在生產者發送消息的時候是否處於運行狀態,它都可以提取消息。

b、發佈訂閱消息模型   每個消息可以有多個消費者

生產者和消費者之間有時間上的相關性。訂閱一個主題的消費者只能消費自它訂閱之後發佈的消息。JMS規範允許客戶創建持久訂閱,這在一定程度上放鬆了時間上的相關性要求。持久訂閱允許消費者消費它在未處於激活狀態時發送的消息。

三、JMS消息介面

JMS支持兩種消息類型P -to- P 和 Pub-Sub 這兩種消息類型都繼承統一介面JMS Parent,主要介面是

JMS Parent

P -to -P

Pub - Sub

ConnectionFactory

QueueConnectionFactory

TopicConnectionFactory

Connection

QueueConnection

TopicConnection

Destination

QueueDestination

TopicDestination

Session

QueueSession

TopicSession

MessageProducer

QueueSender

TopicPublisher

MessageConsumer

QueueReceiver

TopicSubscriber

1、介面描述:

ConnectionFactory:連接工廠,JMS創建連接的方式

Connection:JMS客戶端與JMS Provider的連接(通過ConnectionFactory創建的)。

Destination:消息的目的地

Session:一個接收或發送消息的一次回話

MessageProducer:由session對象創建的用於發送消息的對象

MessageConsumer:由session對象創建的用來接收消息的對象

2、JMS的創建流程

  • 創建ConnectionFactory工廠
  • 通過工廠創建Connection連接
  • 通過連接創建一個連接回話Session
  • 通過Session創建消息的生產者MessageProducer和消息的消費者MessageConsumer;同時Session也創建一個消息Mesage。
  • 消息的生產者MessageProducer將該消息發送到目的地中Destination;消費者同時監聽該消息目的地Destination。

P -to- P模型:

生產者:

package com.jalja.org.base.JMS;
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.ActiveMQConnectionFactory;
public class ProducerJMS {
    private static String url="http://localhost:8161";//ActiveMq的地址
    private static String queueName="queue-ch2";//創建一個隊列
    public static void main(String[] args) throws JMSException {
        //
        ConnectionFactory connFactory = new ActiveMQConnectionFactory();
        Connection conn = connFactory.createConnection();
        conn.start();//開啟連接
        //創建Session
        Session session = conn.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
        //創建一個p -to -P 類型的消息隊列(消息目的地)
        Destination des = session.createQueue(queueName);
        //將消息交給消息發送者
        MessageProducer producer = session.createProducer(des);
        //創建一個text類型的消息
        TextMessage msg  = session.createTextMessage();
        msg.setText("Hello World!");
        //將消息發送到消息隊列中
        producer.send(msg);
        //關閉資源
        session.close();
        conn.close();
    }
}

消費者

package com.jalja.org.base.JMS;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnectionFactory;
public class ConsumerA {
    private static String url = "tcp://localhost:8161";
    private static String queueName = "queue-ch2";
    public static void main(String[] args) throws Exception {
        ConnectionFactory connFactory = new ActiveMQConnectionFactory();
        Connection conn = connFactory.createConnection();
        conn.start();//啟動連接
        //創建Session
        Session session = conn.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
        //創建一個p -to -P 類型的消息隊列(消息目的地)
        Destination des = session.createQueue(queueName);
        //創建一個消息消費者 並指定其消費信息的目的地
        MessageConsumer consumer  = session.createConsumer(des);
        //監聽消息隊列
        Listener listener = new Listener();
        listener.setForm("ConsumerA");
        consumer.setMessageListener(listener);
        
    }
}

消息監聽器:

package com.jalja.org.base.JMS;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
public class Listener implements MessageListener {
    private String form = null;
    /**
     * 監聽消息隊列,如果該消息隊列有消息,該監聽器就可以獲取消息
     */
    @Override
    public void onMessage(Message message) {
        TextMessage msg  = (TextMessage)message;
        try {
            System.out.println(getForm() + ":" + msg.getText());
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
    public String getForm() {
        return form;
    }
    public void setForm(String form) {
        this.form = form;
    }

}

 

 Pub - Sub 模型

 

生產者:

package ch02.pubsub;

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.ActiveMQConnectionFactory;

/*
 * pubsub MQ生產者
 */
public class Publisher {
    private static String url = "tcp://localhost:8161";
    private static String topicName = "topic.ch02";
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        ConnectionFactory connFactory = new ActiveMQConnectionFactory();
        Connection conn = connFactory.createConnection();
        conn.start();
        Session session = conn.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
        Destination des = session.createTopic(topicName);
        MessageProducer publisher = session.createProducer(des);
        TextMessage msg  = session.createTextMessage();
        msg.setText("Hello World!");
        publisher.send(msg);
        session.close();
        conn.close();
    }
}

消費者:

package ch02.pubsub;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;

import org.apache.activemq.ActiveMQConnectionFactory;

/**
 * 
 * PTP 消費者A
 *
 */
public class SubscriberA {
    
    private static String url = "tcp://localhost:8161";
    private static String topicName = "topic.ch02";
    
    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        ConnectionFactory connFactory = new ActiveMQConnectionFactory();
        Connection conn = connFactory.createConnection();
        conn.start();
        Session session = conn.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
        Destination des = session.createTopic(topicName);
        MessageConsumer consumer  = session.createConsumer(des);
        Listener listener = new Listener();
        listener.setForm("SubscriberA");
        consumer.setMessageListener(listener);
        
    }

}

消息監聽器:

package ch02.pubsub;

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

public class Listener implements MessageListener {
    
    private String form = null;

    @Override
    public void onMessage(Message message) {
        TextMessage msg  = (TextMessage)message;
        try {
            System.out.println(getForm() + ":" + msg.getText());
        } catch (JMSException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public String getForm() {
        return form;
    }

    public void setForm(String form) {
        this.form = form;
    }

}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 如果大家研究一些開源項目,會發現無處不在的DI(Dependency Injection依賴註入)。 本篇文章將會詳細講述如何在MVC中使用Ninject實現DI 文章提綱 場景描述 & 問題引出 第一輪重構 引入Ninject 第二輪重構 總結 場景描述 & 問題引出 DI是一種實現組件解耦的設計 ...
  • 度娘許久,找不到我滿意的答案,於是自己東湊西湊實現一個。 DynamicObject擴展--實現JSON和DynamicObject的序列化與反序列化,親測良好。 看代碼 ...
  • 跨平臺系列彙總:http://www.cnblogs.com/dunitian/p/4822808.html#linux 上次說了安裝VSCode(http://www.cnblogs.com/dunitian/p/6661644.html)和sogou(http://www.cnblogs.com ...
  • 本章內容和大家分享的是Asp.NetCore組件寫法,在netcore中很多東西都以提供組件的方式來使用,比如MVC架構,Session,Cache,資料庫引用等; 這裡我也通過調用驗證碼介面來自定義個組件以此說明如何使用,以及使用時需要註意的場景; Middleware之hello world 對 ...
  • 對於WCF應用來說,傳輸前壓縮請求消息和回覆消息,不但可以降低網路流量,也可以提高網路傳輸的性能 一、消息壓縮方案 二、用於數據壓縮與解壓縮組件 三、用於消息壓縮與解壓的組件 四、用於對請求/回覆消息壓縮和解壓縮的組件 五、將CompressionMessageFormatter用於WCF運行時框架 ...
  • 最近接觸了用c#導出Excel文件的一些操作。 使用NPOI的優勢是,開源,操作靈活,不需要下載OFFICE軟體,速度快,不過聽說,數據量過大的時候,不是很好用,大概那都是幾兆的時候吧,不過目前用於我的需要,基本是夠了。 關於NPOI的基本操作:http://blog.csdn.net/pan_ju ...
  • DevExpress 是一個比較有名的界面控制項套件,提供了一系列優秀的界面控制項。這篇文章將展示如何在擁有源代碼的情況下,對 DevExpress 的程式集進行重新編譯。 系統必備 Windows 7 SP1 以上操作系統 Visual Studio 2010 SP1 .Net Framework 4 ...
  • 平時我們開發中,經常使用Task,後續的.net版本種很多都和Task有關,比如asyn,await有了Task 我們很少就去關註Thread 了。Task 給我們帶來了很多的便利之處。是我們更少的去關註執行的歷程,更多的去關註邏輯。但是有些時候,有些應用。又不得不考慮task 的運行狀況,比如這個 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...