2015-07-19 63 views
0

嘿,我有一個問題,需要一些建議。我做了一些研究,但沒有發現任何內容,這描述了我確切的問題。芹菜排隊在其他網站上的行動

我想開發的過程:

  1. 許多用戶都可以觸發動作,這在某些條目添加到我的隊列(RabbitMQ的)
  2. 隊列任務應該從數據庫[獲取登錄名和密碼(可能是許多帳戶]),並執行一些操作。這些操作正在返回某種結果並與使用的帳戶一起保存在數據庫中。
  3. 另一個計劃任務(每5分鐘)應該獲取已保存的數據庫條目,並再次登錄網站並執行一些其他操作。

問題:每個登錄名/密碼組合只能同時登錄。如果一個組合在同一時間被多次使用,那麼這些任務將會相互註銷。

我覺得到現在爲止:

  1. 爲每個登錄/密碼組合的自己的隊列,並有這方面的工作人員,其處理在同一時間只有一個條目。
  2. 鎖定數據庫中行

你有這個問題的任何建議或解決方案?

我用過的框架是:Django作爲主要應用框架,Celery + RabbitMQ用於我的隊列系統。

EDIT1:
http://docs.celeryproject.org/en/latest/tutorials/task-cookbook.html#ensuring-a-task-is-only-executed-one-at-a-time
也許這篇文章可以幫助我..也許設置cachekey可能會有幫助。但是,如果所有的登錄/密碼組合都被「阻止」,任務將會遇到一些死鎖問題。

回答

0

使用某種鎖定。

如果您可以容忍偶爾出現的故障,那麼您可以使用memcached或redis之類的東西做一個快速且髒的分佈式鎖定。或者,如你所說,你的數據庫。

我不知道如果我即使是在數據庫打擾鎖定行 - 我個人會使用Redis的,只是創建一個映射

www.whatever.com:username:hash(password) -> worker hostname:worker pid:start time 

然後你的工人可以檢查網站的特定組合/用戶名/密碼被鎖定。

使用花卉,您還可以檢查鎖定特定憑據集的工作人員是否仍處於活動狀態。

包裝你的任務在try /除了/ finally塊,以確保即使失敗

import redis 
r = redis.StrictRedis() 

class MyTask(Task): 
    __call__(site, username, password): 
     key = '%s:%s:%s' % (site, username, hash(password) 
     val = '%s:%s:%s' % (datetime.now().isoformat(), self.request.hostname, os.getpid()) 

     if not setnx(key, val): 
      LOG.error('%s locked', key) 
      return 

     try: 
      return super(MyTask, self).__call__(site, username, password) 
     finally: 
      r.del(key) 
該鎖在每個任務結束時發佈