私はAzure Webジョブでスロットルメカニズムを実装しました。私たちのWeb仕事の「仕事」は、サードパーティーのapiから別々の.wavファイルを1日中ずっとダウンロードすることです。そして、これは1日に約5,000回(現在)行う。ただし、サードパーティのAPIには使用制限があり、60秒ごとに最大10のwavファイルしかダウンロードできません。これを超えると、次の60秒ごとに要求ごとに429のエラーが発生します。スロットリングにキャッシング機構を使用するのは問題ですか?
私はこのAPIへのリクエストを抑制するために少しコードを実装しました。
var maxPerPeriod = 10;
var keyPrefix = RingCentralId;
var intervalPeriod = 60000;
var sleepInterval = 5000;
var recentTransactions = MemoryCache.Default.Count(x => x.Key.StartsWith(keyPrefix));
while (recentTransactions >= maxPerPeriod)
{
System.Threading.Thread.Sleep(sleepInterval);
recentTransactions = MemoryCache.Default.Count(x => x.Key.StartsWith(keyPrefix));
}
var key = keyPrefix + "_" + DateTime.Now.ToUniversalTime().ToString("yyyyMMddHHmmss");
var existing = MemoryCache.Default.Where(x => x.Key.StartsWith(key));
if (existing != null && existing.Any())
{
var counter = 2;
var last = existing.OrderBy(x => x.Key).Last();
var pieces = last.Key.Split('_');
if (pieces.Count() > 2)
{
var lastCount = 0;
if (int.TryParse(pieces[2], out lastCount))
{
counter = lastCount + 1;
}
}
key = key + "_" + counter;
}
var policy = new CacheItemPolicy
{
AbsoluteExpiration = DateTimeOffset.UtcNow.AddMilliseconds(intervalPeriod)
};
MemoryCache.Default.Set(key, 1, policy);
そして、これは実際には(少なくとも今のところは)美しく動作します。これは今、すべての要求の前に実行されますコードのブロックです。お分かりのように、私は60秒間それぞれ固有のキーを持つキャッシュを使用しています。このメカニズムはキャッシュを検索し、キャッシュに現在10個以上存在する場合は、期限が切れるまで待機する必要があることを意味します。そして私はwhile
ループを実装することでこれを行います。そして、それは私を最も懸念している部分です。私はMemoryCache
を使って多くの経験を持っていません。ある時点で無限ループを導入する可能性はありますか?問題を引き起こす可能性があることを見落としている可能性があることは他にありますか?
単純なタイマーははるかに複雑ではないでしょうか? –
それは良い考えです。しかし、これを可能な限り速く実行したいと考えています。タイマーを使用する場合は、個々のwavファイルを実行するために、おそらく60秒に設定されたハードコードされた間隔が必要です。これにより、処理が6倍遅くなる可能性があります(10秒と比較して60秒)。 –