介紹
rabbitMQ是基於AMQP協議的消息隊列,erlang語言實現。引用官網如下:
RabbitMQ is a message broker: it accepts and forwards messages. You can think about it as a post office: when you put the mail that you want posting in a post box, you can be sure that Mr. or Ms. Mailperson will eventually deliver the mail to your recipient. In this analogy, RabbitMQ is a post box, a post office and a postman.
說白了,就是一個生產者、中間件和消費者的關係,發送者只負責生產消息,rabbitMQ作爲中間件負責接收消息,緩存消息,發送消息。而消費者只負責從中間件獲取消息。
本次helloworld示例模型如下:
下面用java方式實現。
首先導入maven:
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.8.0</version>
</dependency>
生產者實現
之後編寫生產者:
創建步驟:
step1:通過連接工廠ConnnectionFactory創立連接Connection
step2:創立通道Channel
step3:申明隊列
step4:發送消息
step5:先關閉Channel,再關閉Connection。
代碼入下:
public class Producer01 {
private static final String QUEUENAME = "hello-world";
public static void main(String[] args) throws IOException, TimeoutException {
//通過連接工廠創建新的連接和mq建立連接
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
connectionFactory.setPort(5672);
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
//設置虛擬機,一個mq的服務可以設置多個虛擬機,每個虛擬機相當於一個獨立的mq。
connectionFactory.setVirtualHost("/");
//建立新連接
Connection connection = null;
connection = connectionFactory.newConnection();
//創建會話通道,生產者和mq服務所有的通信都在channel裏完成。
Channel channel = connection.createChannel();
//聲明隊列:如果隊列在mq中沒有,則創建
//參數String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
/**
* 參數明細:
* queue:隊列名稱
* durable:持久化,如果持久化,重啓mq服務隊列還在
* exclusive:是否獨佔連接,隊列只允許在該連接中訪問,如果連接關閉則隊列刪除,設置爲true,可用於臨時隊列。
* autoDelete:自動刪除,設置爲true,連接不使用則刪除隊列
* arguments:指定一些擴展參數。例如存活時間等等
*/
channel.queueDeclare(QUEUENAME,true,false,false,null);
//發送消息
//參數:String exchange, String routingKey, BasicProperties props, byte[] body
/**
* 參數明細:
* exchange:交換機,不指定的話爲默認交換機
* routingKey:交換機根據路由key,將消息轉發到指定隊列,如果使用默認交換機,routingKey設置爲隊列的名稱
* props:消息的屬性
* body:消息內容,字節數組形式
*/
channel.basicPublish("",QUEUENAME,null,"hello,world!請多指教".getBytes());
System.out.println("send to mq");
//關閉通道
channel.close();
//關閉連接
connection.close();
}
}
至此創建生產者成功,同時也創建了名爲hello-world的消息隊列,之後的消費者若要取出信息,就要到同名的隊列中取出。
消費者實現
消費者的實現方式和生產者類似,僅僅將發送消息替換成監聽隊列即可。代碼如下:
public class Consumer01 {
private static final String QUEUENAME = "hello-world";
public static void main(String[] args) throws IOException, TimeoutException {
//通過連接工廠創建新的連接和mq建立連接
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
connectionFactory.setPort(5672);
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
//設置虛擬機,一個mq的服務可以設置多個虛擬機,每個mq相當於一個獨立的mq。
connectionFactory.setVirtualHost("/");
//建立新連接
Connection connection = null;
connection = connectionFactory.newConnection();
//創建會話通道,生產者和mq服務所有的通信都在channel裏完成。
Channel channel = connection.createChannel();
//聲明隊列:如果隊列在mq中沒有,則創建
channel.queueDeclare(QUEUENAME,true,false,false,null);
//實現消費方法
DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
/**
* 當接收到消息後,此方法執行
* @param consumerTag 消費者標籤,用來標識消費者,在監聽隊列時也可設置channel.basicConsume
* @param envelope 信封,可用信封獲取一些信息,例如交換機、消息id等
* @param properties 消息屬性,發送消息時設置的消息屬性可在這裏獲取
* @param body 消息內容
* @throws IOException
*/
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//super.handleDelivery(consumerTag, envelope, properties, body);
//拿到交換機
String exchange = envelope.getExchange();
//消息id,mq在channel中用來表示消息的id,可用於確認消息已接收。
long deliveryTag = envelope.getDeliveryTag();
String message = new String(body,"UTF-8");
System.out.println("交換機:"+exchange+" 消息id"+deliveryTag+" 消息內容"+message);
}
};
//監聽隊列
//參數 String queue, boolean autoAck, Consumer callback
/**
* 參數明細:
* queue:隊列名稱
* autoAck:自動回覆,消費者接受到消息會自動告訴mq服務消息已接收此參數設置爲true
* 會自動回覆mq,如果設置爲false要通過編程回覆,不回覆的話消息一直在隊列裏。
* callback:回調方法,當消費者接收到消息要執行的方法。
*/
channel.basicConsume(QUEUENAME,true,defaultConsumer);
}
}