限制 ASP.NET Web API 服务的同时请求
Limit the simultaneous requests served by the ASP.NET Web API
我正在使用 ASP.NET Web API 2.2 和 Owin 一起构建 Web 服务,我观察到对控制器的每次调用都将由单独的线程提供服务 运行ning在服务器端,这并不奇怪,而且是我预期的行为。
我现在遇到的一个问题是,因为服务器端操作非常占用内存,所以如果超过 X 数量的用户同时呼入,服务器代码很可能会抛出一个错误-内存异常。
是否可以设置全局 "maximum action count" 以便 Web Api 可以对来电进行排队(而不是拒绝)并且仅在有空槽时才继续。
我无法 运行 64 位网络服务,因为一些引用的库不支持它。
我也查看了像 https://github.com/stefanprodan/WebApiThrottle 这样的库,但它只能根据调用频率进行限制。
谢谢
您可以按照以下方式添加一段 OwinMiddleware
(受您链接到的 WebApiThrottle 的影响):
public class MaxConccurrentMiddleware : OwinMiddleware
{
private readonly int maxConcurrentRequests;
private int currentRequestCount;
public MaxConccurrentMiddleware(int maxConcurrentRequests)
{
this.maxConcurrentRequests = maxConcurrentRequests;
}
public override async Task Invoke(IOwinContext context)
{
try
{
if (Interlocked.Increment(ref currentRequestCount) > maxConcurrentRequests)
{
var response = context.Response;
response.OnSendingHeaders(state =>
{
var resp = (OwinResponse)state;
resp.StatusCode = 429; // 429 Too Many Requests
}, response);
return Task.FromResult(0);
}
await Next.Invoke(context);
}
finally
{
Interlocked.Decrement(ref currentRequestCount);
}
}
}
我正在使用 ASP.NET Web API 2.2 和 Owin 一起构建 Web 服务,我观察到对控制器的每次调用都将由单独的线程提供服务 运行ning在服务器端,这并不奇怪,而且是我预期的行为。
我现在遇到的一个问题是,因为服务器端操作非常占用内存,所以如果超过 X 数量的用户同时呼入,服务器代码很可能会抛出一个错误-内存异常。
是否可以设置全局 "maximum action count" 以便 Web Api 可以对来电进行排队(而不是拒绝)并且仅在有空槽时才继续。
我无法 运行 64 位网络服务,因为一些引用的库不支持它。
我也查看了像 https://github.com/stefanprodan/WebApiThrottle 这样的库,但它只能根据调用频率进行限制。
谢谢
您可以按照以下方式添加一段 OwinMiddleware
(受您链接到的 WebApiThrottle 的影响):
public class MaxConccurrentMiddleware : OwinMiddleware
{
private readonly int maxConcurrentRequests;
private int currentRequestCount;
public MaxConccurrentMiddleware(int maxConcurrentRequests)
{
this.maxConcurrentRequests = maxConcurrentRequests;
}
public override async Task Invoke(IOwinContext context)
{
try
{
if (Interlocked.Increment(ref currentRequestCount) > maxConcurrentRequests)
{
var response = context.Response;
response.OnSendingHeaders(state =>
{
var resp = (OwinResponse)state;
resp.StatusCode = 429; // 429 Too Many Requests
}, response);
return Task.FromResult(0);
}
await Next.Invoke(context);
}
finally
{
Interlocked.Decrement(ref currentRequestCount);
}
}
}