(二)rabbitmq python 踩坑記錄

2021-07-26 02:02:11 字數 2883 閱讀 2235

a.直連,publisher傳送訊息後,投遞到繫結到同乙個exchange上的所有queue.訊息路由是通過routing_key來路由,與queue_name沒有太大的關係

要求:consumer的exchangename 和 routing_key 與 publisher要一致,否則訊息不會被處理

b.訊息會輪流給每個consumer傳送

使用durable=true宣告queue是持久化的,這樣即便mq崩潰了重啟後queue仍然存在,這樣可以防止訊息的丟失。

除了要宣告queue是持久化的外,還需宣告message是持久化的basic_publish的properties引數指定message的屬性 此處pika.basicproperties中的delivery_mode=2指明message為持久的,這樣一來rabbitmq崩潰重啟後queue仍然存在其中的message也仍。但需注意的是將message標記為持久的並不能完全保證message不丟失,因為從rabbitmq接收到message到將其儲存到disk仍需一段時間,若此時rabbitmq崩潰則message會丟失。況且rabbitmq不會對每條message做fsync動作。這時可通過publisher confirms實現更強壯的永續性保證。

a.exchange持久化,在宣告時指定durable => 1

b.queue持久化,在宣告時指定durable => 1

c.訊息持久化,在投遞時指定delivery_mode => 2(1是非持久化)

channel.basic_publish(exchange=』test_exchange』, routing_key=』standard_key』, body=』queue:group』, properties=pika.basicproperties(content_type=』text/plain』, delivery_mode=1))

在處理完訊息時,返回應答狀態。你要預設加上,別忘了!!!

channel.basic_ack(delivery_tag= method.delivery_tag)

假如不返回應答狀態,即使這個consumer處理完成當前的任務,他也不會去從任務池裡取下個任務,會一直等待下去(這是不合理的),他處理完後不會去通知publish,是給mq說一聲,我處理完了這個任務了,再給我乙個任務吧。否則mq會認為,這傢伙那麼忙,我找別人幹活去,不給他任務了。

channel.basic_consume(on_message, 『queuename』,no_ack=false);basic_consume裡的引數裡no_ack的含義為no_ack=false意思為,您需要手動設定一下,即呼叫basic_ack來決定訊息處理是否處理完成.這種狀態下,publish傳送的任務會到任務池裡,增加consume時,直接從任務池裡取任務

當呼叫basic_consume(…no_ack=true…)時,所有的任務都會分配給當前正在執行的consume,因為mq會把當前的consume當成空閒狀態,consume接受任務後,立即回給mq說幹完了(和perfetch_count不衝突)。(例如:當前正在執行3個consume,當第四個consume來到後,會檢索到任務池裡沒有任務,因為任務全部被consume執行了,所以publish再次執行4次才可以被第4個consume發現)

channel.basic_qos(prefetch_count= 1 ): 這個是流量控制,比如我有5個consumer在同時消費,publisher傳送任務後,consumer自動去任務池裡去獲取任務,處理完後,再次去取任務,直到任務完全取完。每個consumer都最大分配1個任務。當第6個consumer來到後,也是直接拿起任務就幹.

若prefetch_count=2,那麼每個consumer最大容納2個任務。比如任務池裡有10個任務(假設任務是耗時的,很長時間才能處理完畢),當前只有3個consumer(a,b,c)在執行。任務分配的情況:a->1,b->2,c->3,a->4,b->5,c->6.(剛開始是搶任務,每個consumer搶乙個,輪完後發現還有任務,再第二輪搶,此時a的第二輪有肯能是任務5,任務6,視其效率而定)任務7,8,9,10就得等待。此時第4個consumer到了,會拿到7,8。

舉個通俗的例子:

學校買個10張桌子給1班,每個桌子最大可以做2個學生。 假如有10個學生,老師決定,每個桌子坐1個學生。剛好分完。假如有15個學生,那麼部分桌子是2個人的,其餘的還是1個人。此時,又來了一張桌子,又來了5個學生,老師說了,新桌子不准用,舊桌子啥時候坐滿了,啥時候再用新桌子。那麼第11張桌子只能等到第21個學生來了(桌子=consumer,學生=publisher,老師=規則)

channel.exchange_declare(exchange="test_exchange", exchange_type="direct", passive=false, durable=true, auto_delete=false)
例如如果使用者僅僅想查詢某乙個佇列是否已存在,如果不存在,不想建立該佇列,仍然可以呼叫queue.declare,只不過需要將引數passive設為true,傳給queue.declare,如果該佇列已存在,則會返回true;如果不存在,則會返回error,但是不會建立新的佇列.

排他佇列,如果乙個佇列被宣告為排他佇列,該佇列僅對首次宣告它的連線可見,並在連線斷開時自動刪除。這裡需要注意三點:

其一,排他佇列是基於連線可見的,同一連線的不同通道是可以同時訪問同乙個連線建立的排他佇列的。

其二,「首次」,如果乙個連線已經宣告了乙個排他佇列,其他連線是不允許建立同名的排他佇列的,這個與普通佇列不同。

其三,即使該佇列是持久化的,一旦連線關閉或者客戶端退出,該排他佇列都會被自動刪除的。這種佇列適用於只限於乙個客戶端傳送讀取訊息的應用場景。

自動刪除,如果該佇列沒有任何訂閱的消費者的話,該佇列會被自動刪除。這種佇列適用於臨時佇列

Python opencv 二 畫素運算 二

使用工具python3.x 使用庫numpy opencv,1.cv.bitwise and s1,s2 s1,s2為cv.imread函式返回的物件,表示將s1和s2的畫素進行邏輯與運算,函式會返回乙個物件。可以通過cv.imshow顯示出進行直觀感受。2.cv.bitwise or s1,s2 ...

大二第二學期周學習進度總結(二)

本週檢測的是從文件中讀取隨機數並得到最大連續子陣列,難度並不是很大,主要是需要使用biginteger來進行運算解決問題,我經常有這樣的感覺,就是很多情況下已經有了很成熟的技術,但是我們這些初學者僅僅是因為不知道,所以導致我們不知道這些方法如何解決,這個問題在課堂上困住了不少人,也許不少人是因為懶得...

二叉堆實現二

堆可以視為一棵完全二叉樹,樹的每一層都是被填滿的,最後一層可能除外,所以堆可以用陣列來表示。對於陣列中任意位置 i上的元素,其左兒子在位置 i 2 1 其右兒子在位置 i 2 2 上,其父節點在位置 i 1 2 1處。二叉堆有兩種 最大堆和最小堆。最大堆中,除根結點外 其無父結點 每個結點的關鍵字都...