rabbitmq direct 多个消费者_RabbitMQ实战应用技巧
1. RabbitMQ實戰(zhàn)應(yīng)用技巧
1.1. 前言
由于項目原因,之后會和RabbitMQ比較多的打交道,所以讓我們來好好整理下RabbitMQ的應(yīng)用實戰(zhàn)技巧,盡量避免日后的采坑
1.2. 概述
RabbitMQ有幾個重要的概念:虛擬主機,交換機,隊列和綁定
- 虛擬主機:一個虛擬主機持有一組交換機、隊列和綁定,我們可以從虛擬主機層面的顆粒度進行權(quán)限控制
- 交換機:Exchange用于轉(zhuǎn)發(fā)消息,它并不存儲消息,如果沒有Queue隊列綁定到Exchange,它會直接丟棄掉生產(chǎn)者發(fā)來的數(shù)據(jù)。
交換機還有個關(guān)聯(lián)的重要概念:路由鍵,消息轉(zhuǎn)發(fā)到哪個隊列根據(jù)路由鍵決定 - 綁定:就是綁定交換機和隊列,它是多對多的關(guān)系,也就是說多個交換機可以綁同一個隊列,也可以一個交換機綁多個隊列
1.3. 交換機
交換機有四種類型的模式Direct, topic, Headers and Fanout
1.3.1. Direct Exchage
Direct模式使用的是RabbitMQ的默認交換機,也是最簡單的模式,適合比較簡單的場景
如下圖所示,使用Direct模式,我們需要創(chuàng)建不同的隊列,而默認交換機則通過Routing key路由鍵的值來決定轉(zhuǎn)發(fā)到哪個隊列,可以看到,路由鍵綁定隊列是可以指定多個的
1.3.2. Topic Exchange
Topic模式主要是根據(jù)通配符匹配,也就類似于模糊匹配,當這種匹配模式和路由鍵匹配后交換機就能轉(zhuǎn)發(fā)消息到指定隊列
- 路由鍵為一串字符串,由句號(.)隔開,比如a.b.c
- (*)代表指定位置一個單詞,(#)代表零個或者多個單詞,比如a.*.b.#,表示a和b中間隨意填個單詞,b后面可以跟n個單詞,比如a.x.b.c.d.e
Topic模式和Direct模式的區(qū)別在于交換機需要自己指定,路由鍵支持模糊匹配,例如:
rabbitTemplate.convertAndSend("topicExchange","a.x.b.d", " hello world!");1.3.3. Headers Exchage
Headers也是根據(jù)規(guī)則匹配,但它不是根據(jù)路由鍵了,headers有個自定義匹配規(guī)則,它將匹配鍵值設(shè)在了消息的headers屬性上,當這些鍵值對有一對或者全部匹配時,消息才會被投遞到對應(yīng)隊列,這種模式效率相對較低,一般不推薦使用
1.3.4. Fanout Exchange
Fanout即為大名鼎鼎的廣播模式了,它不需要管路由鍵,會把消息發(fā)給綁定它的全部隊列,就算配置了路由鍵也會被忽略
1.4. 復(fù)雜情況
1.5. springboot配置
我們的常用配置如下
spring.rabbitmq.addresses=localhost:5672 spring.rabbitmq.username=user spring.rabbitmq.password=123456 spring.rabbitmq.virtual-host=/ spring.rabbitmq.connection-timeout=1000 ##設(shè)置監(jiān)聽限制:最大10,默認5 spring.rabbitmq.listener.simple.concurrency=5 spring.rabbitmq.listener.simple.max-concurrency=10 spring.rabbitmq.publisher-confirms=true spring.rabbitmq.publisher-returns=true spring.rabbitmq.template.mandatory=true spring.rabbitmq.listener.simple.acknowledge-mode=manual其中最后四條配置需要著重解釋:
- spring.rabbitmq.publisher-confirms為true,表示生產(chǎn)者消息發(fā)出后,MQ的broker接收到了消息,發(fā)送回執(zhí)表示確認接收,不設(shè)置則可能導致消息丟失
- spring.rabbitmq.publisher-returns為true,表示當消息不能到達MQ的Broker端,,則使用監(jiān)聽器對不可達的消息做后續(xù)處理,這種一般是路由鍵沒配好,或MQ宕機才可能發(fā)生
- spring.rabbitmq.template.mandatory當上面兩個為true時,這個一定要配true,否則上面兩個不起作用
- spring.rabbitmq.listener.simple.acknowledge-mode這個為manual表示手工確認,實際生產(chǎn)應(yīng)該設(shè)為手工,才能保證你的業(yè)務(wù)是處理完成的,注意業(yè)務(wù)的冪等性,可重復(fù)調(diào)用,手工確認代碼如下例子
1.6. 隊列屬性
- 比如添加x-message-ttl為5000,則表示消息超過5秒沒被處理就會超時過期;
- x-expires設(shè)置120000表示隊列在2分鐘內(nèi)沒被消費則被刪除;
- x-max-length,x-max-length-bytes表示傳送數(shù)據(jù)的最大長度和字節(jié)數(shù)
- x-dead-letter-exchange,x-dead-letter-routing-key表示死信交換機和死信路由,放在需要過期或處理失敗的隊列屬性中,這些數(shù)據(jù)會轉(zhuǎn)發(fā)到死信隊列存儲起來,創(chuàng)建普通的交換機和隊列綁定,把交換機名填到x-dead-letter-exchange的值,填寫路由鍵要符合死信隊列的路由鍵
- x-max-priority,表示設(shè)置優(yōu)先級,范圍為0~255,只有當消息堆積的時候,這個優(yōu)先級才有意義,數(shù)字越大優(yōu)先級越高
- x-queue-mode當為lazy,表示惰性隊列,3.6.0之后才被引入的概念,相比默認的模式,惰性隊列模式會將生產(chǎn)者產(chǎn)生的消息直接存到磁盤中,這當然會增加IO開銷,但適合應(yīng)對大量消息堆積的情況;因為當大量消息堆積時,內(nèi)存也不夠存放,會將消息轉(zhuǎn)存到磁盤,這個過程也是比較耗時且過程中不能接收新的消息。如果需要將普通隊列轉(zhuǎn)換成惰性隊列需要將原來的隊列刪除,重新創(chuàng)建個惰性隊列綁定。
1.7. 交換機屬性
- 如下圖:exchange0設(shè)置了alternate-exchange交換機為exchange1,生產(chǎn)者發(fā)送數(shù)據(jù)到exchange0路由鍵為test1,在exchange0路由不到,則轉(zhuǎn)發(fā)到exchange1判斷路由符合,發(fā)送到隊列queue1
1.8. 磁盤和內(nèi)存
在RabbitMQ的管理界面,當我們集群部署時可以看到Nodes節(jié)點中Info字段可能為disc也可能ram,表示了磁盤存儲或內(nèi)存儲存。事實上,在集群部署的時候,我們至少要一個磁盤儲存,它代表了將交換機,隊列,綁定,用戶等元數(shù)據(jù)持久化保存到磁盤,一遍重啟RabbitMQ也能恢復(fù)到原先的狀態(tài),當只有一個節(jié)點時,必定是磁盤存儲;而內(nèi)存儲存也有它的優(yōu)勢,就是效率更高速度更快
1.9. 報錯案例
- 當報下列錯誤,表示你一定存在排他性隊列,也就是設(shè)置了exclusive屬性的隊列,由于同一個連接創(chuàng)建的不同通道可以訪問同一個隊列,此時由于這個排他屬性會得到資源被鎖定錯誤,也就是下列的錯誤。
- 由此我們可以知道,若你把隊列設(shè)置成了exclusive屬性的,那么就別創(chuàng)建新的連接去訪問同一個隊列
總結(jié)
以上是生活随笔為你收集整理的rabbitmq direct 多个消费者_RabbitMQ实战应用技巧的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BlogEngine(4)---Widg
- 下一篇: 正则表达式简明使用手册