(九)JMS的兩種訊息模型(Point-to-Point(P2P)和Publish/Subscribe(Pub/Sub))應用舉例
在P2P模型中,有下列概念:訊息佇列(Queue)、傳送者(Sender)、接收者(Receiver)。每個訊息都被髮送到一個特定的佇列,接收者從佇列中獲取訊息。佇列保留著訊息,直到它們被消費或超時。
每個訊息只有一個消費者(Consumer)(即一旦被消費,訊息就不再在訊息佇列中)
傳送者和接收者之間在時間上沒有依賴性,也就是說當傳送者傳送了訊息之後,不管接收者有沒有正在執行,它不會影響到訊息被髮送到佇列。
接收者在成功接收訊息之後需向佇列應答成功
如果你希望傳送的每個訊息都應該被成功處理的話,那麼你需要P2P模型。
舉例:
//註冊訊息監聽器,當有訊息傳送過來的時候會呼叫onMessage方法(實現MessageListener 介面)
Java程式碼
- import javax.ejb.ActivationConfigProperty;
- import javax.ejb.MessageDriven;
- import javax.jms.JMSException;
- import javax.jms.Message;
- import javax.jms.MessageListener;
- import javax.jms.TextMessage;
- @MessageDriven(activationConfig={
-
@ActivationConfigProperty(propertyName=
- @ActivationConfigProperty(propertyName="destination", propertyValue="queue/myqueue")
- }
- )
- publicclass QueueMessageBean implements MessageListener {
- publicvoid onMessage(Message msg) {
- //共有下面幾種訊息型別
- //1 Text
-
//2 Map
- //3 Object
- //4 stream
- //5 byte
- TextMessage txtMsg = (TextMessage)msg;
- String s = "";
- try {
- s = txtMsg.getText();
- } catch (JMSException e) {
- e.printStackTrace();
- }
- System.out.println("QueueMessageBean接收到了訊息:" + s);
- }
- }
- //客戶端呼叫
- import javax.jms.Message;
- import javax.jms.MessageProducer;
- import javax.jms.Queue;
- import javax.jms.QueueConnection;
- import javax.jms.QueueConnectionFactory;
- import javax.jms.QueueSession;
- import javax.naming.InitialContext;
- publicclass Test {
- publicstaticvoid main(String[] args) throws Exception {
- InitialContext ctx = new InitialContext();
- //獲得QueueConnectionFactory物件
- QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("QueueConnectionFactory");
- //建立QueueConnection對像
- QueueConnection connection = factory.createQueueConnection();
- //建立會話
- //arg1:與事物有關,true表示最後提交,false表示自動提交
- //arg2:表示訊息向中介軟體傳送確認通知,這裡採用的是自動通知的型別
- QueueSession session = (QueueSession) connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
- //取得destination
- Queue queue = (Queue) ctx.lookup("queue/myqueue");
- //訊息生產者
- MessageProducer sender = session.createProducer(queue);
- //定義訊息
- Message msg = session.createTextMessage("訊息來了");
- //傳送訊息
- sender.send(queue, msg);
- session.close();
- connection.close();
- }
- }
2、Pub/Sub模式
在Pub/Sub模型中,有下列概念: 主題(Topic)、釋出者(Publisher)、訂閱者(Subscriber)。客戶端將訊息傳送到主題。多個釋出者將訊息傳送到Topic,系統將這些訊息傳遞給多個訂閱者。
每個訊息可以有多個消費者
釋出者和訂閱者之間有時間上的依賴性。針對某個主題(Topic)的訂閱者,它必須建立一個訂閱之後,才能消費釋出者的訊息,而且,為了消費訊息,訂閱者必須保持執行的狀態。
當然,為了緩和這種嚴格的時間相關性,JMS允許訂閱者建立一個可持久化的訂閱。這樣,即使訂閱者沒有被啟用(執行),它也能接收到釋出者的訊息。
如果你希望傳送的訊息可以不被做任何處理、或者被一個消費者處理、或者可以被多個消費者處理的話,那麼可以採用Pub/Sub模型。
//註冊訊息監聽器,當有訊息傳送過來的時候會呼叫onMessage方法(實現MessageListener 介面)
Java程式碼
- import javax.ejb.ActivationConfigProperty;
- import javax.ejb.MessageDriven;
- import javax.jms.JMSException;
- import javax.jms.Message;
- import javax.jms.MessageListener;
- import javax.jms.TextMessage;
- @MessageDriven(activationConfig={
- @ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Topic"),
- @ActivationConfigProperty(propertyName="destination", propertyValue="topic/myTopic")
- }
- )
- publicclass TopicMessageBean implements MessageListener {
- publicvoid onMessage(Message msg) {
- //共有下面幾種訊息型別
- //1 Text
- //2 Map
- //3 Object
- //4 stream
- //5 byte
- TextMessage txtMsg = (TextMessage)msg;
- String s = "";
- try {
- s = txtMsg.getText();
- } catch (JMSException e) {
- e.printStackTrace();
- }
- System.out.println("TopicMessageBean接收到了訊息:" + s);
- }
- }
- //客戶端測試
- import javax.jms.MessageProducer;
- import javax.jms.Topic;
- import javax.jms.TopicConnection;
- import javax.jms.TopicConnectionFactory;
- import javax.jms.TopicSession;
- import javax.naming.InitialContext;
- publicclass Test {
- publicstaticvoid main(String[] args) throws Exception {
- InitialContext ctx = new InitialContext();
- //獲得QueueConnectionFactory物件
- TopicConnectionFactory factory = (TopicConnectionFactory) ctx.lookup("TopicConnectionFactory");
- //建立QueueConnection對像
- TopicConnection connection = factory.createTopicConnection();
- //建立會話
- //arg1:與事物有關,true表示最後提交,false表示自動提交
- //arg2:表示訊息向中介軟體傳送確認通知,這裡採用的是自動通知的型別
- TopicSession session = (TopicSession) connection.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);
- //取得destination
- Topic queue = (Topic) ctx.lookup("topic/myTopic");
- //訊息生產者
- MessageProducer publisher = session.createProducer(queue);
- //定義訊息
- Message msg = session.createTextMessage("訊息來了");
- //傳送訊息
- publisher.send(queue, msg);
- session.close();
- connection.close();
- }
- }
二種模型的實現結果:對於p2p模型的每個訊息只能有一個消費者 如果我們定義二個訊息接受者的Bean那麼只能有一端會接收到訊息。當你把部署在Jboss中的訊息接收Bean去掉以後,然後傳送訊息 此時訊息在佇列中,一旦你重新部署他會立刻就接收到剛剛傳送的訊息所以它沒有時間的依賴性, pub/sub模型可以有多個消費者 在這個模型中如果我們定義多個接收訊息的Bean當我們在客戶端傳送訊息的時候二個bean都會接收到訊息,所以他有多個消費者 但是如果你把Jboss部署中的訊息接收bean去掉之後,傳送訊息。然後在重新部署,那麼訊息也無法接收到,所以說他有時間的依賴性。
//程式碼中幾個概念的理解
Connection Factory
建立Connection物件的工廠,針對兩種不同的JMS訊息模型,分別有QueueConnectionFactory和TopicConnectionFactory兩種。可以通過JNDI來查詢ConnectionFactory物件。
Destination
Destination的意思是訊息生產者的訊息傳送目標或者說訊息消費者的訊息來源。對於訊息生產者來說,它的Destination是某個佇列(Queue)或某個主題(Topic);對於訊息消費者來說,它的Destination也是某個佇列或主題(即訊息來源)。
所以,Destination實際上就是兩種型別的物件:Queue、Topic。
可以通過JNDI來查詢Destination。
Connection:
Connection表示在客戶端和JMS系統之間建立的連結(對TCP/IP socket的包裝)。Connection可以產生一個或多個Session。跟ConnectionFactory一樣,Connection也有兩種型別:QueueConnection和TopicConnection。
Session:
Session是我們操作訊息的介面。可以通過session建立生產者、消費者、訊息等。Session提供了事務的功能。當我們需要使用session傳送/接收多個訊息時,可以將這些傳送/接收動作放到一個事務中。同樣,也分QueueSession和TopicSession。
訊息生產者:
訊息生產者由Session建立,並用於將訊息傳送到Destination。同樣,訊息生產者分兩種型別:QueueSender和TopicPublisher。可以呼叫訊息生產者的方法(send或publish方法)傳送訊息!
訊息消費者:
訊息消費者由Session建立,用於接收被髮送到Destination的訊息。兩種型別:QueueReceiver和TopicSubscriber。可分別通過session的createReceiver(Queue)或createSubscriber(Topic)來建立。當然,也可以通過session的createDurableSubscriber方法來建立持久化的訂閱者。
MessageListener:
訊息監聽器。如果註冊了訊息監聽器,一旦訊息到達,將自動呼叫監聽器的onMessage方法。EJB中的MDB(Message-Driven Bean)就是一種MessageListener。
MDB介紹:
對客戶端來說,message-driven bean就是非同步訊息的消費者。當訊息到達之後,由容器負責呼叫MDB。客戶端傳送訊息到destination,MDB作為一個MessageListener接收訊息。
相關推薦
JMS兩種訊息模型
前段時間學習EJB,接觸到了JMS(Java訊息服務),JMS支援兩種訊息模型:Point-to-Point(P2P)和Publish/Subscribe(Pub/Sub),即點對點和釋出訂閱
(九)JMS的兩種訊息模型(Point-to-Point(P2P)和Publish/Subscribe(Pub/Sub))應用舉例
1、P2P模型在P2P模型中,有下列概念:訊息佇列(Queue)、傳送者(Sender)、接收者(Receiver)。每個訊息都被髮送到一個特定的佇列,接收者從佇列中獲取訊息。佇列保留著訊息,直到它們被消費或超時。 每個訊息只有一個消費者(Consumer)(即一旦被消費
主題:JMS的兩種訊息模型(Point-to-Point(P2P)和Publish/Subscribe(Pub/Sub))應用舉例...
1、P2P模型 在P2P模型中,有下列概念:訊息佇列(Queue)、傳送者(Sender)、接收者(Receiver)。每個訊息都被髮送到一個特定的佇列,接收者從佇列中獲取訊息。佇列保留著訊息,直到它們被消費或超時。 每個訊息只有一個消費者(Consumer)(即一旦被消
兩種訊息模型: 點對點&&釋出/訂閱
點對點: 訊息生產者生產訊息傳送到queue中,然後訊息消費者從queue中取出並且消費訊息。這裡要注意: 訊息被消費以後,queue中不再有儲存,所以訊息消費者不可能消費到已經被消費的訊息。 Queue支援存在多個消費者,但是對一個訊息而言,只會有一個消費者可以消費。 釋出
DIV+CSS兩種盒子模型(W3C盒子與IE盒子)
在辨析兩種盒子模型之前,先簡單說明一下什麼叫盒子模型。 原理: 先說說我們在網頁設計中常聽的屬性名:內容(content)、填充(padding)、邊框(border)、邊界(margin), CSS盒子模式都具備這些屬性。 這些屬性我們可以把它轉移到我們日常生活中的盒子(
JMQ的兩種訊息模式(點對點訊息模式、訂閱模式)
一:JMQ的兩種訊息模式 訊息列隊有兩種訊息模式,一種是點對點的訊息模式,還有一種就是訂閱的模式. 1.1:點對點的訊息模式 點對點的模式主要建立在一個佇列上面,當連線一個列隊的時候,傳送端不需要知道接收端是否正在接收,可以直接向ActiveMQ傳送訊息,傳送的訊息,將
【轉】JMeter學習(二十九)使用Jmeter創建ActiveMQ JMS POINT TO POINT請求,環境搭建、請求創建、插件安裝、監聽服務器資源等
分布式 jndi 根目錄 point 啟動 lib .cn 轉載 p2p 最近要做公司消息中間件的性能測試,第一個想到的工具就是Jmeter了,網上簡單搜了一下,基本上都是WEB測試的居多,只好自己研究官方文檔了。 其中涉及Jmeter基本的術語或者概念,請自行參考官方文檔
(三)Redis兩種持久化方案
根據 edit 接受 lang app append size aps pen Redis的持久化策略:2種 RDB方式的持久化是通過快照(snapshotting)完成的,當符合一定條件時Redis會自動將內存中的數據進行快照並持久化到硬盤。RDB是Redis默認采用
MySQL關閉查詢緩存(QC)的兩種方法
from com 技術分享 兩種 查詢 data- 命中 sql語句 count MySQL Query Cache 會緩存select 查詢,安裝時默認是開啟的,但是如果對表進行INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE,
Python-資料結構與演算法(十一、字典(對映)——基於兩種不同的底層實現)
保證一週更兩篇吧,以此來督促自己好好的學習!程式碼的很多地方我都給予了詳細的解釋,幫助理解。好了,幹就完了~加油! 宣告:本python資料結構與演算法是imooc上liuyubobobo老師java資料結構的python改寫,並添加了一些自己的理解和新的東西,liuyubobobo
牛客網線上程式設計(13):兩種排序方法-python
題目描述 考拉有n個字串字串,任意兩個字串長度都是不同的。考拉最近學習到有兩種字串的排序方法: 1.根據字串的字典序排序。例如: "car" < "carriage" < "cats" < "doggies < "koala" 2.根據字串的長度排序。例如: "car
矩陣快速冪(共軛函式兩種遞推式)
題目連結:https://cn.vjudge.net/contest/261339#problem/B AC1:ans= x(n)+y(n)*sqrt(6),所以,ans=x(n)+y(n)*sqrt(6)+(x(n)-y(n)*sqrt(6))-(x(n)-y(n)*sqrt(6))=2*
線程(調用的兩種方法、全局變量共享、線程數量)
break %d span 兩種方法 全局變量 glob 導致 col 方法 1 # -*- coding:utf-8 -*- 2 # Author:Sure Feng 3 4 5 import threading 6 import time 7 8
java解析Excel(xls、xlsx兩種格式)
https://www.cnblogs.com/hhhshct/p/7255915.html ********************************************************** 一、需要匯入的jar 1.commons-collections4-4.
python中@符號兩種含義,1表示修飾符,2表示矩陣乘法(python3.5以後)
第一種,大家所熟知,表示修飾符,可以在模組或者類的定義層內對函式進行修飾。出現在函式定義的前一行,不允許和函式定義在同一行。在下面這種情況 def funcA(A): print("function A") print(A) def funcB(B): print(B(
c#呼叫python的四種方法(嘗試了四種,只詳細講解本人成功的後兩種,其餘方法只列出,詳細用法請自行谷歌百度)
一、使用c#,nuget管理包上下載的ironPython安裝包 嘗試後發現,對引用了numpy等第三方庫的python程式碼,會報找不到模組xxx的錯誤,上網查證後發現此問題基本難以解決 二、使用c++程式呼叫python檔案,然後將其做成動態連結庫
SQL Server中掃描(scan)和查詢(seek)這兩種演算法的區別
SQL SERVER使用掃描(scan)和查詢(seek)這兩種演算法從資料表和索引中讀取資料。這兩種演算法構成了查詢的基礎,幾乎無處不在。Scan會掃描並且返回整個表或整個索引。 而seek則更有效率,根據謂詞(predicate),只返索引內的一個或多個範圍內的資料。
兩種簡單的陣列排序演算法:氣泡排序和直接選擇排序(升序)
氣泡排序的基本思想是:面對一排資料,先從前往後兩兩比較,如果前一個數比後一個數大就交換兩者的順序,即第一個數和第二個數比,第二個數和第三個數比,……,倒數第二個數和最後一個數比,這樣一輪下來以後最大的數就排到最後;接著把除去最大的數的該組資料進行同樣的操作,直至
求平方根(根號n)的兩種演算法——二分法和牛頓迭代
面試阿里口碑的時候遇到了這個問題,這裡做個筆記1.二分法#define eps 0.00001 float SqrtByDichotomy(float n) { if (n < 0) { return -1.0; } else { float low,
SpringBoot學習(三),兩種啟動方式-以main方法啟動和在tomcat裡啟動
sprigboot既可以直接通過main方法啟動,也可以在tomcat裡啟動,在main方法裡啟動很簡單,直接run啟動類的main方法就可以了。 在tomcat裡啟動