RabbitMQ入門 使用簡單模式完成消息傳遞
搭建示例工程
入門程序
需求:使用簡單模式完成消息傳遞
步驟:
①創建工程(生產者、消費者)
②分別添加依賴
③編寫生產者發送消息
④編寫消費者接收消息
創建工程
創建空項目 rabbitmq
創建modules
rabbitmq-consumer
rabbitmq-producer
添加依賴
往rabbitmq-consumner、rabbitmq-producer的pom.xml文件中添加如下依賴:
<dependencies>
<!--rabbitmq java 客戶端-->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.6.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
編寫生產者
編寫消息生產者
cn.liuawen.producer.Producer_HelloWorld
package cn.liuawen.producer;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 發送消息
*/
public class Producer_HelloWorld {
public static void main(String[] args) throws IOException, TimeoutException {
//1.創建連接工廠
ConnectionFactory factory = new ConnectionFactory();
//2. 設置參數
//http://39.99.254.180:15672/
factory.setHost("39.99.254.180");//ip 默認值 localhost
factory.setPort(5672); //端口 默認值 5672
factory.setVirtualHost("/liuawen");//虛擬機 默認值/
factory.setUsername("liuawen");//用戶名 默認 guest
factory.setPassword("liuawen");//密碼 默認值 guest
//3. 創建連接 Connection
Connection connection = factory.newConnection();
//4. 創建Channel
Channel channel = connection.createChannel();
//5. 創建隊列Queue
/*
queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
參數:
1. queue:隊列名稱
2. durable:是否持久化,當mq重啓之後,還在
3. exclusive:
* 是否獨佔。只能有一個消費者監聽這隊列
* 當Connection關閉時,是否刪除隊列
*
4. autoDelete:是否自動刪除。當沒有Consumer時,自動刪除掉
5. arguments:參數。
*/
//如果沒有一個名字叫hello_world的隊列,則會創建該隊列,如果有則不會創建
channel.queueDeclare("hello_world",true,false,false,null);
/*
basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
參數:
1. exchange:交換機名稱。簡單模式下交換機會使用默認的 ""
2. routingKey:路由名稱
3. props:配置信息
4. body:發送消息數據
*/
String body = "hello rabbitmq~~~";
//6. 發送消息
channel.basicPublish("","hello_world",null,body.getBytes());
//7.釋放資源
channel.close();
connection.close();
}
}
在執行上述的消息發送之後;
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Process finished with exit code 0
可以登錄rabbitMQ的管理控制檯,可以發現隊列和其消息:
編寫消費者
編寫消息的消費 cn.liuawen.consumer.Consumer_HelloWorld
package cn.liuawen.consumer;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer_HelloWorld {
public static void main(String[] args) throws IOException, TimeoutException {
//1.創建連接工廠
ConnectionFactory factory = new ConnectionFactory();
//2. 設置參數
factory.setHost("39.99.254.180");//ip 默認值 localhost
factory.setPort(5672); //端口 默認值 5672
factory.setVirtualHost("/liuawen");//虛擬機 默認值/
factory.setUsername("liuawen");//用戶名 默認 guest
factory.setPassword("liuawen");//密碼 默認值 guest
//3. 創建連接 Connection
Connection connection = factory.newConnection();
//4. 創建Channel
Channel channel = connection.createChannel();
//5. 創建隊列Queue
/*
queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
參數:
1. queue:隊列名稱
2. durable:是否持久化,當mq重啓之後,還在
3. exclusive:
* 是否獨佔。只能有一個消費者監聽這隊列
* 當Connection關閉時,是否刪除隊列
*
4. autoDelete:是否自動刪除。當沒有Consumer時,自動刪除掉
5. arguments:參數。
*/
//如果沒有一個名字叫hello_world的隊列,則會創建該隊列,如果有則不會創建
channel.queueDeclare("hello_world",true,false,false,null);
/*
basicConsume(String queue, boolean autoAck, Consumer callback)
參數:
1. queue:隊列名稱
2. autoAck:是否自動確認
3. callback:回調對象
*/
// 接收消息
Consumer consumer = new DefaultConsumer(channel){
/*
回調方法,當收到消息後,會自動執行該方法
1. consumerTag:標識
2. envelope:獲取一些信息,交換機,路由key...
3. properties:配置信息
4. body:數據
*/
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("consumerTag:"+consumerTag);
System.out.println("Exchange:"+envelope.getExchange());
System.out.println("RoutingKey:"+envelope.getRoutingKey());
System.out.println("properties:"+properties);
System.out.println("body:"+new String(body));
}
};
channel.basicConsume("hello_world",true,consumer);
//關閉資源?不要
//消費者 監聽
}
}
執行
"org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
consumerTag:amq.ctag-hvie61k1SqFB655rv3nPHQ
Exchange:
RoutingKey:hello_world
properties:#contentHeader<basic>(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null)
body:hello rabbitmq~~~
小結
上述的入門案例中中其實使用的是如下的簡單模式:
在上圖的模型中,有以下概念:
- P:生產者,也就是要發送消息的程序
- C:消費者:消息的接受者,會一直等待消息到來。
- queue:消息隊列,圖中紅色部分。類似一個郵箱,可以緩存消息;生產者向其中投遞消息,消費者從其中取出消息。