1.簡介:java
RabbitMQ是一個消息中間件,主要做用是用來接收和轉發消息。你能夠將他想象成是郵局:git
當你在郵箱中放入了一封信,那麼郵遞員確定會將信送給它的接收者。而RabbitMQ就像是郵局、web
郵箱、郵遞員。它負責從一處接收消息,按要發送的「地址」將消息轉發到指定「地址」。數組
RabbitMQ和郵局的不一樣之處也就在於它並不處理報刊和雜誌,而是接收、存儲並轉發二進制的消息(Message)緩存
2.RabbitMQ中的經常使用術語:服務器
一般狀況下,消息的生產者、消費者、以及消息中間件並不在同一臺機器中。異步
3.使用Java客戶端:maven
在這節的示例中,咱們將寫兩個Java文件;一個負責發送單條消息(消息生產者),ide
一個負責接收並打印消息(消息消費者)。在下圖中P表明生產者,C表明消費者,測試
中間的紅色格子表明隊列(消息緩存的地方)
4.引入Java依賴包:
本例採用Maven的形式引入,依賴以下:
在pom文件中添加如下代碼
<dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>3.6.6</version> </dependency>
消息生產者的Java代碼(Send.java):
maven引入依賴後請自行導包,代碼中有註釋,再也不對代碼作解釋。
public class Send { private static final String QUEUE_NAME = "hello"; /** * 如下代碼均爲本機測試,RabbitMQ安裝後默認啓用guest帳戶,用戶名guest,密碼guest * 可是該帳戶默認僅能在localhost中使用.請注意. * 測試代碼請根據本身的環境修改userName和password * @param args * @throws Exception */ public static void main(String[] args) throws Exception{ //建立鏈接工廠,設置鏈接地址,用戶名,密碼 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setUsername("admin"); factory.setPassword("admin"); //建立鏈接 Connection connection = factory.newConnection(); //經過鏈接建立信道,信道的建立和銷燬代價比鏈接要小的多 Channel channel = connection.createChannel(); //發送的消息體 String message = "hello rabbitmq"; //發送消息,消息體格式爲字節數組 channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); //關閉鏈接和通道 channel.close(); connection.close(); } }
消費者Java代碼(Recv.java)
public class Recv { //隊列名稱 private static final String QUEUE_NAME = "hello"; public static void main(String[] argv) throws Exception { //建立連接工廠,設置用戶名密碼 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setUsername("admin"); factory.setPassword("admin"); Connection connection = factory.newConnection(); //建立通道 Channel channel = connection.createChannel(); //聲明隊列,發送者和生產者都作了隊列聲明的操做 channel.queueDeclare(QUEUE_NAME, false, false, false, null); System.out.println(" [*] Waiting for messages. To exit press CTRL+C"); //建立消費者,重寫消息的處理方法 Consumer consumer = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body, "UTF-8"); System.out.println(" [x] Received '" + message + "'"); } }; //消費消息. channel.basicConsume(QUEUE_NAME, true, consumer); } }
上述兩個Java文件中,發送者和消費者都作了隊列的聲明操做。在RabbitMQ中該操做是冪等的(只有在該隊列不存在時纔會建立,不會重複建立)
之因此在生產者和消費中都建立隊列,是由於並不肯定會先啓動哪一個服務.徹底有可能先啓動消費者再啓動生產者.咱們要確保消費者從該隊列消費
消息時該隊列已經存在.在下一章你就會看到這樣的例子.
而RabbitMQ隊列的建立是冪等的.因此生產者和消費者同時作隊列的聲明並不會引發什麼問題.
消息生產者的示意圖:
消息經過生產者Send.java將消息發送到名爲hello的隊列
消費者的示意圖:
消費者Revc.java從名爲hello的隊列中取出消息執行本身的邏輯
RabbitMQ服務器會異步的將消息推送出來,因此在消費者中提供一個回調.並重寫handleDelivery方法處理消息.
在此處僅僅是將消息打印出來.
程序到此處已經寫完了,如今你能夠運行項目了.步驟:
1.先運行Send.java,程序將發送一條消息到hello隊列.此時你能夠先不啓動消費者,去MQ的web管理控制檯中看看
在管理控制檯的Queues下能夠看到名爲hello的隊列中有一條準備好的消息.
此時啓動消費者.會看到控制檯hello隊列中的ready消息爲0,已經被消費者消費掉了.隊列也隨之被清空
Java控制檯會打印出來消息內容.
示例代碼地址:https://git.oschina.net/li_mingzhu/rabbitmq.git