目錄
1.threading+Queue實現執行緒佇列
2.多個佇列
1. 解耦
2. 冗餘
3. 擴展性
4. 靈活性 & 峰值處理能力
5. 可恢復性
6. 送達保證
7.排序保證
8.緩衝
9. 理解資料流
10. 非同步通訊
首頁 後端開發 Python教學 Python中線程的MQ訊息佇列實作及優缺點介紹

Python中線程的MQ訊息佇列實作及優缺點介紹

Sep 19, 2017 am 10:15 AM
python 實現 佇列

訊息佇列(MQ,Message Queue)在訊息資料傳輸中的保存作用為資料通訊提供了保障和即時處理上的便利,這裡我們就來看一下Python中線程的MQ訊息佇列實作以及訊息佇列的優點解析

「訊息佇列」是在訊息的傳輸過程中保存訊息的容器。訊息佇列管理器在將訊息從它的來源中繼到它的目標時充當中間人。佇列的主要目的是提供路由並保證訊息的傳遞;如果發送訊息時接收者不可用,訊息佇列會保留訊息,直到可以成功地傳遞它。相信對任何架構或應用來說,訊息佇列都是一個至關重要的元件,以下是十個理由:

Python的訊息佇列範例:

1.threading+Queue實現執行緒佇列

#!/usr/bin/env python
 
import Queue
import threading
import time
 
queue = Queue.Queue()
 
class ThreadNum(threading.Thread):
 """没打印一个数字等待1秒,并发打印10个数字需要多少秒?"""
 def __init__(self, queue):
  threading.Thread.__init__(self)
  self.queue = queue
 
 def run(self):
  whileTrue:
   #消费者端,从队列中获取num
   num = self.queue.get()
   print "i'm num %s"%(num)
   time.sleep(1)
   #在完成这项工作之后,使用 queue.task_done() 函数向任务已经完成的队列发送一个信号
   self.queue.task_done()
 
start = time.time()
def main():
 #产生一个 threads pool, 并把消息传递给thread函数进行处理,这里开启10个并发
 for i in range(10):
  t = ThreadNum(queue)
  t.setDaemon(True)
  t.start()
  
 #往队列中填错数据 
 for num in range(10):
   queue.put(num)
 #wait on the queue until everything has been processed
 queue.join()
 
main()
print "Elapsed Time: %s" % (time.time() - start)
登入後複製

執行結果:

i'm num 0
i'm num 1
i'm num 2
i'm num 3
i'm num 4
i'm num 5
i'm num 6
i'm num 7
i'm num 8
i'm num 9
Elapsed Time: 1.01399993896
登入後複製

解讀:

#具體工作步驟說明如下:

1,建立一個Queue.Queue() 的實例,然後使用資料對它進行填充。

2,將經過填充資料的實例傳遞給線程類,後者是透過繼承 threading.Thread 的方式創建的。

3,產生守護線程池。

4,每次從佇列中取出一個項目,並使用該執行緒中的資料和 run 方法來執行相應的工作。

5,在完成這項工作之後,使用 queue.task_done() 函數向任務已經完成的佇列發送一個訊號。

6,對佇列執行 join 操作,實際上意味著等到佇列為空,再退出主程式。

在使用這個模式時需要注意一點:透過將守護執行緒設為 true,程式運行完自動退出。好處是在退出之前,可以對佇列執行 join 操作、或等到佇列為空。

2.多個佇列

所謂多個佇列,一個佇列的輸出可以作為另一個佇列的輸入

#!/usr/bin/env python
import Queue
import threading
import time
 
queue = Queue.Queue()
out_queue = Queue.Queue()
 
class ThreadNum(threading.Thread):
  def __init__(self, queue, out_queue):
    threading.Thread.__init__(self)
    self.queue = queue
    self.out_queue = out_queue
 
  def run(self):
    whileTrue:
      #从队列中取消息
      num = self.queue.get()
      bkeep = num
      
      #将bkeep放入队列中
      self.out_queue.put(bkeep)
 
      #signals to queue job is done
      self.queue.task_done()
 
class PrintLove(threading.Thread):
  def __init__(self, out_queue):
    threading.Thread.__init__(self)
    self.out_queue = out_queue
 
  def run(self):
    whileTrue:
      #从队列中获取消息并赋值给bkeep
      bkeep = self.out_queue.get()  
      keke = "I love " + str(bkeep)
      print keke,
      print self.getName()
      time.sleep(1)
 
      #signals to queue job is done
      self.out_queue.task_done()
 
start = time.time()
def main():
  #populate queue with data
  for num in range(10):
    queue.put(num)
    
  #spawn a pool of threads, and pass them queue instance
  for i in range(5):
    t = ThreadNum(queue, out_queue)
    t.setDaemon(True)
    t.start()
 
 
  for i in range(5):
    pl = PrintLove(out_queue)
    pl.setDaemon(True)
    pl.start()
 
  #wait on the queue until everything has been processed
  queue.join()
  out_queue.join()
 
main()
print "Elapsed Time: %s" % (time.time() - start)
登入後複製

運行結果:

I love 0 Thread-6
I love 1 Thread-7
I love 2 Thread-8
I love 3 Thread-9
I love 4 Thread-10
I love 5 Thread-7
I love 6 Thread-6
I love 7 Thread-9
I love 8 Thread-8
I love 9 Thread-10
Elapsed Time: 2.00300002098
登入後複製

 

解讀:

ThreadNum 類別工作流程

#定義佇列--->繼承threading---->初始化queue---->定義run函數--->get queue中的資料---->處理資料---->put資料到另一個queue-->發訊號告訴queue該條處理完畢

 

main函數工作流程:

--->往自訂queue中丟資料

--->for迴圈確定啟動的執行緒數-- -->實例化ThreadNum類別---->啟動線程並設定守護

--->for循環決定啟動的線程數---->實例化PrintLove類別--- >啟動執行緒並設定為守護

--->等待queue中的訊息處理完畢後執行join。即退出主程式。

了解了MQ的大概實現以後,我們來總結一下訊息佇列的優點:

1. 解耦

在專案啟動之初來​​預測未來專案會碰到什麼需求,是極為困難的。訊息佇列在處理過程中間插入了一個隱含的、基於資料的介面層,兩邊的處理過程都要實現這一介面。這允許你獨立的擴展或修改兩邊的處理過程,只要確保它們遵守相同的介面約束。

2. 冗餘

有時在處理資料的時候處理過程會失敗。除非資料被持久化,否則將永遠遺失。訊息佇列把資料持久化直到它們已經完全處理,透過這種方式規避了資料遺失風險。在被許多訊息佇列所採用的"插入-獲取-刪除"範式中,在把一個訊息從佇列中刪除之前,需要你的處理過程明確的指出該訊息已經被處理完畢,確保你的資料被安全的保存直到你使用完畢。

3. 擴展性

因為訊息佇列解耦了你的處理過程,所以增大訊息入隊和處理的頻率是很容易的;只要另外增加處理過程即可。不需要改變程式碼、不需要調節參數。擴充就像調大電力按鈕一樣簡單。

4. 靈活性 & 峰值處理能力

當你的應用程式上了Hacker News的首頁,你將發現訪問流量攀升到一個不同尋常的水平。在訪問量劇增的情況下,你的應用仍然需要繼續發揮作用,但是這樣的突發流量並不常見;如果為 以能處理這類峰值訪問為標準來投入資源隨時待命無疑是巨大的浪費。使用訊息佇列能夠使關鍵元件頂住成長的存取壓力,而不是因為超出負荷的請求而完全崩潰。 請查看我們關於峰值處理能力的部落格文章以了解更多此方面的資訊。

5. 可恢復性

當體系的一部分元件失效,不會影響整個系統。訊息佇列降低了進程間的耦合度,所以即使一個處理訊息的進程掛掉,加入佇列中的訊息仍然可以在系統復原後被處理。而這種允許重試或延後處理請求的能力通常是造就一個略感不便的使用者和一個沮喪透頂的使用者之間的區別。

6. 送達保證

訊息佇列提供的冗餘機制保證了訊息能被實際的處理,只要一個行程讀取了該佇列即可。在此基礎上,IronMQ提供了一個"只送達一次"保證。無論有多少進 程在從隊列中領取數據,每個訊息只能被處理一次。這之所以成為可能,是因為取得一個訊息只是"預定"了這個訊息,暫時把它移出了隊列。除非客戶端明確的 表示已經處理完了這個訊息,否則這個訊息會被放回佇列中去,在一段可設定的時間之後可再次處理。

7.排序保證

在許多情況下,資料處理的順序都很重要。訊息佇列本來就是排序的,並且能保證資料會按照特定的順序來處理。 IronMO保證訊息漿糊透過FIFO(先進先出)的順序來處理,因此訊息在佇列中的位置就是從佇列中擷取他們的位置。

8.緩衝

在任何重要的系統中,都會有需要不同的處理時間的元素。例如,載入一張圖片比應用濾鏡花費更少的時間。訊息佇列透過一個緩衝層來幫助任務最高效率的執行--寫入佇列的處理會盡可能的快速,而不受從佇列讀取的預備處理的約束。此緩衝有助於控制和最佳化資料流經過系統的速度。

9. 理解資料流

在一個分散式系統裡,要得到一個關於使用者操作會用多長時間及其原因的總體印象,是個巨大的挑戰。訊息系列透過訊息被處理的頻率,來方便的輔助確定那些表現不佳的處理過程或領域,這些地方的資料流都不夠優化。

10. 非同步通訊

很多時候,你不想也不需要立即處理訊息。訊息佇列提供了非同步處理機制,讓你把一個訊息放入佇列,但不會立即處理它。你想向隊列中放入多少訊息就放多少,然後在你樂意的時候再去處理它們。

以上是Python中線程的MQ訊息佇列實作及優缺點介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

vs code 可以在 Windows 8 中運行嗎 vs code 可以在 Windows 8 中運行嗎 Apr 15, 2025 pm 07:24 PM

VS Code可以在Windows 8上運行,但體驗可能不佳。首先確保系統已更新到最新補丁,然後下載與系統架構匹配的VS Code安裝包,按照提示安裝。安裝後,注意某些擴展程序可能與Windows 8不兼容,需要尋找替代擴展或在虛擬機中使用更新的Windows系統。安裝必要的擴展,檢查是否正常工作。儘管VS Code在Windows 8上可行,但建議升級到更新的Windows系統以獲得更好的開發體驗和安全保障。

visual studio code 可以用於 python 嗎 visual studio code 可以用於 python 嗎 Apr 15, 2025 pm 08:18 PM

VS Code 可用於編寫 Python,並提供許多功能,使其成為開發 Python 應用程序的理想工具。它允許用戶:安裝 Python 擴展,以獲得代碼補全、語法高亮和調試等功能。使用調試器逐步跟踪代碼,查找和修復錯誤。集成 Git,進行版本控制。使用代碼格式化工具,保持代碼一致性。使用 Linting 工具,提前發現潛在問題。

notepad 怎麼運行python notepad 怎麼運行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。

vscode 擴展是否是惡意的 vscode 擴展是否是惡意的 Apr 15, 2025 pm 07:57 PM

VS Code 擴展存在惡意風險,例如隱藏惡意代碼、利用漏洞、偽裝成合法擴展。識別惡意擴展的方法包括:檢查發布者、閱讀評論、檢查代碼、謹慎安裝。安全措施還包括:安全意識、良好習慣、定期更新和殺毒軟件。

See all articles