ASP.NET MVC에서 요청 조절을 구현하는 가장 좋은 방법은 무엇입니까?


212

우리는 주어진 기간 동안 사용자 행동을 조절하는 다양한 방법을 실험하고 있습니다 .

  • 질문 / 답변 게시물 제한
  • 편집 제한
  • 피드 검색 제한

당분간은 캐시를 사용하여 단순히 사용자 활동 레코드를 삽입하고 있습니다. 사용자가 동일한 활동을 수행하는 경우 해당 레코드가 존재하는 경우 스로틀합니다.

캐시를 사용하면 자동으로 오래된 데이터 정리 및 사용자 슬라이딩 활동 창이 제공되지만 어떻게 확장되는지 문제가 될 수 있습니다.

요청 / 사용자 작업을 효과적으로 조절할 수있는 다른 방법은 무엇입니까 (안정성 강조)?


사용자 당 또는 질문 당으로 제한하려고합니까? 사용자별로 세션을 사용할 수있는 경우 더 작은 세트입니다.
Greg Ogle

1
사용자 당이지만 쿠키가 필요하므로 세션을 사용할 수 없습니다. 현재 IP 주소를 기준으로 제한하고 있습니다.
Jarrod Dixon

1
요즘 nuget 패키지 고려 github.com/stefanprodan/MvcThrottle MVC 페이지와 대한 github.com/stefanprodan/WebApiThrottle 웹 API 요청을
앤디

답변:


240

지난해 Stack Overflow에서 사용한 일반적인 버전은 다음과 같습니다.

/// <summary>
/// Decorates any MVC route that needs to have client requests limited by time.
/// </summary>
/// <remarks>
/// Uses the current System.Web.Caching.Cache to store each client request to the decorated route.
/// </remarks>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class ThrottleAttribute : ActionFilterAttribute
{
    /// <summary>
    /// A unique name for this Throttle.
    /// </summary>
    /// <remarks>
    /// We'll be inserting a Cache record based on this name and client IP, e.g. "Name-192.168.0.1"
    /// </remarks>
    public string Name { get; set; }

    /// <summary>
    /// The number of seconds clients must wait before executing this decorated route again.
    /// </summary>
    public int Seconds { get; set; }

    /// <summary>
    /// A text message that will be sent to the client upon throttling.  You can include the token {n} to
    /// show this.Seconds in the message, e.g. "Wait {n} seconds before trying again".
    /// </summary>
    public string Message { get; set; }

    public override void OnActionExecuting(ActionExecutingContext c)
    {
        var key = string.Concat(Name, "-", c.HttpContext.Request.UserHostAddress);
        var allowExecute = false;

        if (HttpRuntime.Cache[key] == null)
        {
            HttpRuntime.Cache.Add(key,
                true, // is this the smallest data we can have?
                null, // no dependencies
                DateTime.Now.AddSeconds(Seconds), // absolute expiration
                Cache.NoSlidingExpiration,
                CacheItemPriority.Low,
                null); // no callback

            allowExecute = true;
        }

        if (!allowExecute)
        {
            if (String.IsNullOrEmpty(Message))
                Message = "You may only perform this action every {n} seconds.";

            c.Result = new ContentResult { Content = Message.Replace("{n}", Seconds.ToString()) };
            // see 409 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
            c.HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
        }
    }
}

샘플 사용법 :

[Throttle(Name="TestThrottle", Message = "You must wait {n} seconds before accessing this url again.", Seconds = 5)]
public ActionResult TestThrottle()
{
    return Content("TestThrottle executed");
}

ASP.NET 캐시는 여기서 챔피언처럼 작동합니다.이를 사용하면 스로틀 항목을 자동으로 정리할 수 있습니다. 그리고 트래픽이 증가함에 따라 이것이 서버에서 문제가되는 것을 보지 못했습니다.

이 방법에 대한 의견을 자유롭게 보내십시오. 스택 오버플로를 개선하면 Ewok 수정이 훨씬 빨라집니다. :)


5
빠른 질문-c.HttpContext.Request.UserHostAddress 값을 키의 일부로 사용하고 있습니다. 해당 값이 비어 있거나 null 또는 모두 같은 값입니까? (즉,로드 밸런서를 사용하고 있고 실제 클라이언트가 아닌 해당 머신의 IP 인 경우) 프록시 또는로드 밸런서 (예 : BIG IP F5)에 동일한 데이터를 입력하고 확인해야합니다. X-Forwarded-For 또는 무엇인가?
Pure.Krome

7
@ Pure.Krome-그렇습니다. 클라이언트 IP를 검색 할 때, 우리는 그 검사 모두 도우미 기능을 사용 REMOTE_ADDR하고 HTTP_X_FORWARDED_FOR서버 변수 및 소독하라고 적절.
Jarrod Dixon

3
@BrettRobi, 나는 그들이 사용자의 IP 주소를 기반으로 서버 선호도를 가지고 있다고 확신합니다. 따라서 그들은 여전히 ​​같은 서버를 공격 할 것입니다.
mmcdole

4
주석 스트림에서 이것을 자세히 읽고 관심을 가진 사람들을 위해 ... 우리는 리디렉션하기 전에 스로틀 캐시 키를 지우는 자체 리디렉션을 작성했습니다. 이 방법으로 모든 리디렉션이 코드를 통과하여 키를 제거하고 그 중 어느 것도 Throttle 속성을 트리거하지 않습니다.
SLoret

4
이것의 웹 API 버전을 찾고 있다면 여기를 확인하십시오 : stackoverflow.com/questions/20817300/…
Papa Burgundy

68

Microsoft에는 IIS 7.0 용 동적 IP 제한 확장-베타라는 IIS 7의 새로운 확장이 있습니다.

"IIS 7.0의 동적 IP 제한은 웹 서버 및 웹 사이트에 대한 서비스 거부 및 무차별 대입 공격으로부터 보호하는 모듈입니다. 이러한 보호는 비정상적으로 많은 수의 동시 요청을하는 HTTP 클라이언트의 IP 주소를 일시적으로 차단함으로써 제공됩니다. 또는 짧은 기간 동안 많은 수의 요청을하는 사람. " http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/

예:

이후에 차단 기준을 설정 X requests in Y milliseconds하거나 X concurrent connections in Y millisecondsIP 주소가 차단 Y milliseconds되면 요청이 다시 허용됩니다.


1
Googlebot과 같은 크롤러에 문제가 있는지 알고 있습니까?
Helephant


1
이제 버전 8부터 IIS와 함께 릴리스되고 번들로 제공됩니다 -iis.net/learn/get-started/whats-new-in-iis-8/…
Matthew Steeples

나는 이것을 사용하고 싶지만에 의해 조절할 수는 없습니다 <location>. 앱에 대한 모든 요청이거나 전혀 없습니다.
Kasey Speakman

웹 서버가로드 밸런서 뒤에있는 경우 모든 트래픽이 동일한 IP 주소에서 온 것으로 보이므로 유용하지 않은 것 같습니다. 내가 명백한 것을 놓치지 않으면 ...
Dscoduc

11

우리는이 URL http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx 에서 빌린 기술을 사용합니다. 스로틀 링이 아니라 가난한 사람의 서비스 거부 (DOS)에 사용됩니다. 이것은 또한 캐시 기반이며 수행중인 작업과 유사 할 수 있습니다. DOS 공격을 막기 위해 제한하고 있습니까? 라우터를 사용하여 DOS를 줄일 수 있습니다. 라우터가 필요한 조절을 처리 할 수 ​​있다고 생각하십니까?


1
그것은 우리가 이미하고있는 일과 거의 같습니다.하지만 잘 작동합니다 :)
Jarrod Dixon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.