中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

免費(fèi)下載ppt模板網(wǎng)站哪個(gè)好免費(fèi)網(wǎng)站模板庫(kù)

免費(fèi)下載ppt模板網(wǎng)站哪個(gè)好,免費(fèi)網(wǎng)站模板庫(kù),網(wǎng)站建設(shè)云平臺(tái),wordpress登錄評(píng)論1、什么是MQ? MQ全稱(chēng)message queue(消息隊(duì)列),本質(zhì)是一個(gè)隊(duì)列,FIFO先進(jìn)先出,是消息傳送過(guò)程中保存消息的容器,多 用于分布式系統(tǒng)之間進(jìn)行通信。 在互聯(lián)網(wǎng)架構(gòu)中,MQ是一種非常常見(jiàn)的…
1、什么是MQ?

MQ全稱(chēng)message queue(消息隊(duì)列),本質(zhì)是一個(gè)隊(duì)列,FIFO先進(jìn)先出,是消息傳送過(guò)程中保存消息的容器,多 用于分布式系統(tǒng)之間進(jìn)行通信。

在互聯(lián)網(wǎng)架構(gòu)中,MQ是一種非常常見(jiàn)的上下游“邏輯解耦+物理解耦”的消息通訊服務(wù),使用了MQ后,消息發(fā)送上游只需要依賴(lài)MQ,不需要依賴(lài)其他的服務(wù)。

2、為什么使用MQ?
  1. 流量削峰
  2. 應(yīng)用解耦
    1. 比如電商系統(tǒng)中分為訂單系統(tǒng),支付系統(tǒng),庫(kù)存系統(tǒng),物流系統(tǒng),如果訂單系統(tǒng)直接調(diào)用三種系統(tǒng),其中一個(gè)系統(tǒng)出現(xiàn)了短暫的故障,訂單系統(tǒng)就屬于不可用的狀態(tài),
    2. 如果使用mq,訂單系統(tǒng)生成的訂單直接存放在MQ中,即便其余某個(gè)系統(tǒng)短暫故障,訂單系統(tǒng)不感知,系統(tǒng)可用性增強(qiáng)
  3. 異步處理
    1. 假設(shè)A調(diào)用B ,B是異步處理并且需要很長(zhǎng)時(shí)間來(lái)處理,但是A需要知道B的處理結(jié)果,通常做法是
      1. A每隔一段時(shí)間去調(diào)用B的查詢(xún)函數(shù),
      2. 或者A提供一個(gè)回調(diào)函數(shù)讓B調(diào)用完成之后通知A。
    2. MQ提供了一種新的處理思路,即B處理完之后,發(fā)送一條消息給MQ,MQ將消息給A進(jìn)行處理。
3、實(shí)現(xiàn)MQ的兩種主流方式?

兩種,AMQP和JMS

  1. AMQP即 Advanced Message Queuing Protocol(高級(jí)消息隊(duì)列協(xié)議),是一個(gè)網(wǎng)絡(luò)協(xié)議,是應(yīng)用層協(xié)議的一個(gè)開(kāi)放標(biāo)準(zhǔn),為面向消息的中間件設(shè)計(jì)的。
  2. JMS?即 Java 消息服務(wù)(Java Message Service)應(yīng)用程序接口,是一個(gè)java平臺(tái)中關(guān)于面向消息中間件的API。是javaEE規(guī)范的一種。

區(qū)別?

  • JMS定義了統(tǒng)一的接口,來(lái)對(duì)消息操作進(jìn)行統(tǒng)一,而AMQP是通過(guò)協(xié)議規(guī)定了數(shù)據(jù)交互格式
  • JMS限制了必須使用java,AMQP只是協(xié)議,不規(guī)定實(shí)現(xiàn)方式,是跨語(yǔ)言的
  • JMS規(guī)定了兩種消息模式,AMQP的消息模式更加豐富

4、MQ的選擇?
  1. kafka:主要特點(diǎn)是基于pull的模式來(lái)處理消息消費(fèi),追求高吞吐量,一開(kāi)始的目的就是用于日志收集和傳輸,適合產(chǎn)生大量數(shù)據(jù)的數(shù)據(jù)收集業(yè)務(wù),如果有日志采集功能,首選kafka
  2. rocketMQ: 適用于金融互聯(lián)網(wǎng)領(lǐng)域,對(duì)可靠性要求很高的場(chǎng)景適用(阿里雙11),尤其是電商里面的訂單扣款、業(yè)務(wù)削峰等,穩(wěn)定性好,適用于并發(fā)場(chǎng)景。
  3. rabbitMQ:性能好,時(shí)效性微妙級(jí)別,社區(qū)活躍度高,功能完備,管理界面使用方便,適合數(shù)據(jù)量沒(méi)有那么大的中小型公司。

5、rabbitMQ中的四大核心概念?
  1. 生產(chǎn)者:產(chǎn)生數(shù)據(jù),發(fā)送消息的程序
  2. 交換機(jī):rabbitMQ中非常重要的一個(gè)部件,一方面接收來(lái)自生產(chǎn)者的消息,另一方面將消息推送到隊(duì)列中。(交換機(jī)必須要確切知道如何處理接收到的消息)
  3. 隊(duì)列:存放消息的數(shù)據(jù)結(jié)構(gòu),本質(zhì)是一個(gè)大的消息緩沖區(qū)
  4. 消費(fèi)者:大多數(shù)情況是一個(gè)等待接收消息的程序

6、rabbitMQ的基本結(jié)構(gòu)?

  • producer:消息生產(chǎn)者,即生產(chǎn)消息的客戶(hù)端
  • consumer:消息消費(fèi)者,即消費(fèi)消息的客戶(hù)端,接收MQ轉(zhuǎn)發(fā)的消息
  • connection:producer/consumer 和broker之間的TCP連接
  • channel:如果每一次訪(fǎng)問(wèn)rabbitMQ都建立一個(gè)connection,在消息量大的時(shí)候建立TCP連接的開(kāi)銷(xiāo)是巨大的,效率也很低,channel是在connection內(nèi)部建立的邏輯連接,一個(gè)連接內(nèi)包含多個(gè)信道,每次發(fā)消息只占用一個(gè)信道,這樣就極大的減少了建立connection的開(kāi)銷(xiāo)。
  • broker:接收和分法消息的應(yīng)用,消息隊(duì)列的服務(wù)進(jìn)程,包括兩個(gè)部分,exchange和queue
  • exchange:消息隊(duì)列交換機(jī),按照一定的規(guī)則將消息路由轉(zhuǎn)發(fā)給到某個(gè)隊(duì)列,對(duì)消息進(jìn)行過(guò)濾
  • queue:消息隊(duì)列,存儲(chǔ)消息
  • binding:exchange和queue之間的虛擬連接

生產(chǎn)者生產(chǎn)消息的過(guò)程:

  1. producer先連接到broker,這個(gè)步驟需要先建立connection連接,并開(kāi)啟一個(gè)信道channel
  2. producer聲明一個(gè)交換器,并設(shè)置相關(guān)屬性 (交換器寫(xiě)空字符串,會(huì)使用默認(rèn)的交換器)
  3. producer聲明一個(gè)隊(duì)列,并設(shè)置相關(guān)屬性
  4. producer通過(guò)綁定將交換器和隊(duì)列進(jìn)行綁定
  5. producer發(fā)送消息到broker,其中包含路由鍵,交換器等信息
  6. 交換器根據(jù)收到的路由鍵查找對(duì)應(yīng)的隊(duì)列
  7. 如果找到,就會(huì)將消息存入相應(yīng)的隊(duì)列,如果沒(méi)有找到,會(huì)根據(jù)producer的配置選擇丟棄或者是退回給生產(chǎn)者
  8. 關(guān)閉信道

消費(fèi)者接收消息的過(guò)程:

  1. consumer連接到broker,建立connection連接,開(kāi)啟一個(gè)信道
  2. consumer請(qǐng)求消費(fèi)相應(yīng)隊(duì)列中的消息,可以設(shè)置響應(yīng)的回調(diào)函數(shù)
  3. 等待broker回應(yīng)并投遞相應(yīng)隊(duì)列中的消息,接收消息
  4. consumer確認(rèn)收到消息,ack響應(yīng)
  5. rabbitMQ接收到ack,將隊(duì)列中的消息刪除
  6. 關(guān)閉信道。

7、rabbitMQ的消息應(yīng)答機(jī)制ack?

rabbitMQ向消費(fèi)者傳遞完消息后,會(huì)刪除該條消息(kafka中是不刪除的,這個(gè)是一點(diǎn)差異)

為了保證消息在發(fā)送過(guò)程中不丟失,rabbitMQ引入了消息應(yīng)答機(jī)制:消費(fèi)者在接收消息并處理該消息后,告訴rabbitMQ他已經(jīng)處理了,此時(shí),rabbitMQ就可以把該消息刪除了。

  1. 自動(dòng)應(yīng)答:消息一旦被消費(fèi)者接收,自動(dòng)發(fā)送ack
  2. 手動(dòng)應(yīng)答:消息接收后,不會(huì)發(fā)送ack,需要手動(dòng)調(diào)用

如何選擇應(yīng)答方式呢?

  1. 如果消息不太重要,丟失也沒(méi)有影響,那么選擇自動(dòng)ack會(huì)比較好--- 性能高,可能丟失數(shù)據(jù)
  2. 如果不允許消息丟失,那么需要選擇在消費(fèi)完成后手動(dòng)ack --- 可靠性高,性能稍差
8、rabbitMQ消息的重新入列?

如果消費(fèi)者由于某些原因失去連接,導(dǎo)致消費(fèi)者未成功發(fā)送ACK確認(rèn)應(yīng)答,RabbitMQ將會(huì)對(duì)未完全處理完的消息重新入隊(duì),如果其他消費(fèi)者可以處理,則該消息將被分配到另一個(gè)消費(fèi)者,從而保證消息未丟失。

9、rabbitMQ的持久化?
  1. 隊(duì)列持久化
  2. 消息持久化
  3. exchange持久化

持久化只是告訴rabbitMQ將消息保存到磁盤(pán),但是并不能真正的保證數(shù)據(jù)不丟失(準(zhǔn)備從內(nèi)存往磁盤(pán)寫(xiě)的時(shí)候rabbitMQ掛掉了)

隊(duì)列持久化是在定義隊(duì)列的時(shí)候,由durable參數(shù)決定的,設(shè)置為true的時(shí)候,才會(huì)持久化隊(duì)列。

Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
//第二個(gè)餐胡設(shè)置為true,代表隊(duì)列持久化
channel.queueDeclare("queue.persistent.name", true, false, false, null);

消息持久化是在發(fā)布消息的時(shí)候設(shè)置的,

//通過(guò)傳入MessageProperties.PERSISTENT_PLAIN就可以實(shí)現(xiàn)消息持久化
channel.basicPublish("exchange.persistent", "persistent", MessageProperties.PERSISTENT_TEXT_PLAIN, "persistent_test_message".getBytes());

exchange的持久化:如果不設(shè)置exchange的持久化對(duì)消息的可靠性來(lái)說(shuō)沒(méi)有什么影響,**但是同樣如果exchange不設(shè)置持久化,那么當(dāng)broker服務(wù)重啟之后,exchange將不復(fù)存在,那么既而發(fā)送方rabbitmq producer就無(wú)法正常發(fā)送消息。因此建議同樣設(shè)置exchange的持久化。

一般只需要:``channel.exchangeDeclare(exchangeName, “direct/topic/header/fanout”, true); 就是在聲明的時(shí)候講durable字段設(shè)置為true就行了。

10、rabbitMQ的分發(fā)機(jī)制,以及如何修改?

rabbitMQ默認(rèn)的分發(fā)機(jī)制是輪詢(xún)模式,是公平的,但是實(shí)際場(chǎng)景中并不適用,比如consumerA處理消息很快,consumerB處理消息很滿(mǎn),那么輪詢(xún)的機(jī)制就會(huì)導(dǎo)致consumerA有很多時(shí)間處于空閑,因此,需要修改成能者多勞的模式。

如何實(shí)現(xiàn)?

對(duì)信道進(jìn)行設(shè)置,通過(guò) BasicQos 方法設(shè)置prefetchCount = 1,需要注意的是,不公平分發(fā)只在手動(dòng)ack的時(shí)候才會(huì)生效。

?

11、rabbitMQ中的預(yù)取值?

預(yù)取值是消費(fèi)者信道最大傳輸信息數(shù)。上面說(shuō)了如何設(shè)置rabbitMQ 的不公平分發(fā),即設(shè)置prefetchCount = 1,其實(shí)這個(gè)值是可以設(shè)置更大的數(shù)字的,這個(gè)設(shè)置的值,就是預(yù)取值。

我們將慢的消費(fèi)者preCount取值為5,快的消費(fèi)者預(yù)取值為2,然后發(fā)送7條消息,實(shí)際慢的服務(wù)器會(huì)收到5條消息(第一條處理的時(shí)候,其余四條會(huì)堆積),快的服務(wù)器只會(huì)收到2條消息。

這是因?yàn)榭斓南M(fèi)者信道滿(mǎn)了,不能再發(fā)送消息,所以消息只能發(fā)送給慢的服務(wù)器,這就是basicQos用法。

12、rabbitMQ的發(fā)布確認(rèn)機(jī)制?

發(fā)布確認(rèn)機(jī)制有三種方式:

  1. 單個(gè)確認(rèn)發(fā)布:一種簡(jiǎn)單的同步確認(rèn)發(fā)布的方式,也即是只有前一個(gè)發(fā)布的消息確認(rèn)發(fā)布之后,后續(xù)的消息才可以繼續(xù)發(fā)布。 缺點(diǎn)就是發(fā)布速度慢,沒(méi)有確認(rèn)發(fā)布的消息會(huì)阻塞后續(xù)消息發(fā)布,適用于每秒數(shù)百條消息吞吐量的環(huán)境。
  2. 批量確認(rèn)發(fā)布:也是同步確認(rèn)的方式,一樣會(huì)阻塞后續(xù)消息的發(fā)布,但是可以先發(fā)布一批消息,然后一起確認(rèn),提高吞吐量,缺點(diǎn)就是發(fā)生故障導(dǎo)致發(fā)布失敗后,不知道那個(gè)消息有問(wèn)題,必須將整個(gè)批處理保存在內(nèi)存中,來(lái)記錄重要的信息,然后重新發(fā)布消息
  3. 異步確認(rèn)發(fā)布:效率和可靠性都比較高,利用回調(diào)函數(shù)來(lái)達(dá)到消息的可靠性傳遞(這種情況下,所有在該信道上發(fā)布的消息都會(huì)被指派一個(gè)唯一的ID ,一旦消息被投遞到所有匹配的隊(duì)列后,rabbitMQ就會(huì)發(fā)送一個(gè)確認(rèn)給生產(chǎn)者(包含這個(gè)消息的唯一id),這樣生產(chǎn)者就知道消息已經(jīng)正確的到達(dá)目的隊(duì)列了,如果rabbitMQ沒(méi)能處理這個(gè)消息,也會(huì)發(fā)送一個(gè)NACK 的消息給producer,這時(shí)就可以進(jìn)行重試操作。)
13、如何處理異步未確認(rèn)的消息?

簡(jiǎn)陋版本:

將未確認(rèn)的消息放到一個(gè)基于內(nèi)存的,能夠被發(fā)布線(xiàn)程訪(fǎng)問(wèn)的隊(duì)列中,能夠在confirm callbacks線(xiàn)程和發(fā)布線(xiàn)程之間進(jìn)行消息傳遞。

比如使用ConcurrentSkipListMap,這個(gè)是基于并發(fā)的有序map集合。(ConcurrentHashMap是無(wú)序的)

1、RabbitMQ的消息確認(rèn)機(jī)制確保了消息的可靠抵達(dá),其中ConfirmCallback是其中一種實(shí)現(xiàn)方式
  1. ConfirmCallback是一個(gè)回調(diào)函數(shù),用于在消息被確認(rèn)時(shí)進(jìn)行回調(diào),以確保消息已經(jīng)被正確地發(fā)送到RabbitMQ Broker并被處理。當(dāng)生產(chǎn)者發(fā)送消息時(shí),可以通過(guò)調(diào)用channel的confirmSelect()方法將channel設(shè)置為confirm模式,然后通過(guò)添加ConfirmCallback回調(diào)函數(shù)來(lái)處理消息確認(rèn)。
  2. 當(dāng)消息被發(fā)送到Broker后,如果Broker成功地將消息路由到目標(biāo)隊(duì)列,則會(huì)調(diào)用ConfirmCallback回調(diào)函數(shù)的handleAck()方法,表示消息已被確認(rèn)。如果Broker無(wú)法將消息路由到目標(biāo)隊(duì)列,則會(huì)調(diào)用handleNack()方法,表示消息未被確認(rèn)
  3. 使用ConfirmCallback可以確保消息已經(jīng)被正確地發(fā)送到RabbitMQ Broker并被處理,從而避免了消息丟失或重復(fù)發(fā)送的情況。同時(shí),ConfirmCallback還可以在消息未被確認(rèn)時(shí)進(jìn)行重試或記錄日志等操作,以確保消息的可靠性和穩(wěn)定性。
2、RabbitMQ的ReturnCallback機(jī)制是為了解決消息無(wú)法路由到指定隊(duì)列的問(wèn)題。
  1. 當(dāng)發(fā)送的消息無(wú)法被路由到指定隊(duì)列時(shí),RabbitMQ會(huì)將消息返回給生產(chǎn)者,這時(shí)候如果生產(chǎn)者設(shè)置了ReturnCallback回調(diào)函數(shù),就可以在回調(diào)函數(shù)中處理這種情況
  2. ReturnCallback機(jī)制的使用場(chǎng)景一般是在消息發(fā)送時(shí),指定了mandatory參數(shù)為true,表示如果消息無(wú)法被路由到指定隊(duì)列,則將消息返回給生產(chǎn)者。如果mandatory參數(shù)為false,則消息會(huì)被直接丟棄。
  3. 當(dāng)生產(chǎn)者設(shè)置了ReturnCallback回調(diào)函數(shù)后,RabbitMQ在將消息返回給生產(chǎn)者時(shí),會(huì)觸發(fā)該回調(diào)函數(shù)。在ReturnCallback回調(diào)函數(shù)中,可以處理消息無(wú)法路由的情況,例如重發(fā)消息、記錄日志等。
  4. 需要注意的是,ReturnCallback機(jī)制只有在消息被發(fā)送到交換機(jī)后,才會(huì)觸發(fā)。如果消息發(fā)送的交換機(jī)不存在,或者路由鍵不符合任何綁定規(guī)則,消息會(huì)被直接丟棄,不會(huì)觸發(fā)ReturnCallback回調(diào)函數(shù)。
3、備份交換機(jī)

通過(guò)mandatory參數(shù)和消息回退機(jī)制,可以處理交換機(jī)投遞失敗的消息,但是消息回退給生產(chǎn)者后,有時(shí)候并不知道如何處理這些消息,最多就是打印一個(gè)日志,存在緩存中,然后定時(shí)重試投遞,還要考慮多次投遞失敗后的告警等等。如果生產(chǎn)者多了的話(huà),每個(gè)生產(chǎn)者都要寫(xiě)這些邏輯代碼,無(wú)疑大大增加了生產(chǎn)者的復(fù)雜性。

rabbitMQ中有死信隊(duì)列可以處理消費(fèi)失敗的信息,但是當(dāng)前所說(shuō)的這些消息根本就沒(méi)有進(jìn)入隊(duì)列,因此死信隊(duì)列也沒(méi)有用。在?RabbitMQ?中,有一種備份交換機(jī)的機(jī)制存在,可以很好的應(yīng)對(duì)這個(gè)問(wèn)題。

備份交換機(jī)可以理解為 RabbitMQ 中交換機(jī)的“備胎”,當(dāng)我們?yōu)槟骋粋€(gè)交換機(jī)聲明一個(gè)對(duì)應(yīng)的備份交換機(jī)時(shí),就是為它創(chuàng)建一個(gè)備胎,當(dāng)交換機(jī)接收到一條不可路由消息時(shí),將會(huì)把這條消息轉(zhuǎn)發(fā)到備份交換機(jī)中,由備份交換機(jī)來(lái)進(jìn)行轉(zhuǎn)發(fā)和處理,通常備份交換機(jī)的類(lèi)型為 Fanout ,這樣就能把所有消息都投遞到與其綁定的隊(duì)列中,然后我們?cè)趥浞萁粨Q機(jī)下綁定一個(gè)隊(duì)列,這樣所有那些原交換機(jī)無(wú)法被路由的消息,就會(huì)都進(jìn)入這個(gè)隊(duì)列了。 當(dāng)然,還可以建立一個(gè)報(bào)警隊(duì)列,用獨(dú)立的消費(fèi)者來(lái)進(jìn)行監(jiān)測(cè)和報(bào)警。

mandatory 參數(shù)與備份交換機(jī)可以一起使用的時(shí)候,如果兩者同時(shí)開(kāi)啟,備份交換機(jī)的優(yōu)先級(jí)更高。

在這里插入圖片描述

?

14、rabbitMQ中的交換機(jī)exchange

rabbitMQ消息傳遞的模型核心思想是:生產(chǎn)者生產(chǎn)的消息不直接發(fā)送到隊(duì)列,而是通過(guò)交換機(jī)。(事實(shí)上,生產(chǎn)者壓根不知道發(fā)送到了哪些隊(duì)列),交換機(jī)的功能十分簡(jiǎn)單,一方面接收來(lái)自生產(chǎn)者的消息,另一方面將消息推入隊(duì)列。

交換機(jī)必須知道如何處理接收到的消息,是放入特定的隊(duì)列,還是放入很多隊(duì)列,還是丟棄,這些是由交換機(jī)的類(lèi)型決定的。

bindings:binding其實(shí)就是exchange和queue之間的橋梁,即是綁定關(guān)系

交換機(jī)的類(lèi)型:

  1. 無(wú)名exchange(默認(rèn)exchange),聲明的時(shí)候就是一個(gè)空字符串,但是通過(guò)routingkey綁定queue
  2. 扇出交換機(jī) fanout: 就是將受到的所有消息廣播到他知道的所有隊(duì)列中,routingkey可以是空字符串
  3. 直接交換機(jī) direct:消息只到交換機(jī)綁定的隊(duì)列中,通過(guò)routingkey 來(lái)綁定,如果所有隊(duì)列的routingkey都一樣,那么就相當(dāng)于是fanout 交換機(jī)了
  4. 主題交換機(jī) topic:topic 交換機(jī)的消息的 routing_key 不能隨意寫(xiě),必須滿(mǎn)足一定的要求,它必須是一個(gè)單詞列表,以點(diǎn)號(hào)分隔開(kāi),類(lèi)似于正則表達(dá)式,*(星號(hào))可以代替一個(gè)單詞?;#(井號(hào))可以替代零個(gè)或多個(gè)單詞
  5. 頭部交換機(jī) header:不通過(guò)RoutingKey進(jìn)行分發(fā)消息,而時(shí)通過(guò)消息中內(nèi)容的headers的 key/value(鍵值對(duì))匹配隊(duì)列 (性能不高,用的少?)

15、死信和死信隊(duì)列?

什么是死信?

在rabbitMQ中,消息可能有不同的表現(xiàn),死信,顧名思義,就是dead message。死信消息通常包括以下幾種:

  • 消息被拒絕,即rabbitMQ返回了一個(gè)nack信號(hào)
  • 消息的TTL過(guò)期了
  • 消息隊(duì)列達(dá)到最大長(zhǎng)度,后續(xù)消息無(wú)法入列
  • 消息不符合要求等。。

什么是死信隊(duì)列?

死信隊(duì)列就是用于存儲(chǔ)死信的隊(duì)列,死信隊(duì)列中,有且只有死信構(gòu)成,不會(huì)存在其余類(lèi)型的消息。

死信隊(duì)列在rabbitMQ中并不會(huì)單獨(dú)存在,通常死信隊(duì)列都會(huì)綁定一個(gè)普通的消息隊(duì)列,當(dāng)綁定的消息隊(duì)列中有消息變成死信了,那么這個(gè)消息就會(huì)重新被交換機(jī)路由到指定的死信隊(duì)列中,我們可以通過(guò)對(duì)這個(gè)死信隊(duì)列進(jìn)行監(jiān)聽(tīng),從而手動(dòng)去對(duì)這些消息進(jìn)行補(bǔ)償。

如何使用死信隊(duì)列?

在 RabbitMQ 中,死信隊(duì)列的標(biāo)識(shí)為 x-dead-letter-exchange ,通過(guò)觀(guān)察死信隊(duì)列的標(biāo)識(shí),我們不難發(fā)現(xiàn),其標(biāo)識(shí)最后為 exchange ,即 RabbitMQ 中的交換機(jī),RabbitMQ 中的死信隊(duì)列就是由死信交換機(jī)而得出的,要想使用死信隊(duì)列,我們需要首先聲明一個(gè)普通的消息隊(duì)列,并將死信隊(duì)列的標(biāo)識(shí)綁定到這個(gè)普通的消息隊(duì)列上。

16,rabbitMQ中處理消息失敗了怎么辦?

生產(chǎn)環(huán)境中,使用MQ的時(shí)候設(shè)計(jì)兩個(gè)隊(duì)列:一個(gè)是業(yè)務(wù)隊(duì)列,專(zhuān)門(mén)用來(lái)處理消息,另外一個(gè)死信隊(duì)列,用來(lái)處理異常情況。

比如,消費(fèi)者消費(fèi)消息時(shí),數(shù)據(jù)庫(kù)等發(fā)生了故障,無(wú)法將數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù),這時(shí),消費(fèi)者就可以將該條消息返回一個(gè)nack:

  • 一旦返回nack,MQ就會(huì)將這條消息轉(zhuǎn)入提前設(shè)置好的死信隊(duì)列中
  • 數(shù)據(jù)庫(kù)故障期間,處理的所有失敗消息都會(huì)轉(zhuǎn)入死信隊(duì)列
  • 消費(fèi)者設(shè)置一個(gè)后臺(tái)線(xiàn)程,監(jiān)控?cái)?shù)據(jù)庫(kù)是否正常
  • 一旦發(fā)現(xiàn)數(shù)據(jù)庫(kù)正常后,這個(gè)線(xiàn)程就把死信隊(duì)列中的消息取出來(lái),重新消費(fèi)

在這里插入圖片描述

?

17、rabbitMQ的延遲隊(duì)列?

延遲隊(duì)列的內(nèi)部是有序的,最重要的特性就是體現(xiàn)在它的延遲屬性上,延遲隊(duì)列中的元素就是希望在指定的時(shí)間到了之后,將他取出來(lái)消費(fèi)

延遲隊(duì)列的使用場(chǎng)景(在某個(gè)事件發(fā)生之后或者之前的指定時(shí)間內(nèi)要做的任務(wù))

  • 訂單在十分鐘內(nèi)未支付自動(dòng)取消
  • 新用戶(hù)注冊(cè)后,三天沒(méi)有登錄短信提醒
  • 用戶(hù)退款,三天內(nèi)沒(méi)有 處理通知相關(guān)運(yùn)營(yíng)人員
  • 預(yù)定會(huì)議后,提前十分鐘通知與會(huì)人員

?18、rabbitMQ的延遲隊(duì)列怎么實(shí)現(xiàn)?

18.1:死信隊(duì)列 +TTL 過(guò)期時(shí)間

rabbitMQ并沒(méi)有直接提供延遲隊(duì)列功能,但是可以通過(guò) 死信隊(duì)列 +TTL 過(guò)期時(shí)間進(jìn)行實(shí)現(xiàn):TTL就是消息或者隊(duì)列的過(guò)期功能。當(dāng)消息過(guò)期就會(huì)進(jìn)到死信隊(duì)列,死信隊(duì)列和普通隊(duì)列沒(méi)啥區(qū)別,然后我們只需要配置一個(gè)消費(fèi)者來(lái)消費(fèi)死信隊(duì)列里面的消息就可以了

注意:?RabbitMQ只會(huì)對(duì)隊(duì)列頭部的消息進(jìn)行過(guò)期淘汰,消息是否過(guò)期是在即將投遞消息到消費(fèi)者之前判定的,如果隊(duì)列出現(xiàn)消息堆積情況,則已過(guò)期的消息還是會(huì)繼續(xù)存活的,比如過(guò)期時(shí)間設(shè)置在消息內(nèi),由于消息隊(duì)列是先進(jìn)先出的,假設(shè)第一個(gè)消息過(guò)期時(shí)間是10s,第二個(gè)消息過(guò)期時(shí)間是1s,一前一后幾乎同時(shí)發(fā)消息,1s的已經(jīng)過(guò)期了,但是10s的還沒(méi)有過(guò)期,那么第二個(gè)消息也不會(huì)從隊(duì)列中剔除轉(zhuǎn)到死信隊(duì)列,從而導(dǎo)致消息不斷積壓。

?

18.2:基于插件實(shí)現(xiàn)延遲隊(duì)列

rabbitMQ還可以通過(guò)安裝插件來(lái)實(shí)現(xiàn)延遲隊(duì)列,安裝過(guò)程略。

使用延遲插件的情況下,延遲時(shí)間短的消息會(huì)被優(yōu)先消費(fèi),解決了死信隊(duì)列+TTL過(guò)期時(shí)間導(dǎo)致的消息積壓?jiǎn)栴}。(通過(guò)交換機(jī)延遲消息的方式來(lái)實(shí)現(xiàn)消息的延遲)

?

上面介紹了rabbitMQ中的延遲隊(duì)列實(shí)現(xiàn)方式,當(dāng)然還有一些其他的選擇,比如利用java自帶的DelayQueue, 利用redis中的zset,利用kafka的時(shí)間輪等等,這些方式各有特點(diǎn),可以根據(jù)不同的適用場(chǎng)景選擇不同的實(shí)現(xiàn)方式。

1、DelayQueue

  • DelayQueue是java自帶的一個(gè)BlockingQueue,用于放置實(shí)現(xiàn)了Delayed接口的對(duì)象。隊(duì)列中的對(duì)象只能在其到期的時(shí)候才能從隊(duì)列中取出。
  • 添加元素:觸發(fā)Delayed接口中的compareTo方法按照時(shí)間進(jìn)行排序,排在隊(duì)列頭部是最早到期的,越往后越晚到期
  • 查看元素:消費(fèi)者線(xiàn)程查看元素,調(diào)用getDelay方法,如果方法返回值小于等于0,說(shuō)明元素已經(jīng)到期,則會(huì)取出,否則,返回wait的時(shí)間,wait時(shí)間之后,在從頭部取出元素
  • 注意,不能將null放入DelayQueue中。

大數(shù)據(jù)必學(xué)Java基礎(chǔ)(六十七):DelayQueue深入了解 - 知乎

2、redis中的zeset

  • redis 中,zset的存儲(chǔ)結(jié)構(gòu)是k-v,其中value包含了memmber和score,通過(guò)score可以進(jìn)行排序
  • 生產(chǎn)者將需要延遲發(fā)送的數(shù)據(jù)存redis中的 zset
  • 消費(fèi)者循環(huán)從redis的zset隊(duì)列中獲取數(shù)據(jù),消費(fèi)時(shí)間到了的數(shù)據(jù),然后刪除已經(jīng)消費(fèi)了的數(shù)據(jù)

3、kafka實(shí)現(xiàn)延遲隊(duì)列

  • 創(chuàng)建一個(gè)專(zhuān)門(mén)的Topic用于存儲(chǔ)延遲消息
  • 在消息的key中設(shè)置延遲時(shí)間戳??梢允褂卯?dāng)前時(shí)間戳加上延遲時(shí)間作為key
  • 消費(fèi)者進(jìn)程不斷檢查消息的key中的時(shí)間戳是否已經(jīng)過(guò)期。
    • 可以使用當(dāng)前時(shí)間戳與消息的key中的時(shí)間戳進(jìn)行比較。如果時(shí)間戳已經(jīng)過(guò)期,則將消息重新發(fā)送到目標(biāo)Topic中,例如"target-messages"
    • 如果時(shí)間戳還未過(guò)期,則將消息重新發(fā)送到"delayed-messages" Topic中,并設(shè)置一個(gè)新的延遲時(shí)間戳。

kafka實(shí)現(xiàn)延遲隊(duì)列需要消費(fèi)者定期從delayed-messages 中查看消息,消費(fèi)者進(jìn)程宕機(jī)就會(huì)影響延遲隊(duì)列功能,輪詢(xún)檢查也會(huì)消耗資源,延遲精度只能達(dá)到毫秒級(jí)別。

需要注意的是,Kafka并不是專(zhuān)門(mén)為延遲隊(duì)列設(shè)計(jì)的,因此在實(shí)現(xiàn)過(guò)程中需要考慮一些細(xì)節(jié)問(wèn)題,比如消息的重復(fù)消費(fèi)、消息的順序等。

19、rabbitMQ的冪等性?

冪等性是指用戶(hù)對(duì)統(tǒng)一操作發(fā)起的一次或者多次請(qǐng)求結(jié)果都是一致的,不會(huì)因?yàn)橹貜?fù)消費(fèi)而導(dǎo)致結(jié)果不一樣。

rabbitmq 把消息發(fā)給消費(fèi)者進(jìn)行消費(fèi),消費(fèi)者消費(fèi)成功后返回ack消息,但是這個(gè)時(shí)候網(wǎng)絡(luò)中斷等原因,rabbitMQ沒(méi)有收到ack消息,讓rabbitMQ誤以為消息消費(fèi)失敗,然后rabbitMQ把消息重新發(fā)送給其他消費(fèi)者,或者等網(wǎng)絡(luò)重連后重新發(fā)給這個(gè)消費(fèi)者,這個(gè)時(shí)候就會(huì)造成重復(fù)消費(fèi)問(wèn)題。

解決思路:

消費(fèi)者解決冪等性的一般方法就是使用一個(gè)唯一標(biāo)識(shí)ID,消費(fèi)前先判斷是否已經(jīng)消費(fèi)過(guò)。

  1. 唯一id,數(shù)據(jù)庫(kù)主鍵去重
  2. redis原子性,利用setnx命令天然的冪等性。

20、優(yōu)先級(jí)隊(duì)列?

顧名思義,優(yōu)先級(jí)隊(duì)列可以對(duì)元素設(shè)置優(yōu)先級(jí),優(yōu)先級(jí)高的消息具備優(yōu)先消費(fèi)的特權(quán)。

RabbitMQ支持優(yōu)先級(jí)隊(duì)列,在聲明channel的時(shí)候添加 “x-max-priority”屬性,RabbitMQ中優(yōu)先級(jí)大小支持0-255,但是實(shí)際使用,我們可以根據(jù)需要設(shè)置最大的優(yōu)先級(jí)值。

當(dāng)然,在消費(fèi)端速度大于生產(chǎn)端速度,且broker中沒(méi)有消息堆積的話(huà),對(duì)發(fā)送的消息設(shè)置優(yōu)先級(jí)也沒(méi)什么實(shí)際意義,因?yàn)榘l(fā)送端剛發(fā)送完一條消息就被消費(fèi)端消費(fèi)了,那么就相當(dāng)于broker至多只有一條消息,那么對(duì)于單條消息來(lái)說(shuō)優(yōu)先級(jí)是沒(méi)有什么意義的

21、惰性隊(duì)列?

RabbitMQ從3.6版本引入了惰性隊(duì)列這一概念,惰性隊(duì)列會(huì)盡可能的將消息存入磁盤(pán)中,消費(fèi)者消費(fèi)到響應(yīng)的消息時(shí)才會(huì)被加載到內(nèi)存中,他的一個(gè)重要的目標(biāo)是支持更多的消息存儲(chǔ)。

  • 默認(rèn)情況下,當(dāng)生產(chǎn)者將消息發(fā)送到RabbitMQ的時(shí)候,隊(duì)列中的消息會(huì)盡可能地存儲(chǔ)在內(nèi)存之中,這樣可以更加快速地將消息發(fā)送給消費(fèi)者。即使是持久化的消息,在被寫(xiě)入磁盤(pán)的同時(shí)也會(huì)在內(nèi)存中駐留一份備份。當(dāng)RabbitMQ需要釋放內(nèi)存的時(shí)候,會(huì)將內(nèi)存中的消息換頁(yè)至磁盤(pán)中,這個(gè)操作會(huì)耗費(fèi)較長(zhǎng)的時(shí)間,也會(huì)阻塞隊(duì)列的操作,進(jìn)而無(wú)法接收新的消息。雖然RabbitMQ的開(kāi)發(fā)者們一直在升級(jí)相關(guān)的算法,但是效果始終不太理想,尤其是在 消息量特別大的時(shí)候。
  • 惰性隊(duì)列會(huì)將接收到的消息直接存入文件系統(tǒng),而不管是持久化的或者是非持久化的,這樣可以減少內(nèi)存的消耗,但是會(huì)增加I/O的使用,如果消息是持久化的,那么這樣的I/O操作不可避免,惰性隊(duì)列和持久化的消息可謂是“最佳拍檔”。
  • 注意如果惰性隊(duì)列中存儲(chǔ)的是非持久化的消息,內(nèi)存的使用率會(huì)一直很穩(wěn)定,但是重啟之后消息一樣會(huì)丟失。
  • 使用:"x-queue-mode"設(shè)置為?"lazy"

22、RabbitMQ集群?

RabbitMQ集群有兩種模式:普通集群和鏡像集群。

1、普通集群:

  • 就是將RabbitMQ部署到多臺(tái)服務(wù)器上,每臺(tái)服務(wù)器啟動(dòng)一個(gè)RabbitMQ實(shí)例,多個(gè)實(shí)例之間進(jìn)行消息通信。在普通集群上,我們創(chuàng)建的隊(duì)列queue,他的元數(shù)據(jù)(queue的一些配置信息)會(huì)在所有的RabbitMQ實(shí)例中進(jìn)行同步,但是隊(duì)列中的消息只會(huì)存在于一個(gè)RabbitMQ實(shí)例上,不會(huì)同步到其他隊(duì)列。
  • 當(dāng)消費(fèi)消息的時(shí)候,如果連接到了另外一個(gè)實(shí)例,那么實(shí)例會(huì)通過(guò)元數(shù)據(jù)定位到queue所在的位置,然后訪(fǎng)問(wèn)queue所在的實(shí)例,拉取數(shù)據(jù)過(guò)來(lái)發(fā)送給消費(fèi)者
  • 這種集群可以提高RabbitMQ的消費(fèi)吞吐能力,但是無(wú)法保證高可用,因?yàn)橐坏┐嫦⒌腞abbitMQ掛了,消息就沒(méi)辦法訪(fǎng)問(wèn)了。

在這里插入圖片描述

?

2、鏡像集群

  • 和普通集群的最大區(qū)別就是queue數(shù)據(jù)不在單獨(dú)存在一臺(tái)機(jī)器上,而是同時(shí)存儲(chǔ)在多臺(tái)機(jī)器上。也就是說(shuō),每個(gè)RabbitMQ都至少有一份鏡像數(shù)據(jù)(副本數(shù)據(jù))。
  • 每次寫(xiě)入消息的時(shí)候都會(huì)自動(dòng)把數(shù)據(jù)同步到多臺(tái)實(shí)例上去,這樣即便一臺(tái)機(jī)器宕機(jī),其他機(jī)器上還有副本數(shù)據(jù)可以繼續(xù)提供服務(wù),繼而實(shí)現(xiàn)了高可用。

在這里插入圖片描述

?

23、rabbitMQ中的federation exchange,聯(lián)邦交換機(jī)?

應(yīng)用場(chǎng)景:

有時(shí)候?yàn)榱巳轂?zāi)等原因,會(huì)將rabbitMQ部署在不同的城市,當(dāng)跨距離傳輸?shù)臅r(shí)候,會(huì)有網(wǎng)絡(luò)延遲等原因。federation exchange 提供了一個(gè)能力:可以讓原本發(fā)送給上游交換器的消息路由到本地的某個(gè)隊(duì)列中,聯(lián)邦隊(duì)列則允許一個(gè)本地消費(fèi)者接收到來(lái)自上游隊(duì)列的消息。

federation的原理:

  • 聯(lián)邦交換機(jī)首先需要?jiǎng)?chuàng)建出下游隊(duì)列(廣州的broker3),
  • federation插件會(huì)在北京(broker1)上建立一個(gè)同名的交換器,同時(shí)內(nèi)部創(chuàng)建一個(gè)內(nèi)部交換機(jī),并通過(guò)路由將兩個(gè)交換機(jī)綁定起來(lái)。
  • federation插件還會(huì)在broker1 上簡(jiǎn)歷一個(gè)隊(duì)列,并和broker3中的交換機(jī)之間建立一條AMQP連接來(lái)實(shí)時(shí)地消費(fèi)隊(duì)列federation: exchangeA.broker3中的數(shù)據(jù)
  • 對(duì)外而言,客戶(hù)端只能看到federation連接是建立在broker1 exchangeA?和brokr3 exchangeA?之間。

?

24、rabbitMQ中的shovel?
  • shovel插件同樣是為了解決數(shù)據(jù)的轉(zhuǎn)發(fā)問(wèn)題。它能夠可靠地從源端broker中的隊(duì)列中拉取數(shù)據(jù)并轉(zhuǎn)發(fā)到目的端broker的交換機(jī)中
  • 作為源端的隊(duì)列和作為目的端的交換機(jī)可以位于一個(gè)broker中(沒(méi)理解),也可以位于不同的broker上
  • shovel的優(yōu)點(diǎn):松耦合,解決不同Broker、集群、用戶(hù)、vhost、MQ和Erlang版本移動(dòng)消息,支持廣域網(wǎng),可以容忍糟糕的網(wǎng)絡(luò),能保證消息的可靠性,高度定制,當(dāng)Shovel成功連接后,可以配置。

?

拓展,實(shí)現(xiàn)一個(gè)定時(shí)任務(wù)的方法:

  1. 遍歷所有的任務(wù),根據(jù)時(shí)間來(lái)判斷是否需要執(zhí)行
    1. 優(yōu)點(diǎn):邏輯簡(jiǎn)單
    2. 缺點(diǎn):每秒都要遍歷所有的任務(wù),很多距離到期時(shí)間還遠(yuǎn)的任務(wù)做了很多無(wú)用功,數(shù)據(jù)量大的時(shí)候,會(huì)導(dǎo)致任務(wù)執(zhí)行延遲,占用CPU
  2. 根據(jù)執(zhí)行時(shí)間采用小頂堆算法,每次都取最小的時(shí)間進(jìn)行判讀
    1. 優(yōu)點(diǎn):相比較全部遍歷,比較次數(shù)變少
    2. 缺點(diǎn):數(shù)據(jù)量大的時(shí)候,每次插入新數(shù)據(jù),時(shí)間復(fù)雜度為Ologn, 但是還有可能導(dǎo)致任務(wù)延遲,(java中的Timer,ScheduledThreadPoolExcutor 就是這種做法)
  3. jdk自帶的DelayQueue,每次插入都要重新排隊(duì),時(shí)間復(fù)雜度Onlogn
  4. 時(shí)間輪
    1. kafka時(shí)間輪的原理:秒懂 Kafka 時(shí)間輪(TimingWheel) - 知乎
    2. 避免時(shí)間輪的空轉(zhuǎn):從帶圈數(shù)的時(shí)間輪改為多層時(shí)間輪:
      1. 其實(shí)就是從單純小圈轉(zhuǎn)改成:先大圈轉(zhuǎn),轉(zhuǎn)到一定位置后,然后在小圈轉(zhuǎn)
      2. 【第一層的跨度為1ms,第二層的跨度為20ms,第三層的跨度為400ms。那么例如我們放入的任務(wù)為501ms,則將會(huì)放入第三層的第一個(gè)節(jié)點(diǎn)(501%400=101),冗余了101ms,當(dāng)?shù)谌龑拥闹羔樲D(zhuǎn)到第一個(gè)節(jié)點(diǎn)時(shí),則將101ms的任務(wù)轉(zhuǎn)移到第二層,再將任務(wù)放入到第二層的第5個(gè)節(jié)點(diǎn)(101%20=1)。當(dāng)?shù)诙拥闹羔樲D(zhuǎn)移到低5個(gè)節(jié)點(diǎn)的時(shí)候發(fā)現(xiàn)冗余時(shí)間,則將任務(wù)轉(zhuǎn)移到第一層的第一個(gè)節(jié)點(diǎn),第一層轉(zhuǎn)移一次就執(zhí)行了。這么做的好處是避免了單輪空轉(zhuǎn)的情況?!?/li>

動(dòng)圖封面

?

img

?

http://www.risenshineclean.com/news/4341.html

相關(guān)文章:

  • 做充幣提現(xiàn)的網(wǎng)站優(yōu)化大師怎么卸載
  • 網(wǎng)站建設(shè)套餐價(jià)格已備案域名交易平臺(tái)
  • 51做網(wǎng)站廣州2022最近的新聞大事10條
  • 讓自己的電腦做網(wǎng)站的服務(wù)器營(yíng)銷(xiāo)軟文是什么意思
  • 珠海建站公司什么是搜索引擎優(yōu)化推廣
  • 網(wǎng)站系統(tǒng)下載不了文件百度代理服務(wù)器
  • 做的好的電商網(wǎng)站項(xiàng)目如何自己創(chuàng)建網(wǎng)站
  • 網(wǎng)站設(shè)計(jì)做哪些的百度軟件
  • 網(wǎng)站建設(shè)流程域名申請(qǐng)?jiān)扑阉飨螺d
  • 愛(ài)做網(wǎng)站免費(fèi)模板vip北京優(yōu)化網(wǎng)站公司
  • 網(wǎng)站建設(shè)創(chuàng)業(yè)基礎(chǔ)ppt模板電商seo是什么意思啊
  • 網(wǎng)站建設(shè)應(yīng)該學(xué)什么軟件域名查詢(xún)ip網(wǎng)站
  • 四川旅游網(wǎng)站設(shè)計(jì)論文全網(wǎng)營(yíng)銷(xiāo)外包
  • 購(gòu)物網(wǎng)站開(kāi)發(fā)設(shè)計(jì)思路廣州市口碑seo推廣
  • 菏澤網(wǎng)站建設(shè)公司有哪些百度公司地址在哪里
  • 雷州網(wǎng)站建設(shè)公司百度app下載官方免費(fèi)最新版
  • 設(shè)計(jì)漂亮的網(wǎng)站廣州權(quán)威發(fā)布
  • 做模板網(wǎng)站怎么放視頻教程多少關(guān)鍵詞排名優(yōu)化軟件
  • wordpress2.9.2漏洞win7優(yōu)化極致性能
  • 手機(jī)怎么樣自己做網(wǎng)站網(wǎng)站優(yōu)化公司開(kāi)始上班了
  • 廣州設(shè)計(jì)公司網(wǎng)站黃頁(yè)網(wǎng)絡(luò)的推廣網(wǎng)站有哪些軟件
  • 中山技術(shù)支持中山網(wǎng)站建設(shè)做電商必備的幾個(gè)軟件
  • 手機(jī)網(wǎng)絡(luò)營(yíng)銷(xiāo)方案優(yōu)秀網(wǎng)站seo報(bào)價(jià)
  • 長(zhǎng)沙百度網(wǎng)站制作哪里有網(wǎng)頁(yè)設(shè)計(jì)公司
  • 麗水專(zhuān)業(yè)網(wǎng)站建設(shè)公司百度網(wǎng)站站長(zhǎng)工具
  • 長(zhǎng)春?jiǎn)⒆鼍W(wǎng)站多少?gòu)V州網(wǎng)站營(yíng)銷(xiāo)seo
  • 重慶企業(yè)網(wǎng)站建設(shè)聯(lián)系電話(huà)公司網(wǎng)絡(luò)推廣的作用
  • 網(wǎng)站關(guān)鍵詞優(yōu)化方法西安優(yōu)化外
  • 青島網(wǎng)站開(kāi)發(fā)公司一份完整的電商運(yùn)營(yíng)方案
  • lazada網(wǎng)站seo運(yùn)營(yíng)