web-dev-qa-db-ja.com

APIをレート制限する方法

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

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

Ip-addressリクエストが360を超える場合は、次のヘッダーを返します:

  429 - Too Many Requests

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

よりエレガントで効率的なソリューションはありますか?

55
Justin

Redisの使用を試みることができます レート制限のパターンはほとんどありません

30

MySQLでこれを行うことは絶対にお勧めしません。問題は、読み取りがそれほど多くないこと、またはそこで強調しているアルゴリズムの非効率性ではなく、書き込みです。ボリュームが上がると、数秒の書き込みが開始されます。すでに述べた別のポスターとしてREDISをストレージとして使用します-必要なものとまったく同じアトミックなインクリメント/デクリメント機能があり、非常に高速です(メモリ内)-シャーディングを超大容量で管理する必要があります(ただし、 MySQLの何桁も上)。 REDISに慣れていない場合のもう1つのオプションは、Memcachedで行うことですが、操作レベルではそれほど良くありません。

さらに別のオプションは、3scale(http://www.3scale.net)のようなものを使用することです。これは、あなたと他のもの(分析、キー管理、開発者ドキュメントなど)のためにこれらすべてを効果的に行います。多数の言語(https://support.3scale.net/libraries)のコードプラグインがあり、これらはインフラストラクチャに接続します。 Varnish Libmod(https://github.com/3scale/libvmod-3scale/)を使用して、APIの前のVarnishキャッシュにプラグインすることもできます。

11
steve

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

11
Kartik Goyal

理想的なパフォーマンスを得るには、トラフィックデータを監視および記録するための in-memoryデータベース でログを管理する機能を備えた軽量のWebフレームワークを実行できます。 [〜#〜] ip [〜#〜]またはserまたはユーザーによって呼び出されるサービス。より重要な選択は、使用するデータストレージです。

最もよく使用される無料のオプションは次のとおりです。

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

ehcache Terracottaによるプロフェッショナルなオープンソースプロジェクトとして積極的に開発、保守、サポートされている標準ベースのキャッシュ

hazelcast より高速な実行とシームレスで柔軟な拡張性を実現するオープンソースのインメモリデータグリッド

VoltDB インメモリ操作データベース

6
kommradHomer

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

このシステムは、レート制限を確認するためにデータベースアクセスが不要であり、MongoDBやRedisサーバーなどに依存しないことを意味します。 APCでPHPを使用している場合を想定しています。使用していない場合は、代わりにmemcachedが機能する可能性があります。

2
Mechcozmo