【发布时间】:2017-11-13 16:12:43
【问题描述】:
我在 Azure Web 作业上实施了一个限制机制。我们网络工作的“工作”是全天不断地从第三方 api 下载单独的 .wav 文件。它每天(现在)大约执行 5,000 次。但是,第 3 方 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 的经验。我是否可能在某个时间点引入无限循环?还有什么我可以忽略的可能会导致问题的东西,尤其是当我们扩大到每天 1,000,000 个请求时?
【问题讨论】:
-
如果简单得多,难道不是一个简单的计时器吗?
-
这是个好主意。但是,我们希望它尽可能快地运行。如果我们使用计时器,我们必须有一个硬编码的时间间隔,可能设置为 60 秒,以便每个单独的 wav 文件运行。这将导致我们的处理速度可能慢 6 倍(60 秒与 10 秒相比)。
标签: c# azure caching azure-webjobs memorycache