RabbitMQ簡單收發,HelloWorld
前言
接觸RabbitMQ有一週多的時間了,對RabbitMQ有了自己的一些粗淺的見解,想和大家分享下,本文先講解簡單的RabbitMQ收發操作,沒有做任何的處理,參考了官網的資料進行編寫,並加入個人的一些見解,不對之處請多多指教。
一.定義
RabbitMQ是消息隊列,應用程序對應用程序的通信方法,官網中的定義是消息經紀人。也就是說消息中間件,兩個應用程序信息傳遞不是直接去溝通,而是A程序先傳給RabbitMQ,B程序再從RabbitMQ中獲取,再進行處理。有時我會在想爲什麼不通過其他的協議形式直接傳遞,而需要通過這個中間件呢?通過它有什麼樣的優勢.試想下有一種場景,有一堆數據要上傳接受處理,如十萬或上百萬條數據,但你又不需要立刻馬上處理他,若果你直接去接受這麼大量數據,不說outOfMemory情況,噹噹處理這些信息那得多耗時,佔用系統資源,而使用rabbitMQ就能異步處理這些數據,它可以消費一個後再從隊列中取數據,大大節省了響應時間,從而提高系統吞吐量。
二.角色定義
在這簡單的收發模型中有三個角色分別是生產者(producer)、消息隊列(message queue)、消費者(consummer)
a、生產者,主要是發送消息給消息隊列
b、消息隊列,它存在於RabbitMQ中,所有的信息都會存放到消息隊列中,遵循先進先出的存儲方式,當接受到請求,將數據發送出去,如果接到已被消費的ACK(回執),這該消息將從隊列中移除。
c、消費者,從消息隊列中獲取數據,並返回ACK給RabbitMQ。
這是簡單的收發過程圖。
三.預置條件
使用rabbitMQ需要先安裝其服務器
1.下載Erlang http://docs.basho.com/riak/1.3.0/tutorials/installation/Installing-Erlang/
2.下載RabbitMQ http://www.rabbitmq.com/releases/rabbitmq-server/v3.3.4/rabbitmq-server-3.3.4.exe
3.下載依賴包 amqp-client-4.0.2.jar slf4j-api-1.7.21.jar slf4j-simple-1.7.22.jar
四.sending
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* 發送消息端
* @author sibat
*
*/
public class Send {
private final static String QUEUE_NAME = "hello";
public static void main(String[] args) {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
factory.setPort(5672);
Connection connection = null;
Channel channel = null;
try {
connection = factory.newConnection();
channel= connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false,false,null);
String msg = "I am comming";
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
System.out.println("producer send " + "'"+ msg + "'");
} catch (IOException | TimeoutException e) {
e.printStackTrace();
}finally{
if (channel != null) {
try {
channel.close();
} catch (IOException | TimeoutException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
五.Receiving
有一個函數要注意的是channel.basicConsume(),第二個參數爲true,意思是自動返回ACK,即queue在傳遞信息給consumer後就會立馬收到ACK,queue不再對這個消息進行存儲了。
channel.basicConsume(QUEUE_NAME, true, consumer);
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.ShutdownSignalException;
public class Recv {
private static final String QUEUE_NAME = "hello";
public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException, ConsumerCancelledException, InterruptedException {
ConnectionFactory factory = new ConnectionFactory();
//設置MabbitMQ所在主機ip或者主機名
factory.setHost("127.0.0.1");
factory.setPort(5672);
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, 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);
}
}
五.輸出結果
發送端:
producer send 'I am comming'
接收端:
[*] Waiting for messages. To exit press CTRL+C
[x] Received 'I am comming'