概述
RabbitMQ是一個由Erlang語言開發的基於AMPQ標準的開源實現。
具有以下特點:
1.可靠性:可以通過消息確認,消息持久化來保證可靠性
2.具有靈活的路由:消息在進入隊列之前是通過Exchange來路由消息的。
3.支持消息集羣
4.支持多語言客戶端
5.支持跟蹤機制
基本概念
如上圖所示,Rabbit的關鍵元素
關鍵需要理解的有兩點
1.路由機制
消息到達Broker後會先經過Exchange,這過程還隱藏着一個元素,那就是route key,一般發消息會指定一個route key,Exchange通過檢查這個route key與Bindingz中的binding key來決定投到哪一個Queue。
2.信道
我們知道連接是一種很昂貴的資源,RabbitMQ爲了儘量少的減少Connection的開銷,採用信道也就是Channel來多路複用,即在一個連接中可以存在多個Channel,Channel是建立在真實的TCP連接中的虛擬連接。
交換器類型
不同的交換器發生消息的策略也不同,目前交換器有四種,Direct, Fannot, Topic, Headers,其中Headers由於和Direct交換機差不多,所以基本不用,不作解釋。
Direct
這種方式強調的是單播,完全匹配。即消息中的路由鍵要和Binding中的綁定建完全一致,交換器就會把消息發送到對應的隊列中去。
Fanout
Fanout強調廣播,Fanout不處理路由鍵,只是簡單的將隊列綁定到交換器上。通過Fanout是最快的。
Topic
Topic 交換器是通過模式匹配分配消息的路由鍵屬性,將錄用後鍵和某種模式進行匹配。
關鍵點,路由鍵通過點分割,綁定建通過#來表示0或多個,*表示不少於一個
java訪問實例
public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
connectionFactory.setHost("129.204.174.193");
connectionFactory.setVirtualHost("/");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
String exchangeName = "hello-exchange";
channel.exchangeDeclare(exchangeName, "direct", true);
String queueName = channel.queueDeclare().getQueue();
String routingKey = "testRoutingKey";
channel.queueBind(queueName, exchangeName, routingKey);
while (true) {
boolean autoAck = false;
String consumerTag = "";
channel.basicConsume(queueName, autoAck, consumerTag, new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) throws IOException {
String routingKey = envelope.getRoutingKey();
String contentType = properties.getContentType();
System.out.println("消費的路由鍵:" + routingKey);
System.out.println("消費的內容類型:" + contentType);
long delivryTag = envelope.getDeliveryTag();
channel.basicAck(delivryTag, false);
System.out.println("消費的信息體內容:");
String bodyStr = new String(body, "UTF-8");
System.out.println(bodyStr);
}
});
}
}
}
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
//創建連接工廠
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("guest");
factory.setPassword("guest");
factory.setHost("129.204.174.193");
factory.setVirtualHost("/");
Connection conn = factory.newConnection();
Channel channel = conn.createChannel();
String exchangeName = "hello-exchange";
channel.exchangeDeclare(exchangeName, "direct", true);
String routingKey = "testRoutingKey";
byte[] messageBodyBytes = "quit".getBytes();
channel.basicPublish(exchangeName, routingKey, null, messageBodyBytes);
channel.close();
conn.close();
}
}
以上是直接用java連接,當然我們可以選擇用Spring 或 springboot來處理,這樣我們就不必自己來創建連接,做配置了,直接操作RabbitTemplate要方便的多。
持久化
爲了消息不丟失,我們需要做持久化,關鍵點是,持久化我們要對交換器,隊列,消息都進行持久化,交換器和隊列在聲明時候有個durable的參數設置成ture就可以了,消息在發生時,配置BasicProperties,把deliveryMode設置成2就可以了
消息確認
消息確認存在兩個地方,一個是由生產者向Broker,二是Broker向消費者
使用場景
消息異步
消息推送
能夠推送在於RabbitMQ居然連js都能操作,我們在js裏聲明客戶端,然後監聽隊列。