一、什麼是ActiveMQ?
ActiveMQ是Apache提供的一個開源消息系統,它是完全使用java開發,可以很好的支持JMS規範。
二、什麼是JMS?
JMS即Java消息服務(Java Message Service)應用程序接口,是一個Java平臺中關於面向消息中間件(MOM)的API,用於在兩個應用程序之間或者分佈式系統中發送消息,進行異步通信。如果兩個程序之間需要進行通信,我們使用一個JMS服務,進行中間的轉發,通過JMS的使用,我們可以解除兩個程序之間的耦合。例如,我們在點外賣的時候,當我們下單之後,軟件會提示我們“下單成功,正在等待商家接單”的消息。因爲點外賣的人流很多,在同一時刻會有許多人進行下訂單的請求,如果不使用異步消息機制,第二個人必須要等第一個人執行完了,才能夠繼續執行,這就給顧客帶來了極差的體驗,萬一一次的請求時間過長,顧客就會失去耐心而不會再繼續等待了。
三、ActiveMQ的作用?
ActiveMQ支持同步請求與異步請求,首先解釋一下什麼是同步請求與異步請求,同步請求就是在同一個時間點,如果有兩個用戶執行了同一個操作,那麼,第二個用戶只能等待第一個用戶執行完了請求才能夠進行執行;異步請求就是在同一個時間點,第二個用戶能夠不用等待,兩個用戶的請求同時執行。個人建議:如果使用ActiveMQ去執行同步請求,我覺得還不如不用該消息中間件。
四、ActiveMQ支持的消息模式?
兩種消息模式:一種是點對點通訊(PointToPoint),也稱作PTP。該通訊模式是一個生產者對應一個消費者,也就是說一則消息只能夠被一個消費者所消費掉。假設一個場景:現在有一個生產者,兩個消費者,生產者發送了10條信息給Queue(隊列),此時兩個消費者均攤消息,均攤的規則是輪詢,也就是一位消費者接收到的是1,3,5,7,9,另外一位消費者接收到的是2,4,6,8,10。
點對點模型圖:
PTP特點:1.一則消息只能被一位消費者消費;
2.生產者發送消息時,消費者可在線,也可不在線;同樣,消費者接收消息時,生產者可以不在線。
另一種是發佈/訂閱(pulisher/subscriber),對於該通訊模式,首先訂閱者要先去訂閱,然後發佈者發佈消息給所有的訂閱者,換句話說,發佈/訂閱模式所產生的一則消息可以被多個訂閱者所消費。但是這種模式有一個特點就是訂閱者要先在線訂閱,發佈者發送的消息才能夠被接收。
發佈/訂閱模型圖:
發佈/訂閱特點:1.一則消息可以被多位訂閱者消費;
2.訂閱者要先進行訂閱,才能夠接收到發佈者所發佈的消息。
五、項目展示?
1.Activemq客戶端安裝:
去Activemq官網http://activemq.apache.org/download-archives.html下載壓縮包,解壓即可使用,前提是要安裝了JDK,當然,我想都瞭解到了Activemq,不能在機器上連java環境都沒裝。
現在的機器一般都是64位的了,所以選擇win64文件下,點擊activemq.bat即可運行。
見到下圖說明運行成功了:
在瀏覽器中輸入localhost:8161,輸入用戶名admin與密碼admin可以進入activemq的控制檯界面。
2.項目中的pom.xml文件引入依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency>
3.application.properties文件:
#指定ActiveMQ的URL spring.activemq.broker-url=tcp://localhost:61616 #是否是內存模式 spring.activemq.in-memory=true #是否使用PooledConnectionFactory spring.activemq.pool.enabled=false #信任所有的包 spring.activemq.packages.trust-all=true
4.點對點通訊案例:
(1)生產者:
/** * @Description: 生產者 * @Author: HuangChangJun * @Date: 2019/4/24 13:26 * @Version: 1.0 */ public class Producer { //ActiveMQ的通訊地址 private final static String URL="tcp://localhost:61616"; //隊列名稱 private final static String QUEUENAME="my_queue"; public static void main(String [] args) throws JMSException { //1.創建ActiveMQ連接工廠對象 ActiveMQConnectionFactory factory=new ActiveMQConnectionFactory(URL); //2.創建連接 Connection connection= factory.createConnection(); //3.開啓連接 connection.start(); //4.創建session會話 Session session= connection.createSession(false,Session.AUTO_ACKNOWLEDGE); //5.創建目標 Queue queue=session.createQueue(QUEUENAME); //6.創建生產者 MessageProducer producer = session.createProducer(queue); //7.創建消息文本 TextMessage message=session.createTextMessage("我的第一個ActimeMQ消息"); //8.發送消息 producer.send(message); System.out.println("消息已發送!"); //9.關閉連接 if (connection!=null){ connection.close(); } } }
運行完生產者代碼之後,我們可以看到多了一條消息隊列,並且正在排隊,等待消費者消費。
(2)消費者:
/** * @Description: 消費者 * @Author: HuangChangJun * @Date: 2019/4/24 13:47 * @Version: 1.0 */ public class Consumer { //ActiveMQ的通訊地址 private final static String URL="tcp://localhost:61616"; //隊列名稱 private final static String QUEUENAME="my_queue"; public static void main(String [] args) throws JMSException { //1.創建ActiveMQ連接工廠 ActiveMQConnectionFactory factory=new ActiveMQConnectionFactory(URL); //2.創建連接對象 Connection connection= factory.createConnection(); //3.開始連接 connection.start(); //4.創建session會話 Session session= connection.createSession(false,Session.AUTO_ACKNOWLEDGE); //5.創建目標 Queue queue= session.createQueue(QUEUENAME); //6.創建消費者 MessageConsumer consumer= session.createConsumer(queue); //7.實例化監聽函數 consumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { //8.創建消息文本 TextMessage message1=(TextMessage)message; try { //9.接收內容 System.out.println("接收到消息:"+message1.getText()); } catch (JMSException e) { e.printStackTrace(); } } }); } }
這時,我們可以看出待處理的消息已經被消費了,多了一個消費者的數量。
點對點模式的案例就到此了,想要更詳細的代碼可根據自身業務的需求來編寫,比如是否需要開啓事務,接收模式是否時自動簽收,還是等待消費者告訴隊列消息已拿到。如果需要告訴隊列消息已拿到的模式,我們可以將Seesioin.AUTO_ACKNOWLEDGE改爲Session.CLIENT_ACKNOWLEDGE。
5.訂閱/發佈項目案例:
(1)訂閱者:
/** * @Description: 訂閱者 * @Author: HuangChangJun * @Date: 2019/4/25 15:25 * @Version: 1.0 */ public class Subcriber { private final static String URL="tcp://localhost:61616"; private final static String TOPICNAME="my_topic"; public static void main(String [] args) throws JMSException { //1.創建ActiveMQ連接工廠 ActiveMQConnectionFactory factory=new ActiveMQConnectionFactory(URL); //2.創建連接對象 Connection connection = factory.createConnection(); //3.開啓連接 connection.start(); //4.創建Session會話 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //5.創建主題 Topic topic = session.createTopic(TOPICNAME); //6.創建訂閱者 MessageConsumer consumer=session.createConsumer(topic); //7.開始監聽訂閱的主題 System.out.println("訂閱者訂閱成功!"); consumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { //8.接收消息 TextMessage message1=(TextMessage)message; try { System.out.println("收到訂閱內容:"+message1.getText()); } catch (JMSException e) { e.printStackTrace(); } } }); } }
運行完訂閱者我們發現多了四行信息,下面我們就逐一解釋下每行信息的意思:
第一行的ActiveMQ.Advisory.Connection是表示連接開始和停止消息;
第二行的ActiveMQ.Advisory.Consumer.Topic.my_topic是表示消費者在主題上啓動和停止消息;
第三行的ActiveMQ.Advisory.Topic是表示主題的創建和銷燬;
第四行的my_topic是表示我創建的主題的信息,通過上面我們可以看到有一位消費者數量。
如想要了解更多可去官網查看,傳送門:http://activemq.apache.org/advisory-message.html。
(2)發佈者
/** * @Description: 發佈者 * @Author: HuangChangJun * @Date: 2019/4/25 15:18 * @Version: 1.0 */ public class Publisher { private final static String URL="tcp://localhost:61616"; private final static String TOPICNAME="my_topic"; public static void main(String [] args) throws JMSException { //1.創建ActiveMQ連接工廠 ActiveMQConnectionFactory factory=new ActiveMQConnectionFactory(URL); //2.創建連接對象 Connection connection=factory.createConnection(); //3.開啓連接 connection.start(); //4.創建session會話 Session session=connection.createSession(false,Session.AUTO_ACKNOWLEDGE); //5.創建主題 Topic topic= session.createTopic(TOPICNAME); //6.創建生產者 MessageProducer producer= session.createProducer(topic); //7.創建消息 TextMessage message=session.createTextMessage("這是我的第一個主題消息"); System.out.println("發佈成功"); //8.發送消息 producer.send(message); //9.關閉連接 connection.close(); } }
運行完發佈者,我們可以看到,第一行變成了3,因爲發佈者的代碼執行了開始和關閉,所以也就有了第三行的2。第五行的主題有一個消息在排隊,還有一個已出列的消息。
訂閱/發佈的通訊模型案例也就這樣結束了。
這篇文章只是對ActiveMQ有個大致的瞭解,希望對你們的入門有所幫助,喜歡的話可否點個贊,謝啦!