我们正在运行Http Api,并且希望能够设置用户每个时间单位可以执行的请求数量的限制。达到此限制后,我们不希望用户收到错误,例如Http 429.我们希望增加响应时间。这导致用户可以继续工作,但速度较慢,然后可以选择升级或不升级其付款计划。对于已经超过其限制的用户的所有请求,可以使用Thread.sleep(或类似的东西)非常容易地实现此解决方案x秒。
我们认为在最坏的情况下,单个服务器的可能连接数可能存在问题,因为只要我们不断延迟响应,我们就会保持连接打开,从而限制可能的其他连接数量
对Api的所有请求都是异步运行的。服务器本身是可扩展的,并且在负载均衡器后面运行。如有必要,我们可以启动其他服务器。
在搜索这种类型的限制时,我们发现很少有这种限制用户的例子,我们发现的例子似乎并不关心用完的连接。所以我们想知道这不是问题吗?
我们缺少这个缺点,或者这是一个可行的解决方案吗?我们可以同时打开多少个连接而不会出现问题?我们的愿景能否以另一种方式解决,即不给用户带来错误?
答案 0 :(得分:4)
Thread.Sleep()
几乎是您在Web服务器上可能做的最糟糕的事情。您正在异步运行事物并不重要,因为这仅适用于I / O绑定操作,然后释放线程以执行更多工作。
通过使用Sleep()
命令,您将有效地将该线程暂时停止使用。
ASP.Net应用程序池可用的线程数量有限,因此在最坏的情况下,您将服务器的总连接数最多为40-50(无论默认值是多少),如果所有人都在一起睡觉。
<强>其次强>
这会在DOS 方面打开一个主要的攻击媒介。如果我是攻击者,我可以通过旋转100或1000个连接轻松取出整个服务器,所有这些都使用相同的API密钥。使用这种方法,服务器将尽职尽责地开始让所有线程进入休眠状态,然后进行游戏。
因此 可以 使用Task.Delay()
,以便在响应中插入任意数量的延迟。在引擎盖下它使用Timer
,这比使用线程轻得多。
await Task.Delay(numberOfMilliseconds);
<强>然而... 强>
这只关注等式的一面。在延迟期间,您仍然可以与服务器建立开放连接。 因为这是一种有限的资源,它仍然容易受到通常不存在的DOS攻击。
这可能是您可接受的风险,但您至少应该意识到这种可能性。
答案 1 :(得分:0)
为什么不在客户端上添加“Please Wait ...”来人为地看起来像是在处理?在服务器成本上增加人为延迟会导致连接以及线程不必要地连接起来。