乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      RabbitMQ消息隊(duì)列(九):Publisher的消息確認(rèn)機(jī)制

       Aske5rqhg680oe 2017-05-25

         在前面的文章中提到了queue和consumer之間的消息確認(rèn)機(jī)制:通過設(shè)置ack。那么Publisher能不到知道他post的Message有沒有到達(dá)queue,甚至更近一步,是否被某個(gè)Consumer處理呢?畢竟對于一些非常重要的數(shù)據(jù),可能Publisher需要確認(rèn)某個(gè)消息已經(jīng)被正確處理。

            在我們的系統(tǒng)中,我們沒有是實(shí)現(xiàn)這種確認(rèn),也就是說,不管Message是否被Consume了,Publisher不會(huì)去care。他只是將自己的狀態(tài)publish給上層,由上層的邏輯去處理。如果Message沒有被正確處理,可能會(huì)導(dǎo)致某些狀態(tài)丟失。但是由于提供了其他強(qiáng)制刷新全部狀態(tài)的機(jī)制,因此這種異常情況的影響也就可以忽略不計(jì)了。

           對于某些異步操作,比如客戶端需要?jiǎng)?chuàng)建一個(gè)FileSystem,這個(gè)可能需要比較長的時(shí)間,甚至要數(shù)秒鐘。這時(shí)候通過RPC可以解決這個(gè)問題。因此也就不存在Publisher端的確認(rèn)機(jī)制了。

           那么,有沒有一種機(jī)制能保證Publisher能夠感知它的Message有沒有被處理的?答案肯定的。在這里感謝笑天居士同學(xué):他在我的《RabbitMQ消息隊(duì)列(三):任務(wù)分發(fā)機(jī)制》文后留言一起討論了問題,而且也查找了一些資料。在這里我整理了一下他轉(zhuǎn)載和一篇文章和原創(chuàng)的一篇文章。銜接已經(jīng)附后。

       

      1. 事務(wù)機(jī)制 VS Publisher Confirm

             如果采用標(biāo)準(zhǔn)的 AMQP 協(xié)議,則唯一能夠保證消息不會(huì)丟失的方式是利用事務(wù)機(jī)制 — 令 channel 處于 transactional 模式、向其 publish 消息、執(zhí)行 commit 動(dòng)作。在這種方式下,事務(wù)機(jī)制會(huì)帶來大量的多余開銷,并會(huì)導(dǎo)致吞吐量下降 250% 。為了補(bǔ)救事務(wù)帶來的問題,引入了 confirmation 機(jī)制(即 Publisher Confirm)。

           為了使能 confirm 機(jī)制,client 首先要發(fā)送 confirm.select 方法幀。取決于是否設(shè)置了 no-wait 屬性,broker 會(huì)相應(yīng)的判定是否以 confirm.select-ok 進(jìn)行應(yīng)答。一旦在 channel 上使用 confirm.select方法,channel 就將處于 confirm 模式。處于 transactional 模式的 channel 不能再被設(shè)置成 confirm 模式,反之亦然。
          一旦 channel 處于 confirm 模式,broker 和 client 都將啟動(dòng)消息計(jì)數(shù)(以 confirm.select 為基礎(chǔ)從 1 開始計(jì)數(shù))。broker 會(huì)在處理完消息后,在當(dāng)前 channel 上通過發(fā)送 basic.ack 的方式對其進(jìn)行 confirm 。delivery-tag 域的值標(biāo)識(shí)了被 confirm 消息的序列號(hào)。broker 也可以通過設(shè)置 basic.ack 中的 multiple 域來表明到指定序列號(hào)為止的所有消息都已被 broker 正確的處理了。

             在異常情況中,broker 將無法成功處理相應(yīng)的消息,此時(shí) broker 將發(fā)送 basic.nack 來代替 basic.ack 。在這個(gè)情形下,basic.nack 中各域值的含義與 basic.ack 中相應(yīng)各域含義是相同的,同時(shí) requeue 域的值應(yīng)該被忽略。通過 nack 一或多條消息,broker 表明自身無法對相應(yīng)消息完成處理,并拒絕為這些消息的處理負(fù)責(zé)。在這種情況下,client 可以選擇將消息 re-publish 。

            在 channel 被設(shè)置成 confirm 模式之后,所有被 publish 的后續(xù)消息都將被 confirm(即 ack) 或者被 nack 一次。但是沒有對消息被 confirm 的快慢做任何保證,并且同一條消息不會(huì)既被 confirm 又被 nack 。

       

      2. 消息在什么時(shí)候確認(rèn)

      broker 將在下面的情況中對消息進(jìn)行 confirm :

      • broker 發(fā)現(xiàn)當(dāng)前消息無法被路由到指定的 queues 中(如果設(shè)置了 mandatory 屬性,則 broker 會(huì)先發(fā)送 basic.return)
      • 非持久屬性的消息到達(dá)了其所應(yīng)該到達(dá)的所有 queue 中(和鏡像 queue 中)
      • 持久消息到達(dá)了其所應(yīng)該到達(dá)的所有 queue 中(和鏡像 queue 中),并被持久化到了磁盤(被 fsync)
      • 持久消息從其所在的所有 queue 中被 consume 了(如果必要?jiǎng)t會(huì)被 acknowledge)

      broker 會(huì)丟失持久化消息,如果 broker 在將上述消息寫入磁盤前異常。在一定條件下,這種情況會(huì)導(dǎo)致 broker 以一種奇怪的方式運(yùn)行。例如,考慮下述情景:

         1.  一個(gè) client 將持久消息 publish 到持久 queue 中
      2.  另一個(gè) client 從 queue 中 consume 消息(注意:該消息具有持久屬性,并且 queue 是持久化的),當(dāng)尚未對其進(jìn)行 ack
      3.  broker 異常重啟
      4.  client 重連并開始 consume 消息

         在上述情景下,client 有理由認(rèn)為消息需要被(broker)重新 deliver 。但這并非事實(shí):重啟(有可能)會(huì)令 broker 丟失消息。為了確保持久性,client 應(yīng)該使用 confirm 機(jī)制。如果 publisher 使用的 channel 被設(shè)置為 confirm 模式,publisher 將不會(huì)收到已丟失消息的 ack(這是因?yàn)?consumer 沒有對消息進(jìn)行 ack ,同時(shí)該消息也未被寫入磁盤)。

      3. 編程實(shí)現(xiàn)

      首先要區(qū)別AMQP協(xié)議mandatory和immediate標(biāo)志位的作用。

      mandatory和immediate是AMQP協(xié)議中basic.pulish方法中的兩個(gè)標(biāo)志位,它們都有當(dāng)消息傳遞過程中不可達(dá)目的地時(shí)將消息返回給生產(chǎn)者的功能。具體區(qū)別在于:
      1. mandatory標(biāo)志位
      當(dāng)mandatory標(biāo)志位設(shè)置為true時(shí),如果exchange根據(jù)自身類型和消息routeKey無法找到一個(gè)符合條件的queue,那么會(huì)調(diào)用basic.return方法將消息返還給生產(chǎn)者;當(dāng)mandatory設(shè)為false時(shí),出現(xiàn)上述情形broker會(huì)直接將消息扔掉。
      2. immediate標(biāo)志位
      當(dāng)immediate標(biāo)志位設(shè)置為true時(shí),如果exchange在將消息route到queue(s)時(shí)發(fā)現(xiàn)對應(yīng)的queue上沒有消費(fèi)者,那么這條消息不會(huì)放入隊(duì)列中。當(dāng)與消息routeKey關(guān)聯(lián)的所有queue(一個(gè)或多個(gè))都沒有消費(fèi)者時(shí),該消息會(huì)通過basic.return方法返還給生產(chǎn)者。

      具體的代碼參考請參考參考資料1.

       

      參考資料:

      1. http://blog.csdn.net/jiao_fuyou/article/details/21594205

      2. http://blog.csdn.net/jiao_fuyou/article/details/21594947

      3.  http://my.oschina.net/moooofly/blog/142095

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多