2012-06-21 35 views
8

我有一個python腳本在ec2實例上使用boto庫,它是autoscaling組的一部分。該腳本處理來自SQS隊列的消息:使用boto處理SQ​​S隊列

import boto 
from boto.sqs.message import Message 

conn = boto.connect_sqs() 
q = conn.create_queue('queue-name') 

while (qin.count() > 0): 
    m = q.get_messages() 
    #do something with the message 

使用while語句是否有意義?是否計數()更新作爲實時:(?或者我會想念他們)

  1. 其他情況下需要關閉消息隊列(或我要加倍)
  2. 新消息被添加到隊列

即使在隊列爲空的情況下,如何使此腳本不斷地偵聽隊列中的新增加內容?

在這個問題Processing items in SQS queue with a php script有人提到'sqs ruby​​客戶端庫有一個方法「輪詢」,它連續輪詢隊列,並在隊列中接收消息時將它傳遞給一個塊。 Python中是否有等價物?

也有人建議SNS可以用來通知腳本消息隊列的狀態,但我沒有看到如何配置SNS的響應系統,因爲度量標準報警不夠精細。

+0

你知道哪個Ruby庫?我想看看它 – Hassek

+0

對不起,我只看到它在上面鏈接的問題。 – waigani

+0

結帳SNS - 最好是推動然後拉。並且他們在一起很好地工作http://docs.aws.amazon.com/sns/latest/dg/SendMessageToSQS.html –

回答

6

您不應該依賴隊列計數,因爲它只能提供近似計數並且不能保證準確。

如果你想只保留查詢永遠,只是這樣做:

while 1: 
    messages = q.get_messages() 
    # do something with messages 
    time.sleep(N) 

我已經添加了調用time.sleep引進的循環延遲。 N值應該至少爲1秒,並且可能會更多,這取決於您期望新消息在您的隊列中出現的速度。如果你沒有在循環中加入某種延遲,你可能會開始被服務扼殺。

要避免多次讀取消息,應該嘗試將隊列的可見性超時值調整爲大於處理消息所需的時間的值,然後確保在處理消息時刪除消息完成。

3
  1. 當您從SQS中拉取消息時,消息變得不可見並且無法通過其他隊列查詢(編輯 - 隱藏可在0到12小時之間設置)。
  2. 每次添加新消息時,您都必須重新獲取隊列,但這不應該成爲問題 - 這就是排隊服務首先存在的原因。

如果要持續輪詢隊列,請嘗試所謂的Long Polling - 您可以在隊列填充時返回最多20秒的連續輪詢。

希望這是有益的,否則圍繞博託平方documentation戳。

+0

消息不可見性默認爲30秒,而不是4天。這段時間可以修改。 –

2

例子:

# wait_time_seconds count only 1 request in x seconds (0 - 20) 
# num_messages get x messages in same request (1 - 10) 
while 1: 
    logger.info("... waiting messages ...") 
    messages = queue_in.get_messages(wait_time_seconds=20, num_messages=10) 
    for message in messages: 
     logger.info('message: %s' % (message,)) 
     queue_in.delete_message(message)