ActiveMQ 生產者和消費者demo
生產者程式碼
package org.mule.util.ansyLog; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.jms.Connection; import javax.jms.DeliveryMode; import javax.jms.Destination; import javax.jms.ExceptionListener; import javax.jms.JMSException; import javax.jms.MapMessage; import javax.jms.Message; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.ActiveMQSession; import org.apache.activemq.pool.PooledConnectionFactory; /** * JMS訊息生產者 * @author * java學習交流:737251827 進入可領取學習資源及對十年開發經驗大佬提問,免費解答! */ public class JMSProducer implements ExceptionListener{ //設定連線的最大連線數 public final static int DEFAULT_MAX_CONNECTIONS=5; private int maxConnections = DEFAULT_MAX_CONNECTIONS; //設定每個連線中使用的最大活動會話數 private int maximumActiveSessionPerConnection = DEFAULT_MAXIMUM_ACTIVE_SESSION_PER_CONNECTION; public final static int DEFAULT_MAXIMUM_ACTIVE_SESSION_PER_CONNECTION=300; //執行緒池數量 private int threadPoolSize = DEFAULT_THREAD_POOL_SIZE; public final static int DEFAULT_THREAD_POOL_SIZE=50; //強制使用同步返回資料的格式 private boolean useAsyncSendForJMS = DEFAULT_USE_ASYNC_SEND_FOR_JMS; public final static boolean DEFAULT_USE_ASYNC_SEND_FOR_JMS=true; //是否持久化訊息 private boolean isPersistent = DEFAULT_IS_PERSISTENT; public final static boolean DEFAULT_IS_PERSISTENT=true; //連線地址 private String brokerUrl; private String userName; private String password; private ExecutorService threadPool; private PooledConnectionFactory connectionFactory; public JMSProducer(String brokerUrl, String userName, String password) { this(brokerUrl, userName, password, DEFAULT_MAX_CONNECTIONS, DEFAULT_MAXIMUM_ACTIVE_SESSION_PER_CONNECTION, DEFAULT_THREAD_POOL_SIZE, DEFAULT_USE_ASYNC_SEND_FOR_JMS, DEFAULT_IS_PERSISTENT); } public JMSProducer(String brokerUrl, String userName, String password, int maxConnections, int maximumActiveSessionPerConnection, int threadPoolSize,boolean useAsyncSendForJMS, boolean isPersistent) { this.useAsyncSendForJMS = useAsyncSendForJMS; this.isPersistent = isPersistent; this.brokerUrl = brokerUrl; this.userName = userName; this.password = password; this.maxConnections = maxConnections; this.maximumActiveSessionPerConnection = maximumActiveSessionPerConnection; this.threadPoolSize = threadPoolSize; init(); } private void init() { //設定JAVA執行緒池 this.threadPool = Executors.newFixedThreadPool(this.threadPoolSize); //ActiveMQ的連線工廠 ActiveMQConnectionFactory actualConnectionFactory = new ActiveMQConnectionFactory(this.userName, this.password, this.brokerUrl); actualConnectionFactory.setUseAsyncSend(this.useAsyncSendForJMS); //Active中的連線池工廠 this.connectionFactory = new PooledConnectionFactory(actualConnectionFactory); this.connectionFactory.setCreateConnectionOnStartup(true); this.connectionFactory.setMaxConnections(this.maxConnections); this.connectionFactory.setMaximumActiveSessionPerConnection(this.maximumActiveSessionPerConnection); } /** * 執行傳送訊息的具體方法 * @param queue * @param map */ public void send(final String queue, final Map<String, Object> map) { //直接使用執行緒池來執行具體的呼叫 this.threadPool.execute(new Runnable(){ @Override public void run() { try { sendMsg(queue,map); } catch (Exception e) { e.printStackTrace(); } } }); } /** * 執行傳送訊息的具體方法 * @param queue * @param map */ public void send(final String queue, final String message) { //直接使用執行緒池來執行具體的呼叫 this.threadPool.execute(new Runnable(){ @Override public void run() { try { sendMsg(queue,message); } catch (Exception e) { e.printStackTrace(); } } }); } /** * 真正的執行訊息傳送 * @param queue * @param map * @throws Exception */ private void sendMsg(String queue, String msg) throws Exception { Connection connection = null; Session session = null; try { //從連線池工廠中獲取一個連線 connection = this.connectionFactory.createConnection(); /*createSession(boolean transacted,int acknowledgeMode) transacted - indicates whether the session is transacted acknowledgeMode - indicates whether the consumer or the client will acknowledge any messages it receives; ignored if the session is transacted. Legal values are Session.AUTO_ACKNOWLEDGE, Session.CLIENT_ACKNOWLEDGE, and Session.DUPS_OK_ACKNOWLEDGE. */ //false 參數列示 為非事務型訊息,後面的參數列示訊息的確認型別 // session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); session = connection.createSession(Boolean.TRUE, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE); //true 開啟事務,需要客戶端確認 // session = connection.createSession(Boolean.TRUE, Session.CLIENT_ACKNOWLEDGE); //Destination is superinterface of Queue //PTP訊息方式 Destination destination = session.createQueue(queue); //Creates a MessageProducer to send messages to the specified destination MessageProducer producer = session.createProducer(destination); //set delevery mode producer.setDeliveryMode(this.isPersistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT); //map convert to javax message TextMessage message = session.createTextMessage(msg); producer.send(message); session.commit(); } finally { closeSession(session); closeConnection(connection); } } /** * 真正的執行訊息傳送 * @param queue * @param map * @throws Exception * java學習交流:737251827 進入可領取學習資源及對十年開發經驗大佬提問,免費解答! */ private void sendMsg(String queue, Map<String, Object> map) throws Exception { Connection connection = null; Session session = null; try { //從連線池工廠中獲取一個連線 connection = this.connectionFactory.createConnection(); //false 參數列示 為非事務型訊息,後面的參數列示訊息的確認型別 session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); //PTP訊息方式 Destination destination = session.createQueue(queue); //Creates a MessageProducer to send messages to the specified destination MessageProducer producer = session.createProducer(destination); //set delevery mode producer.setDeliveryMode(this.isPersistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT); //map convert to javax message Message message = getMessage(session, map); producer.send(message); } finally { closeSession(session); closeConnection(connection); } } private Message getMessage(Session session, Map<String, Object> map) throws JMSException { MapMessage message = session.createMapMessage(); if (map != null && !map.isEmpty()) { Set<String> keys = map.keySet(); for (String key : keys) { message.setObject(key, map.get(key)); } } return message; } private void closeSession(Session session) { try { if (session != null) { session.close(); } } catch (Exception e) { e.printStackTrace(); } } private void closeConnection(Connection connection) { try { if (connection != null) { connection.close(); } } catch (Exception e) { e.printStackTrace(); } } @Override public void onException(JMSException e) { e.printStackTrace(); }
消費者程式碼,這裡只貼出main方法裡的內容
// ConnectionFactory :連線工廠,JMS 用它建立連線 ConnectionFactory connectionFactory; // Connection :JMS 客戶端到JMS Provider 的連線 // Connection connection = null; // Session: 一個傳送或接收訊息的執行緒 Session session; // Destination :訊息的目的地;訊息傳送給誰. Destination destination; // 消費者,訊息接收者 MessageConsumer consumer = null; connectionFactory = new ActiveMQConnectionFactory( USERNAME,PASSWORD,ACTIVE_URL); try { // 構造從工廠得到連線物件 connection = connectionFactory.createConnection(); // 啟動 connection.start(); // 獲取操作連線 session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 獲取session注意引數值xingbo.xu-queue是一個伺服器的queue,須在在ActiveMq的console配置 destination = session.createQueue(QUEUE_NAME_LOG); consumer = session.createConsumer(destination); while (true) { TextMessage message = (TextMessage) consumer.receive(); if (null != message) { System.out.println("--------------------"+message.getText()); JSONObject json = (JSONObject) JSON.parse(message.getText()); //儲存到資料庫 System.out.println(json.getString("inPro")); message.acknowledge(); } else { break; } } } catch (Exception e) { e.printStackTrace();
這裡是基於queue的,支援事務,並且持久化的。
JMS訊息確認機制
JMS訊息只有在被確認之後,才認為已經被成功地消費了。訊息的成功消費通常包含三個階段:客戶接收訊息、客戶處理訊息和訊息被確認。在事務性會話中,當一個事務被提交的時候,確認自動發生。在非事務性會話中,訊息何時被確認取決於建立會話時的應答模式(acknowledgement mode)。該引數有以下三個可選值:
Session.AUTO_ACKNOWLEDGE。當客戶成功的從receive方法返回的時候,或者從MessageListener.onMessage方法成功返回的時候,會話自動確認客戶收到的訊息。
Session.CLIENT_ACKNOWLEDGE。 客戶通過訊息的acknowledge方法確認訊息。需要注意的是,在這種模式中,確認是在會話層上進行:確認一個被消費的訊息將自動確認所有已被會話消 費的訊息。例如,如果一個訊息消費者消費了10個訊息,然後確認第5個訊息,那麼所有10個訊息都被確認。
Session.DUPS_ACKNOWLEDGE。 該選擇只是會話遲鈍第確認訊息的提交。如果JMS provider失敗,那麼可能會導致一些重複的訊息。如果是重複的訊息,那麼JMS provider必須把訊息頭的JMSRedelivered欄位設定為true。
ActiveMQ訊息確認機制
ActiveMQSession,實現了JMS的session,QueueSession, TopicSession
ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE 每條訊息都必須顯式呼叫acknowledge方法確認訊息。
訊息永續性
JMS 支援以下兩種訊息提交模式:
DeliveryMode.PERSISTENT 指示JMS provider持久儲存訊息,以保證訊息不會因為JMS provider的失敗而丟失。 訊息持久化在硬碟中,ActiveMQ持久化有三種方式:AMQ、KahaDB、JDBC。
DeliveryMode.NON_PERSISTENT 不要求JMS provider持久儲存訊息,訊息存放在記憶體中,讀寫速度快,在JMS服務停止後訊息會消失,沒有持久化到硬碟。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70010294/viewspace-2846195/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 生產者消費者模式模式
- 生產者消費者模型模型
- Java實現生產者和消費者Java
- 生產者和消費者(.net實現)
- 生產消費者模式模式
- 阻塞佇列和生產者-消費者模式佇列模式
- 九、生產者與消費者模式模式
- python 生產者消費者模式Python模式
- 使用BlockQueue實現生產者和消費者模式BloC模式
- 使用Disruptor實現生產者和消費者模型模型
- 新手練習-消費者生產者模型模型
- Java實現生產者-消費者模型Java模型
- Java多執行緒——生產者和消費者模式Java執行緒模式
- 實戰Spring4+ActiveMQ整合實現訊息佇列(生產者+消費者)SpringMQ佇列
- 插曲:Kafka的生產者案例和消費者原理解析Kafka
- 鎖,threading local,以及生產者和消費者模型thread模型
- java實現生產者消費者問題Java
- linux 生產者與消費者問題Linux
- 多執行緒之生產者消費者執行緒
- 直觀理解生產者消費者問題
- Java 生產者消費者模式詳細分析Java模式
- kafka中生產者和消費者APIKafkaAPI
- 讀者寫者與生產者消費者應用場景
- 【RabbitMQ】生產者,消費者,通道,佇列,交換器和繫結MQ佇列
- 多執行緒下的生產者和消費者-BlockingQueue執行緒BloC
- Java多執行緒——生產者消費者示例Java執行緒
- 生產者與消費者之Android audioAndroid
- Qt基於QSemaphore的生產者消費者模型QT模型
- java編寫生產者/消費者模式的程式。Java模式
- 併發設計模式---生產者/消費者模式設計模式
- Python中的生產者消費者問題Python
- JAVA執行緒消費者與生產者模型Java執行緒模型
- python多執行緒+生產者和消費者模型+queue使用Python執行緒模型
- C#多執行緒學習(三) 生產者和消費者C#執行緒
- C# 多執行緒學習(3) :生產者和消費者C#執行緒
- python中多程式消費者生產者問題Python
- 「Kafka應用」PHP實現生產者與消費者KafkaPHP
- 架構設計:生產者/消費者模式[0]:概述架構模式