1.概述
1.1 官方:
https://www.rabbitmq.com/tutorials/tutorial-one-java.html
RabbitMQ是消息代理:它接受並轉發消息。您可以將其視爲郵局:將要發佈的郵件放在郵箱中時,可以確保Mailperson先生或女士最終將郵件傳遞給收件人。以此類推,RabbitMQ是一個郵箱,一個郵局和一個郵遞員。
RabbitMQ與郵局之間的主要區別在於,它不處理紙張,而是接收,存儲和轉發數據消息的二進制斑點。
1.2 RabbitMQ和消息傳遞通常使用一些術語。
-
生產僅意味着發送。發送消息的程序是生產者:
-
隊列是RabbitMQ內部的郵箱的名稱。儘管消息流經RabbitMQ和您的應用程序,但它們只能存儲在隊列中。甲隊列僅由主機的存儲器&磁盤限制約束,它本質上是一個大的消息緩衝器。許多生產者可以發送進入一個隊列的消息,許多消費者可以嘗試從一個隊列接收數據。這就是我們表示隊列的方式:
-
消費與接收具有相似的含義。一個消費者是一個程序,主要是等待接收信息:
請注意,生產者,消費者和經紀人不必位於同一主機上。實際上,在大多數應用程序中它們不是。一個應用程序既可以是生產者,也可以是消費者。
2.代碼示例
2.1 依賴:
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>4.5.0</version>
</dependency>
2.2.連接工具類
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* 創建連接工具類
*/
public class ConnectionUtil {
public static Connection getConnection() throws Exception{
//定義一個連接工廠
ConnectionFactory factory = new ConnectionFactory();
//設置服務地址
factory.setHost("192.168.236.128");
//Overview -- Listening ports
//amqp 5672
factory.setPort(5672);
factory.setUsername("test");
factory.setPassword("test");
//VirtualHost(admin--Virtual Hosts)
factory.setVirtualHost("/test");
return factory.newConnection();
}
}
2.3.發送者
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.shm.demo.util.ConnectionUtil;
/**
* 消息發送者
*/
public class Sender {
private final static String QUEUE = "testhello";//隊列名稱
public static void main(String[] args) throws Exception {
//1.獲取連接
Connection connection = ConnectionUtil.getConnection();
//2.創建通道
Channel channel = connection.createChannel();
//3.聲名隊列
//參數1:隊列的名稱
//參數2:是否持久化隊列,我們的隊列模式是在內存中的,如果RabbitMQ重啓會丟失,如果設置爲true,則會保存在erlang自帶的數據庫中,重啓後恢復
//參數3:是否排外,有兩個作用,第一個當我們的連接關閉後是否自動刪除隊列;第二,是否私有當前隊列,如果私有,其它通道不可訪問
//參數4:是否自動刪除
//參數5:一些其它參數
channel.queueDeclare(QUEUE,false,false,false,null);
//4.發送消息
String msg = "這是我發送的消息!";
channel.basicPublish("",QUEUE,null,msg.getBytes());
//5.關閉連接
channel.close();
connection.close();
}
}
2.4.消費者
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.shm.demo.util.ConnectionUtil;
/**
* 消息消費者
*/
public class Recv {
private final static String QUEUE = "testhello";//隊列名稱
public static void main(String[] args) throws Exception {
//1.獲取連接
Connection connection = ConnectionUtil.getConnection();
//2.創建通道
Channel channel = connection.createChannel();
//3.聲名隊列
//參數1:隊列的名稱
//參數2:是否持久化隊列,我們的隊列模式是在內存中的,如果RabbitMQ重啓會丟失,如果設置爲true,則會保存在erlang自帶的數據庫中,重啓後恢復
//參數3:是否排外,有兩個作用,第一個當我們的連接關閉後是否自動刪除隊列;第二,是否私有當前隊列,如果私有,其它通道不可訪問
//參數4:是否自動刪除
//參數5:一些其它參數
channel.queueDeclare(QUEUE,false,false,false,null);
//定義消費者
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE,true,consumer);//參數2是自動確認
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String msg = new String(delivery.getBody());
System.out.println(msg);
}
}
3. 不足:
耦合性高,生產者一一對應消費者(不支持多個消費者)