2012-04-16 5 views
12

Spring 3 + Spring MVC를 사용하여 간단한 REST API를 개발 중입니다. 인증은 Spring Security를 ​​사용하여 클라이언트 토큰으로 OAuth 2.0 또는 기본 인증을 통해 수행됩니다. 이것은 아직 논란의 여지가 있습니다. 모든 연결은 SSL 연결을 통해 강제됩니다.Spring에서 클라이언트 토큰을 기반으로 속도 제한을 구현하는 방법은 무엇입니까?

나는 속도 제한을 구현하는 방법에 대한 정보를 찾고 있었지만 거기에는 많은 정보가있는 것 같지 않습니다. 구현은 여러 웹 서버에서 작동한다는 점에서 분산되어야합니다.

예를 들어 세 개의 API 서버 A, B, C가 있고 클라이언트가 초당 5 개의 요청으로 제한되는 경우 6 개의 요청을하는 클라이언트는 오류로 거부 된 C의 요청을 찾습니다. 하나의 클라이언트가 많은 사용자를 대신하여 요청을 할 수 있으므로

A recieves 3 requests \ 
B receives 2 requests | Executed in order, all requests from one client. 
C receives 1 request /

그것은 필요는 요청에 포함 된 토큰을 기반으로 작업하고, 각 사용자는 속도는 서버의 IP 주소 대신 제한해야합니다.

설정은 HAProxy로드 밸런서 뒤에 여러 (2-5) 웹 서버가됩니다. 카산드라가 뒷받침되고 memcached가 사용됩니다. 웹 서버는 Jetty에서 실행됩니다.

가능한 해결책 중 하나는 토큰을 추출하고 마지막 X 초 동안 요청을 얼마나 많이했는지 확인하는 사용자 정의 스프링 보안 필터를 작성하는 것일 수 있습니다. 이렇게하면 여러 고객에 대해 서로 다른 요율 한도를 적용 할 수 있습니다.

어떻게 할 수 있습니까? 기존 솔루션이 있습니까? 아니면 자체 솔루션을 작성해야합니까? 전에 많은 웹 사이트 인프라를 수행하지 않았습니다.

+0

필터 아이디어가 올바른 방향입니다. 이미 memcached를 사용하고 있으므로 간단해야합니다. – sourcedelica

+0

필터처럼 보이는 것이 길일 수 있습니다. 마지막 X 분/초 동안 API 사용을 확인할 수 있도록 간격을두고 버킷 시스템을 구현하는 데 유용한 문서를 찾았습니다. -> http://chris6f.com/rate-limiting-with-redis. 그것은 redis를 사용하지만 원리는 memcache 또는 cassandra와 유사해야합니다. –

답변

0

가능한 경우이 요구 사항을 충족시키기 위해 응용 프로그램 수준 코드를 수정하지 마십시오.

나는 HAProxy LB 문서를 통해이 문서를 보았지만 그 요구 사항은 ACL에 대한 완전한 조사를 보증 할 수 있습니다.

한쪽으로 HAProxy를 배치 할 수있는 가능한 아키텍처는 Apache WebServer를 앞에두고 Apache 플러그인을 사용하여 속도 제한을 수행하는 것입니다. 제한 초과 요청은 전면에서 거부되고 Apache 계층의 응용 프로그램 서버는 속도 제한 문제와 분리되어보다 간단 해집니다. 웹 서버에서 정적 컨텐츠를 제공하는 것도 고려해 볼 수 있습니다.

이 질문에 How can I implement rate limiting with Apache? (requests per second)

난이 도움이되기를 바랍니다에 대한 답변을 참조하십시오. Rob

+1

답해 주셔서 감사합니다. 프로젝트는 현재 Apache WebServer를 사용하지 않고 Jetty는 war 파일을 배포하는 데 사용됩니다. 현재의 앱을 구성하는 여러 가지 기존 전쟁이 있으며 API는 단순히 Jetty에서 실행되는 다른 웹 앱입니다. 아파치로 전환하는 것은 상당한 노력이 될 것이므로 가능하다면 그것을 피하려고 노력 중입니다. 또한 Apache mod는 토큰 제한이 아닌 IP에 초점을 맞추고있는 것으로 보입니다. 앱 코드에서 처리하는 것은 고통이지만 대부분의 제어를 제공하는 것 같습니다. 속도는 느릴 수 있지만 DDoS 공격을 중지하기위한 것이 아닙니다. –

0

흐름의 여러 지점에 속도 제한을 설정할 수 있습니다 (일반적으로 높을수록 좋습니다). 일반적인 접근 방식은 많은 의미가 있습니다. 구현을위한 한 가지 옵션은 속도 제한, 분석, 키 관리 등을 수행하고 코드 플러그인 (자바 플러그인은 여기에 있습니다 : https://github.com/3scale/3scale_ws_api_for_java)으로 작동하거나 또는 다음과 같은 것을 넣음으로써 3scale (http://www.3scale.net)을 사용하는 것입니다. Varnish (http://www.varnish-cache.org)를 파이프 라인에 설치하고 속도 제한을 적용합니다.

0

나는 이틀 전에 비슷한 해결책을 생각하고있었습니다.기본적으로 분산 환경에서 클라이언트 요청의 상태를 저장하는 "중앙 제어"솔루션을 선호합니다.

내 응용 프로그램에서는 "session_id"를 사용하여 요청 클라이언트를 식별합니다. 그런 다음 Servlet 필터 또는 Spring HandlerInterceptorAdapter를 만들어 요청을 필터링 한 다음 memcached, redis, cassandra 또는 zookeeper가 될 수있는 중앙 제어 데이터 저장소로 "session_id"를 확인합니다.