【问题标题】:What are the downsides to Request throttling using delay (C# .Net 4 Web Server)使用延迟请求限制的缺点是什么(C# .Net 4 Web 服务器)
【发布时间】:2015-02-07 10:22:09
【问题描述】:

我们正在运行一个 Http Api,并希望能够对用户在每个时间单位内可以执行的请求数进行限制。当达到这个限制时,我们不希望用户收到错误,例如 Http 429。相反,我们希望增加响应时间。这导致用户可以继续工作,但速度较慢,然后可以选择升级或不升级其付费计划。对于已超过其限制的用户的所有请求,此解决方案可以很容易地使用 Thread.sleep(或类似的东西)在 x 秒内实现。

我们认为,在最坏的情况下,单个服务器的可能连接数可能会出现问题,因为只要我们一直延迟响应,我们就会保持连接打开,从而限制其他可能的连接数.

对 Api 的所有请求都是异步运行的。服务器本身被构建为可扩展的,并且在负载平衡器后面运行。如有必要,我们可以启动额外的服务器。

在搜索这种类型的限制时,我们发现很少有这种限制用户的方式的例子,而且我们发现的例子似乎根本不关心连接耗尽。所以我们想知道这不是问题吗?

我们是否缺少任何缺点,或者这是一个可行的解决方案?我们可以同时打开多少个连接而不会出现问题?我们的愿景能否以另一种方式解决,即不给用户带来错误?

【问题讨论】:

  • 听起来像是您应该在网络级别而不是在应用程序内执行的操作。如果您使用Thread.Sleep(),您将面临无法处理请求的风险,因为线程池中的所有线程都已用完休眠,因此您基本上已经自己DOS了。

标签: c# api .net-4.0 request throttling


【解决方案1】:

Thread.Sleep() 几乎是您在 Web 服务器上可以做的最糟糕的事情。异步运行并不重要,因为这仅适用于 I/O 绑定操作,然后释放线程以完成更多工作。

通过使用Sleep() 命令,您将有效地使该线程在其休眠期间停止使用。

ASP.Net 应用程序池可供它们使用的线程数量有限,因此在最坏的情况下,您将在 40-50(无论默认值是多少)中最大化连接到服务器的总数,如果他们都在同时睡觉。

其次

这打开了 DOS 方面的主要攻击媒介。如果我是攻击者,我可以通过启动 100 或 1000 个连接来轻松搞定你的整个服务器,所有连接都使用相同的 API 密钥。使用这种方法,服务器将尽职尽责地开始让所有线程进入睡眠状态,然后游戏结束。

更新

所以您可以使用Task.Delay() 在响应中插入任意数量的延迟。在引擎盖下它使用Timer,它比使用线程轻得多。

await Task.Delay(numberOfMilliseconds);

但是...

这只涉及等式的一侧。在延迟期间,您仍然有与服务器的开放连接。 因为这是一种有限的资源,它仍然使您容易受到通常不会存在的 DOS 攻击。

这可能是您可以接受的风险,但您至少应该意识到这种可能性。

【讨论】:

  • 是的,这些都是不采用此解决方案的好论据。我们将重新考虑策略。谢谢
【解决方案2】:

为什么不简单地在客户端上添加“请稍候...”以人为地看起来它正在处理?在服务器上添加人为延迟会使您付出代价,它会使连接和线程不必要地被占用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多