ASP.NET Web API Throttling handler is designed to control the rate of requests that clients can make to a Web API based on IP address, client API key and request route. WebApiThrottle is compatible with Web API v2 and can be installed via NuGet, the package is available atnuget.org/packages/WebApiThrottle.

Web API throttling can be configured using the built-in ThrottlePolicy. You can set multiple limits for different scenarios like allowing an IP or Client to make a maximum number of calls per second, per minute, per hour or even per day. You can define these limits to address all requests made to an API or you can scope the limits to each API route.

Global throttling based on IP

The setup bellow will limit the number of requests originated from the same IP.
If from the same IP, in same second, you’ll make a call to api/values and api/values/1 the last call will get blocked.

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MessageHandlers.Add(new ThrottlingHandler()
{
Policy = new ThrottlePolicy(perSecond: 1, perMinute: 20,
perHour: 200, perDay: 1500, perWeek: 3000)
{
IpThrottling = true
},
Repository = new CacheRepository()
});
}
}

If you are self-hosting WebApi with Owin, then you’ll have to switch to MemoryCacheRepository that uses the runtime memory cache instead of CacheRepository that uses ASP.NET cache.

public class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration(); //Register throttling handler
config.MessageHandlers.Add(new ThrottlingHandler()
{
Policy = new ThrottlePolicy(perSecond: 1, perMinute: 20,
perHour: 200, perDay: 1500, perWeek: 3000)
{
IpThrottling = true
},
Repository = new MemoryCacheRepository()
}); appBuilder.UseWebApi(config);
}
}

Endpoint throttling based on IP

If, from the same IP, in the same second, you’ll make two calls to api/values, the last call will get blocked.
But if in the same second you call api/values/1 too, the request will go through because it’s a different route.

config.MessageHandlers.Add(new ThrottlingHandler()
{
Policy = new ThrottlePolicy(perSecond: 1, perMinute: 30)
{
IpThrottling = true,
EndpointThrottling = true
},
Repository = new CacheRepository()
});

Endpoint throttling based on IP and Client Key

If a client (identified by an unique API key) from the same IP, in the same second, makes two calls toapi/values, then the last call will get blocked.
If you want to apply limits to clients regardless of their IPs then you should set IpThrottling to false.

config.MessageHandlers.Add(new ThrottlingHandler()
{
Policy = new ThrottlePolicy(perSecond: 1, perMinute: 30)
{
IpThrottling = true,
ClientThrottling = true,
EndpointThrottling = true
},
Repository = new CacheRepository()
});

IP and/or Client Key White-listing

If requests are initiated from a white-listed IP or Client, then the throttling policy will not be applied and the requests will not get stored. The IP white-list supports IP v4 and v6 ranges like “192.168.0.0/24″, “fe80::/10″ and “192.168.0.0-192.168.0.255″ for more information check jsakamoto/ipaddressrange.

config.MessageHandlers.Add(new ThrottlingHandler()
{
Policy = new ThrottlePolicy(perSecond: 2, perMinute: 60)
{
IpThrottling = true,
IpWhitelist = new List<string> { "::1", "192.168.0.0/24" }, ClientThrottling = true,
ClientWhitelist = new List<string> { "admin-key" }
},
Repository = new CacheRepository()
});

IP and/or Client Key custom rate limits

You can define custom limits for known IPs or Client Keys, these limits will override the default ones. Be aware that a custom limit will only work if you have defined a global counterpart.

config.MessageHandlers.Add(new ThrottlingHandler()
{
Policy = new ThrottlePolicy(perSecond: 1, perMinute: 20, perHour: 200, perDay: 1500)
{
IpThrottling = true,
IpRules = new Dictionary<string, RateLimits>
{
{ "192.168.1.1", new RateLimits { PerSecond = 2 } },
{ "192.168.2.0/24", new RateLimits { PerMinute = 30 } }
}, ClientThrottling = true,
ClientRules = new Dictionary<string, RateLimits>
{
{ "api-client-key-1", new RateLimits { PerMinute = 40 } },
{ "api-client-key-9", new RateLimits { PerDay = 2000 } }
}
},
Repository = new CacheRepository()
});

Endpoint custom rate limits

You can also define custom limits for certain routes, these limits will override the default ones.
You can define endpoint rules by providing relative routes like api/entry/1 or just a URL segment like/entry/.
The endpoint throttling engine will search for the expression you’ve provided in the absolute URI,
if the expression is contained in the request route then the rule will be applied.
If two or more rules match the same URI then the lower limit will be applied.

config.MessageHandlers.Add(new ThrottlingHandler()
{
Policy = new ThrottlePolicy(perSecond: 1, perMinute: 20, perHour: 200)
{
IpThrottling = true,
ClientThrottling = true,
EndpointThrottling = true,
EndpointRules = new Dictionary<string, RateLimits>
{
{ "api/search",
new RateLimits { PerScond = 10, PerMinute = 100, PerHour = 1000 } }
}
},
Repository = new CacheRepository()
});

Stack rejected requests

By default, rejected calls are not added to the throttle counter. If a client makes 3 requests per second
and you’ve set a limit of one call per second, the minute, hour and day counters will only record the first call, the one that wasn’t blocked.
If you want rejected requests to count towards the other limits, you’ll have to setStackBlockedRequests to true.

config.MessageHandlers.Add(new ThrottlingHandler()
{
Policy = new ThrottlePolicy(perSecond: 1, perMinute: 30)
{
IpThrottling = true,
ClientThrottling = true,
EndpointThrottling = true,
StackBlockedRequests = true
},
Repository = new CacheRepository()
});

Define rate limits in web.config or app.config

WebApiThrottle comes with a custom configuration section that lets you define the throttle policy as xml.

config.MessageHandlers.Add(new ThrottlingHandler()
{
Policy = ThrottlePolicy.FromStore(new PolicyConfigurationProvider()),
Repository = new CacheRepository()
});

Config example (policyType values are 1 – IP, 2 – ClientKey, 3 – Endpoint):

<configuration>

  <configSections>
<section name="throttlePolicy"
type="WebApiThrottle.ThrottlePolicyConfiguration, WebApiThrottle" />
</configSections> <throttlePolicy limitPerSecond="1"
limitPerMinute="10"
limitPerHour="30"
limitPerDay="300"
limitPerWeek ="1500"
ipThrottling="true"
clientThrottling="true"
endpointThrottling="true">
<rules>
<add policyType="1" entry="::1/10"
limitPerSecond="2"
limitPerMinute="15"/>
<add policyType="1" entry="192.168.2.1"
limitPerMinute="12" />
<add policyType="2" entry="api-client-key-1"
limitPerHour="60" />
<add policyType="3" entry="api/values"
limitPerDay="120" />
</rules>
<whitelists>
<add policyType="1" entry="127.0.0.1" />
<add policyType="1" entry="192.168.0.0/24" />
<add policyType="2" entry="api-admin-key" />
</whitelists>
</throttlePolicy> </configuration>

Retrieving API Client Key

By default, the ThrottlingHandler retrieves the client API key from the “Authorization-Token” request header value.
If your API key is stored differently, you can override the ThrottlingHandler.SetIndentity function and specify your own retrieval method.

public class CustomThrottlingHandler : ThrottlingHandler
{
protected override RequestIndentity SetIndentity(HttpRequestMessage request)
{
return new RequestIndentity()
{
ClientKey = request.Headers.GetValues("Authorization-Key").First(),
ClientIp = base.GetClientIp(request).ToString(),
Endpoint = request.RequestUri.AbsolutePath
};
}
}

Storing throttle metrics

WebApiThrottle stores all request data in-memory using ASP.NET Cache when hosted in IIS or Runtime MemoryCache when self-hosted with Owin. If you want to change the storage to
Velocity, MemCache or a NoSQL database, all you have to do is create your own repository by implementing the IThrottleRepository interface.

public interface IThrottleRepository
{
bool Any(string id); ThrottleCounter? FirstOrDefault(string id); void Save(string id, ThrottleCounter throttleCounter, TimeSpan expirationTime); void Remove(string id); void Clear();
}

Logging throttled requests

If you want to log throttled requests you’ll have to implement IThrottleLogger interface and provide it to the ThrottlingHandler.

public interface IThrottleLogger
{
void Log(ThrottleLogEntry entry);
}

Logging implementation example with ITraceWriter

public class TracingThrottleLogger : IThrottleLogger
{
private readonly ITraceWriter traceWriter; public TracingThrottleLogger(ITraceWriter traceWriter)
{
this.traceWriter = traceWriter;
} public void Log(ThrottleLogEntry entry)
{
if (null != traceWriter)
{
traceWriter.Info(entry.Request, "WebApiThrottle",
"{0} Request {1} from {2} has been throttled (blocked), quota {3}/{4} exceeded by {5}",
entry.LogDate,
entry.RequestId,
entry.ClientIp,
entry.RateLimit,
entry.RateLimitPeriod,
entry.TotalRequests);
}
}
}

Logging usage example with SystemDiagnosticsTraceWriter

var traceWriter = new SystemDiagnosticsTraceWriter()
{
IsVerbose = true
};
config.Services.Replace(typeof(ITraceWriter), traceWriter);
config.EnableSystemDiagnosticsTracing(); config.MessageHandlers.Add(new ThrottlingHandler()
{
Policy = new ThrottlePolicy(perSecond: 1, perMinute: 30)
{
IpThrottling = true,
ClientThrottling = true,
EndpointThrottling = true
},
Repository = new CacheRepository(),
Logger = new TracingThrottleLogger()
});

About

WebApiThrottle is open sourced and MIT licensed, the project is hosted on GitHub atgithub.com/stefanprodan/WebApiThrottle, for questions regarding throttling or any problems you’ve encounter please submit an issue on GitHub.

WebApiThrottle限流框架的更多相关文章

  1. WebApiThrottle限流框架使用手册

    阅读目录: 介绍 基于IP全局限流 基于IP的端点限流 基于IP和客户端key的端点限流 IP和客户端key的白名单 IP和客户端key自定义限制频率 端点自定义限制频率 关于被拒请求的计数器 在we ...

  2. webapi限流框架WebApiThrottle

    为了防止网站意外暴增的流量比如活动.秒杀.攻击等,导致整个系统瘫痪,在前后端接口服务处进行流量限制是非常有必要的.本篇主要介绍下Net限流框架WebApiThrottle的使用. WebApiThro ...

  3. 【Dnc.Api.Throttle】适用于.Net Core WebApi接口限流框架

    Dnc.Api.Throttle    适用于Dot Net Core的WebApi接口限流框架 使用Dnc.Api.Throttle可以使您轻松实现WebApi接口的限流管理.Dnc.Api.Thr ...

  4. 微服务组件--限流框架Spring Cloud Hystrix分析

    Hystrix的介绍 [1]Hystrix是springCloud的组件之一,Hystrix 可以让我们在分布式系统中对服务间的调用进行控制加入一些调用延迟或者依赖故障的容错机制. [2]Hystri ...

  5. 控制ASP.NET Web API 调用频率与限流

    ASP.NET MVC 实现 https://github.com/stefanprodan/MvcThrottle ASP.NET WEBAPI 实现 https://github.com/stef ...

  6. Spring Cloud alibaba网关 sentinel zuul 四 限流熔断

    spring cloud alibaba 集成了 他内部开源的 Sentinel 熔断限流框架 Sentinel 介绍 官方网址 随着微服务的流行,服务和服务之间的稳定性变得越来越重要.Sentine ...

  7. 简易RPC框架-客户端限流配置

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  8. Anno 框架 增加缓存、限流策略、事件总线、支持 thrift grpc 作为底层传输

    github 地址:https://github.com/duyanming/dymDemo dym 分布式开发框架 Demo 熔断 限流 事件总线(包括基于内存的.rabbitmq的) CQRS D ...

  9. 快速入门系列--WCF--06并发限流、可靠会话和队列服务

    这部分将介绍一些相对深入的知识点,包括通过并发限流来保证服务的可用性,通过可靠会话机制保证会话信息的可靠性,通过队列服务来解耦客户端和服务端,提高系统的可服务数量并可以起到削峰的作用,最后还会对之前的 ...

随机推荐

  1. HTML的盒子模型

    每个HTML元素都可以看作一个装了东西的盒子,盒子具有宽度(width)和高度(height),盒子里面的内容到盒子的边框之间的距离即填充(padding),盒子本身有边框(border),而盒子边框 ...

  2. 10年山东省赛-E-最短路

    题目连接:http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2155&cid=1430 题意:输入一个n个节点,m条边的图,然后k条记录,纪录 ...

  3. 【LeetCode OJ】Interleaving String

    Problem Link: http://oj.leetcode.com/problems/interleaving-string/ Given s1, s2, s3, find whether s3 ...

  4. UI基础:UICollectionView

    UITableView 和 UICollectionView的设计思路: 1.UITableView 的布局由TableView和UItableViewDelegate完成. 2.UICollecti ...

  5. 使用java理解程序逻辑 第三章 选择结构一

    if 选择结构: if(条件){       代码块  //条件成立后要执行的代码.可以是一条语句,也可以是一组语句 } 可以处理单一或组合条件的情况. if-else 选择结构: if(条件){   ...

  6. Bat脚本处理ftp超强案例解说

    Bat脚本处理ftp超强案例解说 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://369369.blog.51cto.com/31 ...

  7. parse,tryparse区别

    Convert.ToInt32.int.Parse(Int32.Parse).int.TryParse.(int) 四者都可以解释为将类型转换为 int,那它们的区别是什么呢? Convert.ToI ...

  8. Android 学习第1课,JDK工具包的安装

    1. jdk 的下载 目前为止,jdk的最新版是jdk8,http://www.oracle.com/technetwork/java/javase/downloads/index.html 到这里下 ...

  9. C# 控件不刷新问题

    /********************************************************************** * C# 控件不刷新问题 * 说明: * 当网络连接出问 ...

  10. X86平台乱序执行简要分析(翻译为主)

    多处理器使用松散的内存模型可能会非常混乱,写操作可能会无序,读操作可能会返回不是我们想要的值,为了解决这些问题,我们需要使用内存栅栏(memory fences),或者说内存屏障(memory bar ...