ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • server throttling을 알아보자
    network, security 2022. 5. 1. 23:01

     

    최근에 guava 라이브러리의 RateLimiter을 알게 되어서, 이 기회에 server throttling에 대해서 간단하게 적어보고자 한다.

     

    server throttling이란

    server throttling이란 너무 많은 요청을 서버의 리소스가 감당하지 못하는 상황을 방지하기 위하여, 서버가 처리할 요청량을 제한하는 것을 가리킨다. 비슷한 용어로는 bandwidth throttling, congestion control, traffic shaping, rate limiting 등이 있다. Java로 된 웹 개발 환경에서 쓸 수 있는 대표적인 라이브러리로는 RateLimiterBucket4j가 있다. 

     

    트래픽을 제어하는 방식에는 크게 두 가지의 방식이 있다.

     

    leaky bucket

    leaky bucket 방식은 output rate를 smooth하기 위한 방식이다. input rate가 들쑥날쑥이어도, output rate는 stable하다.

    leaky bucket

     

    leaky bucket 알고리즘은 다음과 같다.

    • 새로운 요청이 오면 queue에 담는다. 요청이 너무 많이 와서 queue가 넘칠 경우 새로운 요청은 버려진다.
    • 정해진 주기(clock)마다 처리할 패킷의 크기가 n으로 정해져있다(즉, fixed rate)
    • 한 주기 내에서 queue의 패킷을 차례로 처리하는데, 패킷의 크기를 합산했을 때 n 이하가 되는 지점까지만 처리한다. 예를 들어 n이 1000이고, queue가 {200, 400, 500, 800, 300}이라면, 이번 주기에서는 200, 400까지만 처리된다.
    • 한 주기가 끝나면 다시 n만큼 처리한다.

     

    위 그림과 연결짓는다면, 수도꼭지에서 나오는 물은 클라이언트가 마구 보내는 요청이 되고, 그것이 담기는 bucket이 queue이며, bucket에 뚫린 구멍의 크기(fixed rate)만큼만 요청이 흐르게 된다. 만약 물이 너무 많이 흘려보내면 bucket이 흘러넘쳐서 버려질 것이다.

     

    token bucket

    token bucket은 정해진 주기에 처리할 수 있는 요청량을 칼같이 제어하는 방식이 아니라, token의 양(요청을 처리할 수 있는 일종의 권한)을 정해진 주기 내에서 일정 수준으로 관리하는 방식이다. 이에 따라 처리하는 요청량이 어느 정도 튀어오르는 것을 용인하게 된다.

     

    token bucket

    token bucket 알고리즘은 다음과 같다.

    • 정해진 주기마다 token의 수가 n개로 정해져있다.
    • 정해진 주기마다 token x개가 bucket에 다시 채워진다. bucket이 흘러넘치면 새로운 token은 버려진다. 
    • 요청은 token을 얻어야만 처리되고, token을 파괴한다. 비싼 요청은 token이 많이 필요한데, 필요한 수만큼의 token을 얻을 때까지 idle 상태가 된다. 

     

    위 그림에서 보듯이, 이번에는 bucket에 패킷이 담기는 것이 아니라 token이 담기게 된다. 패킷은 이 token을 얻어야만 처리될 수 있다.

     

    RateLimiter의 사용법

    guava 라이브러리의 RateLimiter은 token bucket 방식으로서, 정해진 주기마다 발행할 permit의 크기를 설정하고, permit을 acquire한 요청만 처리한다. permit에 비해 요청이 많이 들어왔거나, 또는 앞선 요청이 비싼 요청이라서 permit을 많이 가져갔을 경우에는 permit을 acquire할 수 있을 때까지 기다리게 될 수도 있다.

     

    정확한 방식은 API 문서를 참고하면 좋을 것 같다. 일부를 발췌해보자면 다음과 같다.

     

    The returned RateLimiter ensures that on average no more than permitsPerSecond are issued during any given second, with sustained requests being smoothly spread over each second. When the incoming request rate exceeds permitsPerSecond the rate limiter will release one permit every (1.0 / permitsPerSecond) seconds. When the rate limiter is unused, bursts of up to permitsPerSecond permits will be allowed, with subsequent requests being smoothly limited at the stable rate of permitsPerSecond.

    • 1초당 발행할 permit의 수, 즉 permitsPerSecond를 n으로 설정한다. 1초에 n 이상으로 permit가 발행되는 일은 없다.
    • 요청이 많이 들어와서 n이 다 소진되면, 다른 요청은 sustain되고, 1/n초에 permit가 하나씩 발행된다.
    • 만약 n이 하나도 소진되지 않은 상태였다면, 최대 n만큼 요청량이 팍 튀는 것을 허용한다.

     

    바로 따라해볼 수 있는 튜토리얼은 여기를 참고하면 좋고, RateLimiter의 작동 방식에 대해서 좀 더 자세히 알고 싶다면 이 글API 문서를 참고해보면 좋을 것 같다. 참고로 RateLimiter은 아직 베타이기 때문에 미래에 deprecate되거나 backward compatibility가 깨질 수 있다.

     

    출처

    'network, security' 카테고리의 다른 글

    SameSite 설정에 대해서 알아보자  (0) 2022.01.24
    OAuth란?  (0) 2021.09.20

    댓글

Designed by Tistory.