本文總結下ActiveMQ的核心功能,涉及一些概念和API。
一. Jms生產者Demo
先上一個生產者的小demo,然後圍繞demo展開:
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class JmsProduce {
public static final String ACTIVEMQ_URL = "tcp://192.168.17.101:61616";
public static final String QUEUE_NAME = "queue01";
public static void main(String[] args) throws JMSException {
//創建連接工廠,按照給定的url地址,使用默認用戶名和密碼
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
//通過連接工廠獲取連接,並啓動
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
//創建會話session,true開啓事務,false不開啓事務
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
//創建目的地,是隊列還是topic
Queue queue = session.createQueue(QUEUE_NAME);
//創建消息的生產者
MessageProducer producer = session.createProducer(queue);
//持久化模式設置
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
try {
//生產3條消息到隊列
for (int i = 1; i <= 3; i++) {
//創建消息
TextMessage textMessage = session.createTextMessage("msg--" + i);
//使用生產者發送消息
producer.send(textMessage);
}
session.commit();
} catch (JMSException e) {
//異常情況回滾提交
session.rollback();
} finally {
//關閉資源
producer.close();
//如果上邊開啓事務,那麼這裏要提交,不然消息不進入隊列
session.close();
connection.close();
}
System.out.println("發佈消息到隊列完成!");
}
}
上述是ActiveMQ的一種生產者的原生標準實現,生產3個消息到隊列Queue中(或者主題Topic中),並且使用了事務模式。
本demo使用了JMS包,下面先總結下JMS。
二. JMS介紹
1.jms是什麼
上述demo中使用了javax.jms.包中的內容,比如Connection/Session/Queue/MessageProducer/TextMessage等。JMS(Java Message Service),java消息服務,是JavaEE規範中的一個模塊,制定了消息接收發送的一套標準規範,其中落地產品有很多(各種MQ),ActiveMQ就是其中一款落地產品,它完全遵守了JMS規範。
JMS提供了一套API,爲標準消息協議和消息服務提供了一組接口,包括創建,發送,讀取消息等。
2.jms組成的四大元素
- jms peovider :實現jms接口和規範的消息中間件,也就是MQ服務器;
- jms producer :消息生產者,創建和發送jms消息的客戶端應用;
- jms consumer :消息消費者,接收和處理jms消息的客戶端應用;
- jms message :發送和被接受的消息,包含消息頭,消息體,消息屬性;
3.jms 消息頭
列舉幾個比較重要參數:
- JMSDestination :消息發送的目的地,主要指Queue還是Topic;Message接口提供了setJMSDestination方法;
- JMSDeliveryMode :設置持久化或者非持久化模式,非持久化模式下,MQ宕機,消息丟失,但是持久化模式不會丟失;
- JMSExpiration :設置消息過期時間,過期後會清除,默認是永不過期;
- JMSPriority :消息優先級,包含0-9是個級別,0-4是普通消息,5-9是加急消息,默認是4。JMS規範不要求MQ嚴格按照這個優先級順序發送,但是要保證5-9的早於0-4的。
- JMSMessageID :唯一識別每個消息的標識,由MQ產生或者自己設定;
以上參數可以針對每條消息單獨設置,也可以在send方法中統一設置。
4.消息體
消息體封裝具體的消息數據,有多種類型格式,消息發送方和接收方的格式必須保持一致。
5種消息體格式:
- TextMessage :普通字符串,包含一個string;
- MapMessage :map類型,其中key爲String類型,
- BytesMessage :二進制數組消息,包含一個byte[];
- StreamMessage :java數據流消息,用標準流來順序填充和讀取;
- ObjectMessage :對象消息,包含一個可序列話的java對象;
5.消息屬性
識別,去重,重點標註等操作。
接口方法:
setStringProperty(String name, String value);
除此之外,還有setIntProperty等類型;需要注意的是,生產者與消費者的類型要保持一致。
三. 消息的持久化
jms消息默認是持久化的,可以通過JMS接口的如下方法設置持久與非持久:
void setDeliveryMode(int deliveryMode) throws JMSException;
public interface DeliveryMode {
//非持久
static final int NON_PERSISTENT = 1;
//持久
static final int PERSISTENT = 2;
}
非持久模式下,MQ如果宕機再啓動,消息會丟失;持久化模式下,消息只要沒消費掉,不會丟失。
四. 消息事務
1.生產者事務
文章開頭的demo中,有如下內容:
//創建會話session,true開啓事務,false不開啓事務
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
第一個參數,true表示開啓事務;false表示關閉事務;
開啓了事務模式,那麼就需要提交事務:
session.commit();
提交事務之前,消息不進入隊列;只有提交後,消息才進入隊列,消費者才能消費到。
2.消費者事務
消費者的事務使用代碼和生產者一樣。
消費者中,要注意commit,否則消費者會重複消費消息,消息一直在隊列中消費不掉;只有提交事務後,才能被消費掉。
五. 消息簽收
簽收針對的是消費者,在消費者中,一般也會有如下代碼:
//創建會話session,true開啓事務,false不開啓事務
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
其中,第二個參數是簽收模式。在非事務模式下,共有如下幾種類型:
-
Session.AUTO_ACKNOWLEDGE = 1; //自動簽收,默認就是這種方式;在這種模式下,消費者會自動簽收消息,也就是在拿到消息時,就默認簽收了,不用在調用方法進行簽收;
-
Session.CLIENT_ACKNOWLEDGE = 2; //手動簽收,在這種模式下,消費者拿到消息後,需要使用如下方法進行手動簽收,
textMessage.acknowledge ();
,否則,消息會殘留在消息隊列中,導致重複消費。 -
Session.DUPS_OK_ACKNOWLEDGE = 3; //允許重複簽收,這種模式基本不使用。
注意,上述模式是針對非事務模式的;
如果在事務模式下,那麼簽收模式會失效,即使配置的是手動簽收,在事務模式下,也會被自動簽收。
六.傳輸協議種類
Demo中,使用瞭如下連接,可以發現,使用的的是tcp協議,
public static final String ACTIVEMQ_URL = "tcp://192.168.17.101:61616";
除了此種協議,ActiveMQ還支持其他類型協議:
1.transmission Control Protocol(TCP)
tcp是默認使用的協議,端口61616;
使用格式:tcp://hostname:port?key=value ,key和value可以不添加,具體內容有:
全部內容看官方文檔:
http://activemq.apache.org/tcp-transport-reference
2.New I/O API Protocol (NIO)
nio基於tcp協議,進行了擴展和優化,比tcp協議具有更好的性能,實際生產中,也大多使用此種協議。
要使用此種模式,需要修改ActiveMQ的配置文件:conf / activemq.xml ,增加
<transportConnector name="nio" uri="nio://0.0.0.0:61616"/>
使用格式:nio://hostname:port?key=value ,其中key和value同tcp配置。
具體參考官方文檔:
http://activemq.apache.org/configuring-version-5-transports.html
auto模式
從5.13.0版本開始,activemaq支持auto自動模式,可以從多種類型的協議中自動探測最終使用哪種協議。
官方文檔:http://activemq.apache.org/auto
3.AMQP 協議
4.stomp協議
5.Secure Sockets Layer Protocol (SSL)安全連接
6. mqtt 協議
7. ws 協議
上述其他協議使用不多,具體看官方文檔:
http://activemq.apache.org/configuring-version-5-transports.html