ActiveMQ(1)
扯個淡:
自己想個系列然后堅持下去,其實是個很不錯的自我督促的學習方法。
《我們到底能走多遠系列》已經擠出了25篇啦。在弄一個系列玩玩,主要用於提醒自己不斷的學習新東西,可能都是入門級別的,只是為了拒絕停滯,或退步,為了讓今天的自己比昨天的自己棒。
不要和別人比,和昨天的自己比就可以了。
最近讀《ActiveMQ in action》,整理學習后,記錄下來。
附上自己的想法和問題,希望一起交流。
直接使用ActiveMQ:helloWord!
包結構:(注意對log4j和sl4f包的依賴問題)
Receive:
package d.c.home.test; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.MessageConsumer; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; public class Receiver { public static void main(String[] args) { // ConnectionFactory :連接工廠,JMS 用它創建連接 ConnectionFactory connectionFactory; // Connection :JMS 客戶端到JMS Provider 的連接 Connection connection = null; // Session: 一個發送或接收消息的線程 Session session; // Destination :消息的目的地;消息發送給誰. Destination destination; // 消費者,消息接收者 MessageConsumer consumer; connectionFactory = new ActiveMQConnectionFactory( ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616"); try { // 構造從工廠得到連接對象 connection = connectionFactory.createConnection(); // 啟動 connection.start(); // 獲取操作連接 session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 獲取session注意參數值xingbo.xu-queue是一個服務器的queue,須在在ActiveMq的console配置 destination = session.createQueue("FirstQueue"); consumer = session.createConsumer(destination); while (true) { //設置接收者接收消息的時間,為了便於測試,這里誰定為100s TextMessage message = (TextMessage) consumer.receive(100000); if (null != message) { System.out.println("收到消息" + message.getText()); } else { break; } } } catch (Exception e) { e.printStackTrace(); } finally { try { if (null != connection) connection.close(); } catch (Throwable ignore) { } } } }
Sender:
package d.c.home.test; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.DeliveryMode; import javax.jms.Destination; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; public class Sender { private static final int SEND_NUMBER = 5; public static void main(String[] args) { // ConnectionFactory :連接工廠,JMS 用它創建連接 ConnectionFactory connectionFactory; // Connection :JMS 客戶端到JMS Provider 的連接 Connection connection = null; // Session: 一個發送或接收消息的線程 Session session; // Destination :消息的目的地;消息發送給誰. Destination destination; // MessageProducer:消息發送者 MessageProducer producer; // TextMessage message; // 構造ConnectionFactory實例對象,此處采用ActiveMq的實現jar connectionFactory = new ActiveMQConnectionFactory( ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616"); try { // 構造從工廠得到連接對象 connection = connectionFactory.createConnection(); // 啟動 connection.start(); // 獲取操作連接 session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); // 獲取session注意參數值FirstQueue是一個服務器的queue,須在在ActiveMq的console配置 destination = session.createQueue("FirstQueue"); // 得到消息生成者【發送者】 producer = session.createProducer(destination); // 設置不持久化,此處學習,實際根據項目決定 producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); // 構造消息,此處寫死,項目就是參數,或者方法獲取 sendMessage(session, producer); session.commit(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (null != connection) connection.close(); } catch (Throwable ignore) { } } } public static void sendMessage(Session session, MessageProducer producer) throws Exception { for (int i = 1; i <= SEND_NUMBER; i++) { TextMessage message = session .createTextMessage("ActiveMq 發送的消息" + i); // 發送消息到目的地方 System.out.println("發送消息:" + "ActiveMq 發送的消息" + i); producer.send(message); } } }
啟動兩個main 就可以實現 hello world啦!
1,了解下ActiveMQ是做什么的?
沒用前:
有了ActiveMQ后:
好吧,很容易理解,圖片果然來得不叫快。
2,什么情況下可以用呢?
- 鑒於ActiveMQ支持多語言,除了支持java外還支持C/C++, .NET, Perl, PHP, Python, Ruby,所以,哈哈,多語言平台的交互!
- 遠程方法調用,RMI,很強大,但是如果你不想用,ActiveMQ會是一個可選的替代品!
- 解耦,對於一個越來越龐大,復雜的產品來說,是必經之路。一般,把一個個模塊分出去,弄成應用級別,然后通過異步交互的方式實現解耦,ActiveMQ可以幫你實現
- 異步處理,web應用的同步執行高並發達到極限,只有通過異步的方式,來使性能再上台階。
- 共用模塊的實現,比如發郵件,發短信,log持久化,等這些功能呢個可能在多個應用中都有使用,只要寫一個處理器,專門接受遠程的message,然后實現功能。多個應用在開發這些功能時只要組裝出一個message,扔給它就可以了。
3,關於message-oriented middleware(MOM)面向對象的中間件 和 JMS
面向對象的中間件,是為了解決應用之間通過message形式交互提供的解決方案。這種中間件有很多,比如:WebSphere MQ,jboss的hornetQ
而ActiveMQ就也這些中間件中的一員。
JMS 為這種中間提供商提供了統一的API接口,來定義一個消息的發送和接受的規范。
所有中間商可以實現這些接口以達到自己提供的jms服務,如此統一,有利於減少同提供商之間交互出現的不兼容。
JMS的作用:
JMS規定了什么東西?既然中間件都直線了這些接口,我想只要熟悉了JMS規范,也差不多熟悉了所有的中間件了吧。
1-message producers
使用MessageProducer,向目標發送message,也可以通過MessageProducer來設置一些信息
MessageProducer :
public interface MessageProducer { void setDisableMessageID(boolean value) throws JMSException; boolean getDisableMessageID() throws JMSException; void setDisableMessageTimestamp(boolean value) throws JMSException; boolean getDisableMessageTimestamp() throws JMSException; void setDeliveryMode(int deliveryMode) throws JMSException; int getDeliveryMode() throws JMSException; void setPriority(int defaultPriority) throws JMSException; int getPriority() throws JMSException; void setTimeToLive(long timeToLive) throws JMSException; long getTimeToLive() throws JMSException; Destination getDestination() throws JMSException; void close() throws JMSException; void send(Message message) throws JMSException; void send(Message message, int deliveryMode, int priority, long timeToLive) throws JMSException; void send(Destination destination, Message message) throws JMSException; void send( Destination destination, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException; }
2-MessageConsumer用來消費消息,
public interface MessageConsumer { String getMessageSelector() throws JMSException; MessageListener getMessageListener() throws JMSException; void setMessageListener(MessageListener listener) throws JMSException; Message receive() throws JMSException; Message receive(long timeout) throws JMSException; Message receiveNoWait() throws JMSException; void close() throws JMSException; }
3-Message 傳遞的內容信息對象
Message有head和body組成,head可以通過屬性的設置來改變Message的一些特性:
body的話,是通過鍵值對的方式來設置的,Message接口定義了不同數據類型的設置和取得的方法:
public interface Message { boolean getBooleanProperty(String name) throws JMSException; byte getByteProperty(String name) throws JMSException; short getShortProperty(String name) throws JMSException; int getIntProperty(String name) throws JMSException; long getLongProperty(String name) throws JMSException; float getFloatProperty(String name) throws JMSException; double getDoubleProperty(String name) throws JMSException; String getStringProperty(String name) throws JMSException; Object getObjectProperty(String name) throws JMSException; Enumeration getPropertyNames() throws JMSException; boolean propertyExists(String name) throws JMSException; void setBooleanProperty(String name, boolean value) throws JMSException; void setByteProperty(String name, byte value) throws JMSException; void setShortProperty(String name, short value) throws JMSException; void setIntProperty(String name, int value) throws JMSException; void setLongProperty(String name, long value) throws JMSException; void setFloatProperty(String name, float value) throws JMSException; void setDoubleProperty(String name, double value) throws JMSException; void setStringProperty(String name, String value) throws JMSException; void setObjectProperty(String name, Object value) throws JMSException; }
而Message下分為不同形式: