본문 바로가기
Dart/Dart Server

[추가학습] Dart 서버/ API Throttling 기법 / Dart에서 API Throttling 구현하기: 다양한 전략 (토큰 버킷, 누적 버스트 등)

by Maccrey Coding 2024. 9. 22.
728x90
반응형

 

Dart 서버에서 API Throttling 기법: 다양한 전략

오늘은 Dart 서버에서 API Throttling을 구현할 때 사용할 수 있는 다양한 전략에 대해 쉽게 설명해드릴게요.

초보자도 이해할 수 있도록 토큰 버킷, 누적 버스트 등의 기법을 소개할게요.

Throttling의 필요성

Throttling은 서버가 과도한 요청을 받지 않도록 도와줍니다. 이를 통해 서버의 안정성과 성능을 유지할 수 있어요. 이제 여러 가지 전략을 알아볼까요?

1. 토큰 버킷(Token Bucket) 전략

토큰 버킷은 요청을 허용하는 방식으로, 요청이 들어올 때마다 토큰을 사용해요. 각 요청에는 토큰이 필요하고, 토큰은 주기적으로 생성됩니다.

토큰 버킷 구현하기

import 'dart:async';

class TokenBucket {
  final int maxTokens; // 최대 토큰 수
  int _currentTokens; // 현재 토큰 수
  final Duration _refillTime; // 토큰 재충전 주기
  Timer? _timer;

  TokenBucket(this.maxTokens, this._refillTime)
      : _currentTokens = maxTokens {
    _startRefill();
  }

  void _startRefill() {
    _timer = Timer.periodic(_refillTime, (_) {
      if (_currentTokens < maxTokens) {
        _currentTokens++;
      }
    });
  }

  Future<bool> request() async {
    if (_currentTokens > 0) {
      _currentTokens--; // 토큰 사용
      return true; // 요청 성공
    } else {
      return false; // 요청 실패
    }
  }
}

// 사용 예
void main() async {
  final bucket = TokenBucket(5, Duration(seconds: 1)); // 최대 5개의 토큰, 1초마다 1개 재충전

  for (int i = 0; i < 10; i++) {
    if (await bucket.request()) {
      print('Request $i executed');
    } else {
      print('Request $i failed: No tokens available');
    }
    await Future.delayed(Duration(milliseconds: 200)); // 0.2초 대기
  }
}

코드 설명

  1. TokenBucket 클래스: 이 클래스는 최대 토큰 수와 재충전 주기를 설정해요.
  2. _startRefill 메서드: 주기적으로 토큰을 재충전해요.
  3. request 메서드: 요청이 들어오면 토큰을 사용하고 성공 여부를 반환해요.
  4. 사용 예: 10개의 요청을 시도하고, 0.2초마다 대기해요. 토큰이 없으면 요청이 실패해요.

2. 누적 버스트(Accumulated Burst) 전략

누적 버스트는 짧은 시간에 여러 요청을 허용하는 방법이에요. 기본적으로는 천천히 요청하지만, 누적된 요청을 일정 시간에 한 번에 처리할 수 있어요.

누적 버스트 구현하기

class AccumulatedBurst {
  final int maxRequests; // 최대 요청 수
  int _currentRequests = 0;
  Duration _burstDuration; // 누적 시간
  Timer? _timer;

  AccumulatedBurst(this.maxRequests, this._burstDuration);

  Future<bool> request() async {
    if (_currentRequests < maxRequests) {
      _currentRequests++; // 요청 수 증가
      _startTimer(); // 타이머 시작
      return true; // 요청 성공
    } else {
      return false; // 요청 실패
    }
  }

  void _startTimer() {
    if (_timer == null) {
      _timer = Timer(_burstDuration, () {
        _currentRequests = 0; // 시간 지나면 요청 수 초기화
        _timer = null;
      });
    }
  }
}

// 사용 예
void main() async {
  final burst = AccumulatedBurst(3, Duration(seconds: 2)); // 최대 3개의 요청, 2초마다 초기화

  for (int i = 0; i < 10; i++) {
    if (await burst.request()) {
      print('Request $i executed');
    } else {
      print('Request $i failed: Too many requests');
    }
    await Future.delayed(Duration(milliseconds: 300)); // 0.3초 대기
  }
}

코드 설명

  1. AccumulatedBurst 클래스: 최대 요청 수와 누적 시간 설정해요.
  2. request 메서드: 요청 수를 증가시키고, 최대 수를 초과하면 실패해요.
  3. _startTimer 메서드: 정해진 시간이 지나면 요청 수를 초기화해요.
  4. 사용 예: 10개의 요청을 시도하고, 0.3초마다 대기해요. 최대 3개의 요청만 허용돼요.

Dart에서 API Throttling을 구현하는 다양한 전략을 살펴보았습니다.

토큰 버킷과 누적 버스트는 각각의 상황에 맞게 활용할 수 있어요. 이제 이 기법들을 실습해보세요!

 

구독!! 공감과 댓글은 저에게 큰 힘이 됩니다.

Starting Google Play App Distribution! "Tester Share" for Recruiting 20 Testers for a Closed Test.

 

Tester Share [테스터쉐어] - Google Play 앱

Tester Share로 Google Play 앱 등록을 단순화하세요.

play.google.com

728x90
반응형