Computer >> 컴퓨터 >  >> 프로그래밍 >> Redis

서버리스 환경을 위한 속도 제한 솔루션, @upstash/ratelimit 공개

시스템의 가용성을 유지하는 것은 모든 제품에서 가장 중요한 과제 중 하나입니다. 하지만 안타깝게도 일부 사용자는 과도한 요청으로 리소스를 악용할 수 있으며, 때로는 사용량을 제한하고 요금을 부과하고 싶은 경우도 있습니다. 속도 제한(Rate Limiting)은 이러한 문제들에 대한 표준적인 해결책으로, 별도의 복잡한 설정 없이 바로 동작해야 합니다. 이미 시스템 구축에 많은 노력을 들였다면, 서버리스 함수처럼 상태가 없는(stateless) 환경에서 잘 작동하는 속도 제한 시스템을 새로 설계하는 데 추가 시간을 쓰고 싶지 않을 것입니다.

@upstash/ratelimit 공개

GitHub, npm, Deno에서 이용할 수 있습니다.

오늘 우리는 Vercel, Cloudflare, Deno, Fastly, Netlify와 같은 서버리스 환경에서 속도 제한을 구현할 수 있는 솔루션인 @upstash/ratelimit를 출시합니다. 이 라이브러리는 Upstash Serverless Redis를 기반으로 구축되었으며, 하나 이상의 데이터베이스를 활용하여 전 세계 어디에 있는 사용자에게도 낮은 지연 시간(low latency) 경험을 제공합니다.

시작하기

@upstash/ratelimit는 현재까지 세 가지 표준화된 알고리즘을 구현하고 있으며, 각 알고리즘에 대한 자세한 내용은 프로젝트의 README에서 확인할 수 있습니다.

두 가지 핵심 메서드를 제공합니다:

  • limit(identifier: string): Promise<RatelimitResponse>

limit 메서드는 true 또는 false와 함께 남은 요청 수에 대한 메타데이터를 반환합니다. 설정한 한도를 초과하는 모든 요청을 즉시 거부하고 싶을 때 사용하기에 적합합니다.

  • blockUntilReady(identifier: string, timeout: number): Promise<RatelimitResponse>

요청을 즉시 거부하는 대신, 처리가 가능해질 때까지 대기하고 싶은 경우에 사용합니다. 다만 일부 플랫폼은 함수 실행 시간에 따라 과금하므로, 이 방식을 사용할 때는 비용 측면을 함께 고려해야 합니다.

단일 리전 데이터베이스

단일 데이터베이스로 속도 제한을 구현하는 것은 매우 간단합니다. Upstash에서 데이터베이스를 생성한 뒤 바로 사용하면 됩니다:

import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";

// 10초당 10개의 요청을 허용하는 새로운 속도 제한기 생성
const ratelimit = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(10, "10 s"),
});

// 상수 문자열을 사용해 모든 요청에 단일 속도 제한을 적용하거나,
// userID, apiKey, IP 주소를 사용해 개별 제한을 적용할 수 있습니다.
const identifier = "api";
const { success } = await ratelimit.limit(identifier);

if (!success) {
  return "Unable to process at this time";
}
doExpensiveCalculation();
return "Here you go!";

글로벌 복제 속도 제한

예를 들어 고객이 미국과 유럽에 분포해 있다고 가정해 보겠습니다. 이 경우 Upstash에 두 개의 리전별 Redis 데이터베이스를 생성하면, 사용자는 자신과 지리적으로 가장 가까운 데이터베이스의 빠른 응답 속도를 그대로 누릴 수 있습니다.

import { GlobalRatelimit } from "@upstash/ratelimit"; // Deno의 경우: 위 참조
import { Redis } from "@upstash/redis";

// 10초당 10개의 요청을 허용하는 새로운 글로벌 속도 제한기 생성
const ratelimit = new GlobalRatelimit({
  redis: [
    new Redis({
      /* 유럽 */
    }),
    new Redis({
      /* 북미 */
    }),
  ],
  limiter: Ratelimit.slidingWindow(10, "10 s"),
});

마무리

궁금한 점이 있다면 GitHub 또는 아래 채널을 통해 언제든 문의해 주세요.

DiscordTwitter에서 저희를 팔로우하고 최신 소식을 받아보세요.