如何使用响应式扩展来限制客户端请求
Posted
技术标签:
【中文标题】如何使用响应式扩展来限制客户端请求【英文标题】:How to use Reactive Extensions to throttle client requests 【发布时间】:2014-09-22 15:06:11 【问题描述】:我有一个服务器从许多客户端接收许多对象,并且每次接收到一个对象时都会触发 ObjectReceived
事件,包括在谁发送了什么的参数中。
问题:有一个客户端向我的服务器发出请求,但我的服务器总是响应。
我想根据谁发出请求来限制请求。例如,如果我在 1 秒内收到来自 100 个不同客户端的 100 个请求,并且每个客户端发出了不同的请求,我会响应每个发出请求的客户端;但是如果我在 1 秒内收到来自 2 个客户端的 100 个请求,并且每个客户端执行相同的请求 50 次,我只响应两次,一次响应客户端 A,一次响应客户端 B。
在 Rx 中可以吗?
【问题讨论】:
可能是。我们缺少一些信息。假设您想以 1 个请求/秒的速度响应,但烦人的客户端以 100 个/秒的速度发送它们。剩下的99个怎么办?排队?当队列有 1,000,000 个条目时会发生什么?内存不足?拒绝他们?如何拒绝? 你说得对,已编辑 您所面临的情况称为 DOS 攻击。安全性是您的应用程序的一个方面,在我看来,您应该在尽可能低的层中修复它。看看这个Prevent Malicious Requests - DOS Attacks 和Block DoS attacks easily in ASP.NET。还请查看最后一个链接的 cmets,以获取一些改进建议。 我当然同意最低级别的观点——也就是说,我必须制定政策来防止非恶意过度使用具有复杂业务领域规则的 API。不过,这些天来,这类东西越来越多地通过 API 托管产品(如 apigee、3scale 等)提供。甚至 Azure 现在也有。 【参考方案1】:是的,一种方法是按客户端 ID 对请求进行分组并有选择地应用限制。
假设您有这样的活动:
public class MyEvent
public int ClientId get; set;
public override string ToString()
return ClientId.ToString();
让我们设置慢速和快速客户端:
var slow = Observable.Interval(TimeSpan.FromSeconds(2))
.Select(_ => new MyEvent ClientId = 1 );
var fast = Observable.Interval(TimeSpan.FromSeconds(0.5))
.Select(_ => new MyEvent ClientId = 2 );
var all = slow.Merge(fast);
现在像这样选择性地节流:
var throttled = all.GroupBy(x => x.ClientId).Select(
// apply the throttle here, this could even test the key
// property to apply different throttles to different clients
x => x.Throttle(TimeSpan.FromSeconds(1)))
.SelectMany(x => x);
并对其进行测试:
throttled.Subscribe(x => Console.WriteLine(x.ToString()));
使用此限制,快速客户端将永远不会得到响应 - 限制将无限期地抑制他的请求,因为它们之间的间隔不到一秒。您可以使用其他运算符以不同方式抑制 - 例如Sample
可以在给定的时间间隔内挑选出单个请求。
修改问题后
您可以应用不同于 ClientId 和使用 Throttle
的规则 - 例如,您可以在客户端流上使用 DistinctUntilChanged()
以清除重复请求。
【讨论】:
嗨,Throttle 和 Sample 实际上延迟了我订阅的执行。有没有办法立即响应第一个请求,并且在一定时间内不接受同一种请求? @sam 试试这个。我为这个老问题添加了一个新答案,我认为它可以很好地解决所有问题:***.com/questions/7999503/…【参考方案2】:略有不同的问题:Best way to implement request throttling in ASP.NET MVC?
在任何情况下,性能非常好的典型算法都是:Hierarchical Token bucket。
分层令牌桶 (HTB) 是一种更快的替代 Linux 中基于类的排队 (CBQ) 排队规则。
HTB 有助于控制给定设备上出站带宽的使用 关联。 HTB 允许使用单个物理链路来模拟多个 较慢的链接并在不同的设备上发送不同类型的流量 模拟链接。在这两种情况下,都必须指定如何划分 物理链路变成模拟链路以及如何决定哪个模拟链路 链接一个给定的数据包将被发送。
换句话说,HTB对于限制客户端的下载/上传非常有用 速度。因此,有限的客户端无法使总带宽饱和。
【讨论】:
以上是关于如何使用响应式扩展来限制客户端请求的主要内容,如果未能解决你的问题,请参考以下文章