Computer >> 컴퓨터 >  >> 프로그램 작성 >> Redis

서버리스 애플리케이션 속도 제한

서버리스의 가장 좋은 점 중 하나는 트래픽이 급증하는 경우에도 확장할 수 있다는 것입니다. 그러나 불행하게도 확장은 재정적으로나 기술적으로나 공짜가 아닙니다. 이것이 개발자가 애플리케이션의 확장성을 제어해야 하는 이유입니다. 서버리스 애플리케이션에 속도 제한 메커니즘이 필요한 주요 이유는 다음과 같습니다.

1- 리소스 보호: 공개 API를 제공하는 경우 트래픽 급증으로 인해 서비스 품질이 저하되고 모든 사용자의 서비스가 중단될 수 있습니다. 이러한 연쇄적인 장애와 자초한 Ddos 사고로부터 시스템을 보호해야 합니다. 응용 프로그램의 버그는 시스템에서 이러한 문제를 유발할 수 있습니다. 실패 시 끝점을 무기한 재시도하는 내부 프로세스는 리소스를 쉽게 고갈시킬 수 있습니다.

2- 사용자 할당량 관리: 서비스의 공정한 사용을 위해 사용자에 대한 할당량을 정의할 수 있습니다. 또한 다양한 가격 책정 계층으로 서비스를 제공하는 경우 할당량이 필요할 수 있습니다.

3- 비용 관리: 통제되지 않은 시스템이 어떻게 큰 청구서를 유발할 수 있는지 실제 사례가 많이 있습니다. 이는 확장성이 뛰어난 특성 덕분에 서버리스 애플리케이션의 경우 상당히 위험합니다. 비율 제한은 이러한 비용을 제어하는 ​​데 도움이 됩니다.

솔루션

다른 계층에는 여러 대체 속도 제한 솔루션이 있습니다. 간단한 장단점 분석과 함께 주요 3가지를 나열하겠습니다.

1- 기능의 동시성 수준:

클라우드 공급자는 서버리스 기능 실행을 확장하기 위해 여러 컨테이너를 만듭니다. 최대 동시 컨테이너/인스턴스 수에 대한 제한을 설정할 수 있습니다. 이것이 동시성을 제한하는 데 도움이 될 수 있지만 함수가 1초에 호출되는 횟수를 제어하지는 않습니다.

AWS Lambda 및 Google Cloud Functions의 동시성을 제한하는 방법은 다음과 같습니다.

장점:

  • 오버헤드 없음
  • 간단한 구성

단점:

  • 완벽한 솔루션은 아닙니다. 동시성만 제어합니다. 초당 실행 횟수에는 제한이 없습니다.

2- API 게이트웨이의 속도 제한

API Gateway를 통해 기능에 액세스하는 경우 API Gateway에 속도 제한 정책을 적용할 수 있습니다. AWS와 GCP 모두 솔루션 구성 방법에 대한 가이드를 제공합니다.

장점:

  • 오버헤드 없음
  • 간단한 구성

단점:

  • API 게이트웨이를 사용하는 경우에만 적용됩니다.
  • 사용자별 또는 IP별 할당량과 같은 보다 복잡한 경우는 지원하지 않습니다.

3- Redis의 속도 제한

이것은 가장 완벽하고 강력한 솔루션입니다. 사용 가능한 많은 Redis 기반 속도 제한 라이브러리가 있습니다. Jeremy Daly의 블로그 게시물에서 그는 Elasticache를 가능한 솔루션으로 거부하며* this adds a “non-serverless” component and another thing to manage *. 여기서 Upstash는 서버리스 모델과 요청당 가격 책정으로 매우 좋은 대안이 됩니다.

장점:

  • 강력하며 사용자 모델에 맞는 맞춤형 로직을 구현할 수 있습니다.
  • 확장 가능한 솔루션. Github에서 속도 제한을 위해 Redis를 사용하는 방법 보기
  • 풍부한 생태계, 많은 오픈 소스 라이브러리:redis_rate, redis-cell, node-ratelimiter

단점:

  • Redis 사용 오버헤드.

코드:Redis의 속도 제한

속도 제한 라이브러리 덕분에 응용 프로그램 코드에 속도 제한을 적용하기가 매우 쉽습니다. 다음 예제 코드는 초당 IP당 AWS Lambda 함수의 실행을 제한합니다.

const RateLimiter = require("async-ratelimiter");
const Redis = require("ioredis");
const { getClientIp } = require("request-ip");

const rateLimiter = new RateLimiter({
  db: new Redis("YOUR_REDIS_URL"),
  max: 1,
  duration: 5_000,
});

module.exports.hello = async (event) => {
  const clientIp = getClientIp(event) || "NA";
  const limit = await rateLimiter.get({ id: clientIp });
  if (!limit.remaining) {
    return {
      statusCode: 429,
      body: JSON.stringify({
        message: "Sorry, you are rate limited. Wait for 5 seconds",
      }),
    };
  }

  return {
    statusCode: 200,
    body: JSON.stringify({
      message: "hello!",
    }),
  };
};

전체 예제를 보려면 자습서를 방문하십시오.

읽기 목록

https://cloud.google.com/architecture/rate-limiting-strategies-techniques

https://www.jeremydaly.com/throttling-third-party-api-calls-with-aws-lambda/

https://medium.com/google-cloud/rate-limit-your-api-usage-with-cloud-endpoints-quotas-1270da55d2bf

https://github.blog/2021-04-05-how-we-scaled-github-api-sharded-replicated-rate-limiter-redis/

https://redis.io/commands/incr#pattern-rate-limiter

https://stripe.com/blog/rate-limiters