2014-05-14 85 views
0

這個問題不是關於ruby而已。併發訪問限制的api

我有很多工人正在運行創建許多連接到外部API。這個API有一個限制。
現在我使用sidekiq和redis來限制訪問。
即在每次訪問API評級我運行工人。
然後worker啓動它檢查上次訪問API的時間,如果早於API允許它,工作者被重新計劃,否則它在redis中觸及時間並運行請求。

例如:

def run_or_schedule 
    limiter = RedisLimiter.new(account_token) 
    if limiter.can_i_run? 
    limiter.like 
    run 
    else 
    ApiWorker.perform_at(limiter.next_like, *params) 
    end 
end 

問題是,我創造了許多請求,並重新安排他們很多次。

也許有人可以推薦更好的解決方案嗎?

也許有任何設計模式存在嗎?

回答

1

您正在使用的投票方法的一種替代方法是使用supervisor

因此,不是讓每個工作人員自己處理問題,而是讓另一個對象/工作人員/進程決定何時需要下一個工作人員運行。

如果API在請求之間施加一個時間限制,那麼您可以讓該超級用戶按照時間限制允許的頻率執行。

如果限制更復雜(例如,每X間隔的請求總數),您可以讓管理器不斷運行,並在該間隔時間內達到限制塊(睡眠)。恢復後,它可以繼續從隊列中的下一名工作人員。

這種方法的一個顯而易見的優點是,您可以跳過與實例化的每個工作人員相關的開銷,檢查它是否應該運行,以及是否應該重新計劃。

1

您可以使用隊列和專用線程以允許的最大速率發送事件(當有任何等待時)。

說,你可以發送一個API調用每一秒,你可以做到以下幾點:

class APIProxy 
    def like(data) 
    @like_queue << data 
    end 

    def run 
    Thread.new do 
     @like_queue = Queue.new 
     loop do 
     actual_send_like @like_queue.pop 
     sleep 1 
     end 
    end 
    end 

    private 
    def actual_send_like(data) 
    # use the API you need 
    end 
end