14

私はWebサービスAPIとインターフェイスするPythonライブラリに取り組んでいます。私が遭遇した多くのWebサービスと同様に、これは要求のレートを制限するように要求します。limitクラスのインスタンス化にオプションのパラメーター、を提供したいと思います。これが提供された場合、指定された秒数が経過するまで送信要求を保持します。

一般的なシナリオは次のとおりです。クラスのインスタンスがメソッドを介してリクエストを行います。その場合、メソッドはどこかにロック変数を設定する信号を発し、秒数のカウントダウンタイマーを開始しlimitます。(おそらく、ロックはカウントダウンタイマー自体です。)この時間枠内に別の要求が行われた場合、カウントダウンタイマーがゼロになり、ロックが解除されるまで、その要求をキューに入れる必要があります。この時点で、キュー上の最も古い要求が送信され、カウントダウンタイマーがリセットされ、ロックが再度適用されます。

これは糸脱毛の場合ですか?私が見ていない別のアプローチはありますか?

カウントダウンタイマーとロックはインスタンス変数である必要がありますか、それともクラスのすべてのインスタンスがリクエストを保持するように、それらはクラスに属している必要がありますか?

また、これはライブラリ内でレート制限機能を提供するための一般的に悪い考えですか?デフォルトではカウントダウンは0秒であるため、ライブラリを使用すると、開発者はライブラリを使用して独自のレート制限スキームを提供できます。このサービスを使用する開発者はとにかくリクエストをレート制限する必要があることを考えると、ライブラリがレート制限の手段を提供するのは便利だと思います。

ライブラリに律速スキームを配置するかどうかに関係なく、ライブラリを使用してアプリケーションを作成したいので、提案された手法が役立ちます。

4

6 に答える 6

11

これは、キューとディスパッチャを使用するとうまく機能します。

処理をソースディスパッチの2つの側面に分割します。これらは個別のスレッド(または、より簡単な場合は個別のプロセス)にすることができます。

ソース側は、リクエストを満足させる速度でリクエストを作成してキューに入れます。

ディスパッチ側がこれを行います。

  1. リクエストの開始時刻sを取得します。

  2. リクエストをデキューし、リモートサービスを介してリクエストを処理します。

  3. 現在の時刻tを取得します。レート-(t - s)秒間スリープします。

リモートサービスに直接接続されたソース側を実行する場合は、それを実行し、レート制限をバイパスできます。これは、リモートサービスのモックバージョンを使用した内部テストに適しています。

これに関する難しい部分は、エンキューできる各リクエストの表現を作成することです。Pythonキューはほとんどすべてを処理するため、多くのことを行う必要はありません。

マルチプロセッシングを使用している場合は、オブジェクトをピクルスにしてパイプに入れる必要があります。

于 2008-12-30T20:00:33.837 に答える
2

キューイングは非常に複雑な場合があります。より簡単な解決策は、サービスが最後に呼び出された時間の変数をクラスに与えることです。サービスが呼び出されるたびに (!1)、waitTime を に設定しdelay - Now + lastcalltimeます。 delay要求間の最小許容時間と等しくする必要があります。この数値が正の場合、呼び出しを行う前にその時間だけスリープします (!2)。このアプローチの欠点/利点は、Web サービス要求を同期として扱うことです。利点は、非常にシンプルで実装が簡単なことです。

  • (!1): サービスから応答を受け取った直後、ラッパー内 (おそらくラッパーの下部) で発生するはずです。
  • (!2): Web サービスの周りの Python ラッパーが呼び出されたときに、ラッパーの上部で発生するはずです。

もちろん、S.Lott のソリューションはよりエレガントです。

于 2008-12-30T20:23:16.913 に答える
1

レート制限スキームは、基になるコード(同期または非同期)の呼び出し規約、およびこのレート制限が動作するスコープ(スレッド、プロセス、マシン、クラスター?)に大きく影響される必要があります。

複数の期間/制御レートを簡単に実装できるように、すべての変数をインスタンス内に保持することをお勧めします。

最後に、ミドルウェアコンポーネントになりたいようです。アプリケーションになり、自分でスレッドを導入しようとしないでください。同期している場合はブロック/スリープし、いずれかから呼び出されている場合は非同期ディスパッチングフレームワークを使用します。

于 2008-12-30T20:05:47.103 に答える
1

ライブラリが同期するように設計されている場合は、制限の適用を除外することをお勧めします (ただし、レートを追跡し、少なくとも呼び出し元が制限を尊重する方法を決定するのに役立ちます)。

私は現在、ほとんどすべてのものとのインターフェースにtwistedを使用しています。リクエストの送信とレスポンスの処理を分離するモデルを使用することで、そのようなことを簡単に行うことができます。API ユーザーがツイストを使用する必要がないようにする場合は、少なくとも遅延実行用の API を理解することをお勧めします。

たとえば、xmpp ユーザーに代わってかなりばかげた数のリクエストをプッシュする twitter インターフェースがあります。レート制限はしていませんが、すべてのリクエストが同時に発生するのを防ぐために少し作業を行う必要がありました。

于 2008-12-30T20:43:37.917 に答える
1

SO私は、 import time time.sleep(2) のような単純なものが、リクエスト間で2秒間待機するために機能しないと想定しています

于 2008-12-30T23:25:39.120 に答える