2012-01-08 55 views
45

APIのリクエストを制限する最良の方法は何ですか?基本的には、ユーザーを1時間に360回のAPIリクエストに制限したい(10秒ごとにリクエスト)。何頭に浮かぶことは、すべてのAPIリクエストを追跡し、保存されていますAPIのレートを制限する方法

ip-address   hourly-requests 
    1.2.3.4    77 
    2.3.4.5    34 
    3.4.5.6    124 

のIPアドレスの要求が360よりも大きい場合は、単純にしてヘッダを返す:

429 - Too Many Requests 

そして、時間給要求カウンタをロールバック毎時。カウンタをインクリメントするためのすべてのAPI要求に対してMySQLクエリを作成する必要があるため、これは非常に非効率的な方法のようです。また、すべてのカウンタを1時間ごとにリセットするcronタスクが必要です。

より洗練された/効率的なソリューションはありますか?

+0

より弾力的なアプローチの場合は、[トークンバケットアルゴリズム](https://en.wikipedia.org/wiki/Token_bucket)を参照してください。 パフォーマンスのために、カウンタは一部のメモリストアに保持する必要があります。 – botchniaque

答えて

2

私は現在、この問題についても調査中です。私の現在の計画(これはLAMPスタックであることに注意してください)は、APCのキャッシュ機能を使用してこれを実装することです。要求が受信されると、そのIPがAPCのキャッシュに保存されているかどうかを確認します。そうであれば、それが 'X'より大きいかどうかを確認してください。ここで 'X'は単位時間あたりの最大要求です。そうでない場合は、そのIPのキャッシュエントリを作成します。

このシステムは、レート制限をチェックするためにデータベースへのアクセスが必要ではなく、MongoDBやRedisサーバーのようなものに依存しないことを意味します。あなたがAPCでPHPを使用していると仮定します。もしそうでなければ、memcachedが代わりに働くかもしれません。

10

MySQLでこれを行うことは間違いありません。この問題はあまり読んでいないか、そこにハイライトしているアルゴリズムの非効率性です。ボリュームが上がると、複数秒の書き込みに入るようになります。私たちはREDISをすでに言及した別のポスターと同じようにストレージとして使用しています。それはあなたが必要としているものと非常に高速な(メモリ内の)原子増減機能を持っています。 MySQLよりも多くのオーダー)。あなたがREDISに慣れていないならMemcachedでやっているもう一つの選択肢ですが、操作レベルではそれほど良いものではありません。

さらに3つのオプション(つまり、分析、キー管理、デベロッパードキュメントなど)を効果的に行う3scale(http://www.3scale.net)を使用することです。言語(https://support.3scale.net/libraries)全体のコードプラグインがあり、これらはインフラストラクチャに接続します。 Varnish Libmod(https://github.com/3scale/libvmod-3scale/)を使用して、APIの前にあるワニスキャッシュにプラグインすることもできます。

4

を使用しようとすることができ、あなたはそれは、トラフィックデータを監視し、ログインするためのin-memory database上のログを管理するための機能を持つ軽量のWebフレームワークを実行することができますに基づいてIPまたはユーザまたはサービスを呼び出します。より重要な選択肢は、採用したいデータストレージです。

ベストと最も使用される無料のオプションは以下のとおりです。

redis.io高度なキーと値のストア

ehcache標準ベースのキャッシュ、積極的にテラコッタ

することにより、プロのオープンソースプロジェクトとして開発維持とサポートhazelcast高速な実行とシームレスな弾性スケーラビリティのためのオープンソースのインメモリデータグリッド

VoltDBインメモリop erationalデータベース

8

nginxを試してください。 構成ファイルに簡単な変更を書き込むことで、レート制限を簡単に行うことができます。さらに、nginxは高速です。

関連する問題