RabbitMQ的安裝
這裏暫時使用window環境,稍後補充linux下的安裝。首先,因爲RabbitMQ由ERLANG實現,所以首先需要安裝ERLANG環境,安裝好之後纔是RabbitMQ的安裝和配置。
ERLANG環境
1.先去官網下載最新的OPT。直接打開exe文件執行安裝,記錄下安裝的目錄文件路徑。
2.將ERLANG加入系統環境:
3.此時打開erlang表示成功。
RabbitMQ安裝
1.下載RabbitMQ,直接運行exe文件即可。
2.檢驗安裝是否成功:
進入命令行,輸入你的安裝目錄和rabbitmqctl status命令,看到一大串東西就說明安裝成功。
3.安裝 RabbitMQWeb的管理插件。繼續命令行輸入:rabbitmq-plugins enable rabbitmq_management,此時就可以訪問http://localhost:15672啦。
默認的管理員賬戶和密碼都是guest,我們可以通過命令來創建新的管理員。
1.新增加用戶:命令行(rabbitmqctl.bat add_user 用戶名 密碼)。
2.將用戶升級爲管理員(這樣纔可以登陸後臺管理界面)。輸入rabbitmqctl.bat set_user_tags 用戶名 administrator
3.使用test1 test1登陸成功,這樣RabbitMQ就安裝好了。
RabbitMQ入門
RabbitMQ消息隊列一共有6種,從簡單到複雜分別爲簡單模式、 Work模式、訂閱模式、路由模式、通配符模式和RPC模式。
下面我將使用java簡單做幾個測試demo。
maven中加入的dependency:
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>3.6.5</version>
</dependency>
簡單模式
一個生產者將消息發送到隊列中,一個消費者從隊列中獲得消息。
我們創建兩個獨立的項目,分別表示消費者和生產者。
生產者端代碼:
public class Producer {
private final static String QUEUE_NAME = "RabbitMQ.demo";
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
// 創建連工廠
ConnectionFactory factory = new ConnectionFactory();
// 設置相關信息
factory.setHost("localhost");
// 創建一個鏈接
Connection connection = factory.newConnection();
// 創建一個通道
Channel channel = connection.createChannel();
// 在通道里聲明一個隊列
channel.queueDeclare("", false, false, false, null);
// 發佈消息到隊列中
String message = "This is 消息隊列 demo";
for (int i = 0; i < 20; i++) {
channel.basicPublish("", QUEUE_NAME, null, (message+i).getBytes("UTF-8"));
TimeUnit.MILLISECONDS.sleep(300);
System.out.println("生產者發送了消息:" +"["+i+"]" +message);
}
// 關閉資源
channel.close();
connection.close();
}
}
解釋一下queueDeclare中的參數。
Parameters:
queue :隊列的名字,這沒啥好說的。
durable :是否需要持久化,指的是隊列持久化到數據庫中,持久化設置爲true的話,即使RabbitMQ服務崩潰也不會丟失隊列裏面的數據。
exclusive :是否排外,設置爲true的隊列只可以在本次的連接中被訪問,新的隊列就會被排外不能訪問。
autoDelete :是否自動刪除,也就是關閉connection的時候隊列裏面的數據是否自動刪除。
arguments :隊列的屬性,如構造參數。(應該沒翻譯錯吧other properties (construction arguments) for the queue)。
從RabbitMQ控制檯可以知道,消息發送成功。
消費端代碼
public class Customer {
private final static String QUEUE_NAME = "RabbitMQ.demo";
public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException, ConsumerCancelledException, InterruptedException {
// 創建連工廠
ConnectionFactory factory = new ConnectionFactory();
// 設置相關信息
factory.setHost("localhost");
// 創建一個鏈接
Connection connection = factory.newConnection();
// 創建一個通道
Channel channel = connection.createChannel();
// 在通道里聲明一個隊列
channel.queueDeclare(QUEUE_NAME, false, false, false, null)
System.out.println("消費者1消息隊列開始關注消息");
//定義隊列的消費者
QueueingConsumer consumer = new QueueingConsumer(channel);
//監聽隊列
//false表示接受消息需返回給消息隊列確認
channel.basicConsume(QUEUE_NAME, true,consumer);
//獲取消息
while(true){
TimeUnit.SECONDS.sleep(1);
QueueingConsumer.Delivery nextDelivery = consumer.nextDelivery();
//getBody()方法獲得隊列中的消息
String message = new String(nextDelivery.getBody());
System.out.println("消費者1隊列獲得了消息:"+message);
}
}
}
控制檯輸出:
Work模式
一個生產者,一個隊列,多個消費者。
生產者代碼和簡單模式一樣,消費端只需要複製多個消費者即可。
注意的是,默認情況下,多個消費者依次獲得消息,不能越界,就算你已經早早的消費了消息,但是你還是需要等待,按照順序從列隊拿消息。這顯然是不合理,應該是能者多勞。這時我們只需要在生產者加入一行:
channel.basicQos(1);//表示一個時間服務器只會發送一條消息給消費者
訂閱模式
生產者將數據發送給交換機或多個隊列,消費者從隊列中獲得。
生產者代碼:
public class Producer {
//生產者和交換機綁定了
private final static String EXCHANGE_NAME = "test_exchange_fanout";
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
// 創建連工廠
ConnectionFactory factory = new ConnectionFactory();
// 設置相關信息
factory.setHost("localhost");
// 創建一個鏈接
Connection connection = factory.newConnection();
// 創建一個通道
Channel channel = connection.createChannel();
//使用交換機,就聲明一個交還機,type=fanout
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
/*//一個時刻只會發送一條消息給消費者
channel.basicQos(1);*/
// 發佈消息到隊列中
String message = "This is 消息隊列 demo";
for (int i = 0; i < 20; i++) {
//設置路由b
channel.basicPublish(EXCHANGE_NAME, "", null, (message+i).getBytes("UTF-8"));
TimeUnit.MILLISECONDS.sleep(300);
System.out.println("生產者發送了消息:" +"["+i+"]" +message);
}
// 關閉資源
channel.close();
connection.close();
}
}
消費者1:
public class Customer {
private final static String QUEUE_NAME = "RabbitMQ1.demo";
private final static String EXCHANGE_NAME = "test_exchange_fanout";
public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException, ConsumerCancelledException, InterruptedException {
// 創建連工廠
ConnectionFactory factory = new ConnectionFactory();
// 設置相關信息
factory.setHost("localhost");
// 創建一個鏈接
Connection connection = factory.newConnection();
// 創建一個通道
Channel channel = connection.createChannel();
// 在通道里聲明一個隊列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//綁定到交換機
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
System.out.println("消費者1消息隊列開始關注消息");
//定義隊列的消費者
QueueingConsumer consumer = new QueueingConsumer(channel);
//監聽隊列
//false表示接受消息需返回給消息隊列確認
channel.basicConsume(QUEUE_NAME, true,consumer);
//獲取消息
while(true){
TimeUnit.SECONDS.sleep(1);
QueueingConsumer.Delivery nextDelivery = consumer.nextDelivery();
String message = new String(nextDelivery.getBody());
System.out.println("消費者1隊列獲得了消息:"+message);
}
}
}
消費者2和消費者代碼一樣,只需要修改QUEUE_NAME即可。
控制檯輸出:
這表明,兩個消費者都獲得了相同的消息。
路由模式
生產者將特定的消息傳給交換機,然會由交換機發送給特定的隊列,消費者只需要指定特定的路由key即可。
生產者:我們只需要修改交換機的名稱爲direct,指定路由的key即可,這裏設置key=b
消費者1:表示接受key=a的消息,其他的接收不到。
輸出:
消費者2:表示接受key=b的消息,其他的接收不到。
輸出:
統配符模式
統配符模式其實也可以歸類於路由模式,只不過統配符模式中路由的key可以使用通配符表示。代碼可以參考路由模式。只不過需要修改一下交換機類型爲topic:
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
.....
.....
//設置通配符爲a.*
channel.basicPublish(EXCHANGE_NAME, "a.*", null, (message+i).getBytes("UTF-8"));
.....
.....
這樣任何配以a.開頭的消費者都能獲得此生產者的消息。