2017-02-08 16 views
0

クライアント側のapi呼び出しでレート制限を実装しようとしています。 15分ごとに同じapi(10 reqs/secに限る)を使用するSymfony2のコマンドは約20個あるので、RabbitMQを使用する必要があったため、プロセスがメモリ不足にならないようにしたり、Symfony2、RabbitMQとRedisスロットル

apiコールはコマンドとRabbitMQワーカーで実行されるので、RabbitMQでもそれらを抑制する必要があります。私は労働者が私の場合にはそのような仕事をしてはいけないと知っていますが、私はすべてをリファクタリングする時間がありません。

私のRabbitMQワーカーのすべてのコマンドに共通の方法を絞ることは可能ですか?私はhttps://github.com/jaytaph/RateLimitBundlehttps://github.com/snc/SncRedisBundle(私のシステムには、predisライブラリとRedisがインストールされ、実行中である)を試していますが、ちょっとしたことがあります。

レート制限が最大に近づいた場合、どのように処理する必要がありますか?イベントリスナーが必要ですか?レディスのレート制限をチェックしなければならないのですか?

snc_redis: 
    clients: 
     default: 
      type: predis 
      alias: default 
      dsn: redis://localhost 

レートリミット設定:

noxlogic_rate_limit: 
    enabled: true 
    storage_engine: "redis" 
    redis_client: default 
    rate_response_code: 429 
    rate_response_exception: Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException 
    display_headers: true 
    headers: 
     limit: X-RateLimit-Limit 
     remaining: X-RateLimit-Remaining 
     reset: X-RateLimit-Reset 

答えて

1

だけINCRBY Redisのコマンド(https://redis.io/commands/incrby)を使用

私の方法は、この

/** 
    * @RateLimit(limit=10, period=60) 
    */ 
    protected function apiRequest($query) 
    { 
     $url = $this->getApiUrl().$query.$this->getUsernameAndApiKey(); 

     echo $url. "\r\n"; 

     $xml = $this->getWithCurl($url); 
     $xml = simplexml_load_string($xml); 

//   if ($xml === false) { 
//    $this->slack->sendMessage($this->getError($url)); 
//   } 

     if($xml) 
      return $xml; 

    } 

のRedisの設定のように見えます。

$counter = $redis->increment($key); 
if ($counter > $limit) { 
    //deny logic here 
} 

をそれが原因のRedisのシングルスレッドのアトミックな性質の処理されている多くの同時リクエストで動作します:コマンドからの応答は、コードの中で、あなたがこのようなあなたの限界で、この値を比較することができますので、インクリメント後の値になります$ limit以上のリクエストは処理されません。

関連する問題