RabbitMQ的相關概念
AMPQ:Advanced Message Queue Protocol,RabbitMQ是erlang開發的AMPQ的實現。
Message:消息,不具名,由消息頭(由路由鍵routing-key,優先權priority,持久性存儲delivery-mode等可選屬性構成)和消息體(不透明)組成。
Publisher:消息的生產者,一個向交換器發佈消息的客戶端應用程序。
Exchange:交換器,接收生產者發送的消息並將這些消息路由給服務器中的隊列。有direct,fanout,topic和headers四種類型。
Queue:消息隊列,用以保存信息直到發送給消費者。它是消息的容器,也是消息的重點。一個消息可投入一個或多個隊列。
Binding:綁定,用於消息隊列和交換器之間的關聯。一個綁定就是基於路由鍵將交換器和消息隊列連接起來的路由規則,交換器可以看成是一個由綁定構成的路由表。
Connection:網絡連接,如一個TCP連接。
Channel:信道,多路複用連接中的一條獨立的雙向數據流通道,引入信道概念,以複用一條TCP連接。
Consumer:消息的消費者,表示一個從消息隊列中取得消息的客戶端應用程序。
Virtual Host:虛擬主機,表示一批交換器、消息隊列和相關對象。虛擬主機是共享相同的身份認證加密環境的獨立服務器域,每個vhost本質上就是一個mini版的RabbitMQ服務器,擁有自己的隊列、交換器、綁定和權限機制。vhost必須在連接時指定,RabbitMQ默認的vhost是/
。
Broker:表示消息隊列服務器實體。
RabbitMQ的幾種模式
https://www.rabbitmq.com/tutorials/tutorial-three-python.html
-
簡單模式:一對一,即一個生產者對應一個消費者。
-
Work隊列:一個生產者對應多個消費者,但是隻能有一個消費者獲得消息。
-
發佈/訂閱Publish/Subscribe:發佈者將消息發送到交換器,交換器綁定多個隊列,監聽這些隊列的訂閱者都能收到消息,也就是我們後面要說的fanout。
-
路由Routing:交換器和隊列通過路由鍵綁定,生產者將消息發送到交換器時指定路由鍵,只會發送到對應的隊列,監聽該隊列的消費者收到信息。
-
主題Topics:和Routing路由模式一樣,都是匹配路由鍵,只不過Topic是通過通配符匹配。
#
匹配0個或多個單詞,*
匹配一個單詞。
Exchange的四種類型
除了headers之外,其他和路由模式、發佈訂閱模式和通配符模式一一對應。
direct:完全匹配、單播模式。消息中的路由鍵(routing key)如果和 Binding 中的 binding key 一致, 交換器就將消息發到對應的隊列中。
fanout:每個發到 fanout 類型交換器的消息都會分到所有綁定的隊列上去。fanout 交換器不處理路由鍵,只是簡單的將隊列綁定到交換器上,每個發送到交換器的消息都會被轉發到與該交換器綁定的所有隊列上。很像子網廣播,每臺子網內的主機都獲得了一份複製的消息。fanout 類型轉發消息是最快的。
topic:topic 交換器通過模式匹配分配消息的路由鍵屬性,將路由鍵和某個模式進行匹配,此時隊列需要綁定到一個模式上。它將路由鍵和綁定鍵的字符串切分成單詞,這些單詞之間用點隔開。它同樣也會識別兩個通配符:符號#
和符號*
。#
匹配0個或多個單詞,*
匹配一個單詞。
headers:匹配AMPQ消息的header而不是路由鍵,headers交換器和direct交換器完全一致,但性能差很多,幾乎不用。
Linux系統上Rabbitmq的安裝
docker pull rabbitmq:3-management # management帶web界面管理
docker run -d --name myrabbit -p 5672:5672 -p 15672:15672 cc86ffa2f398 #啓動
systemctl status firewalld #查看防火牆的狀態【(running)意思是打開,我們需要設置開放的端口】
firewall-cmd --list-ports #查看防火牆開放的端口
firewall-cmd --zone=public --add-port=15672/tcp --permanent # 開放15672
firewall-cmd --zone=public --add-port=5672/tcp --permanent # 開放5672
firewall-cmd --reload # 使修改生效
此時就可以通過http://192.168.213.129:15672/
訪問rabbitmq管理界面,賬號密碼默認都是guest。如果是在雲服務器上部署,需要設置15672和5672安全組。
RabbitMQ的Web界面操作
RabbitMQ的web管理界面
創建帳號並設置其角色爲管理員:smday
設置Virtual Hosts
給創建的用戶設置虛擬Host權限
Exchange的添加操作及參數介紹
結構化參數其實就是一個Map,key是指定字符串,比如這裏的Alternate-exchange,如果exchange1指定了Alternate-exchange
的值爲exchange2,那麼如果消息無法匹配exchange1綁定的queue1,它會嘗試通過exchange2路由到exchange2綁定的queue2。
Queue的添加操作及參數介紹
大致差不多,可以看看它的一些結構化參數:
https://www.cnblogs.com/LiangSW/p/6224333.html
參數名key | 值value類型 | 解釋 |
---|---|---|
x-message-ttl | Number | Time-to-Live指消息在隊列中存活的最長的時間 |
x-expires | Number | 指定毫秒內,若隊列未被使用則自定刪除 |
x-max-length | Number | 隊列的消息最大條數 |
x-max-length-bytes | Number | 消息的最大佔用大小 |
x-dead-letter-exchange | String | 死信發生,重新發送該消息到指定交換器 |
x-dead-letter-routing-key | String | 死信發生,重新指定路由鍵 |
x-max-priority | Number | 設置的數字爲最大優先級數,如果沒設置則不支持優先級 |
x-queue-mode | String | 默認爲default,可設爲lazy,將內容儘早移入磁盤 |
x-single-active-consumer | Boolean | 如果設置,確保每次只有一個使用者從隊列中消費,若其被取消或死亡時故障轉移到另一個已註冊的使用者。 |
x-overflow | String | 設置隊列溢出行爲:drop-head, reject-publishor reject-publish-dlx |
x-queue-master-locator | String | 將隊列設置爲主位置模式,確定在節點集羣上聲明隊列主位置時所使用的規則。 |
快速體驗
導入消息隊列相關依賴
<!--消息隊列相關依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
配置yml
spring:
rabbitmq:
host: 121.199.16.31 # rabbitmq的連接地址
virtual-host: /smday # rabbitmq的虛擬host
username: xxx # rabbitmq的用戶名
password: xxx # rabbitmq的密碼
publisher-confirms: true #如果對異步消息需要回調必須設置爲true
進行測試
@SpringBootTest
class SpringbootAmqpApplicationTests {
@Autowired
RabbitTemplate rabbitTemplate;
@Test
void contextLoads() {
Map<String,Object> map = new HashMap<>();
map.put("msg","hello");
map.put("data", Arrays.asList("1","2"));
//對象被默認序列化後發送出去
rabbitTemplate.convertAndSend("exchange.direct","summerday.news",map);
}
@Test
public void receive(){
//接收消息之後,隊列中消失
Object o = rabbitTemplate.receiveAndConvert("summerday.news");
System.out.println(o.getClass());
System.out.println(o);
}
@Test
public void fanout(){
rabbitTemplate.convertAndSend("exchange.fanout","","xxx");
}
}
自定義messageconverter
@Configuration
public class MyAMPQConfig {
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}
消費者監聽事件,收到隊列中的消息
@Service
public class BookService {
@RabbitListener(queues = "atguigu.news")
public void receive(Book book){
System.out.println("收到消息: "+book);
}
@RabbitListener(queues = "summerday.news")
public void receive01(Message message){
System.out.println(message.getBody());
System.out.println(message.getMessageProperties());
}
}
使用Amqpadmin創建
@Autowired
AmqpAdmin amqpAdmin;
@Test
public void createExchange(){
amqpAdmin.declareExchange(new DirectExchange("amqpadmin.exchange"));
System.out.println("創建完成!");
}
@Test
public void createQueue(){
amqpAdmin.declareQueue(new Queue("amqpadmin.queue",true));
System.out.println("創建完成!");
}
@Test
public void bind(){
amqpAdmin.declareBinding(new Binding("amqpadmin.queue", Binding.DestinationType.QUEUE,"amqpadmin.exchange","amqp.haha", null));
}
參考鏈接
https://www.cnblogs.com/ysocean/p/9251884.html
https://www.rabbitmq.com/getstarted.html