블로그 릴레이 - CDK 로 SQS 구현해 보기

블로그 릴레이 - CDK 로 SQS 구현해 보기

안녕하세요 생산지원 그룹 리테일 어플리케이션부의 김승연입니다. 본 블로그는 당사의 한국어 블로그 릴레이의 2025년 다섯 번째 블로그입니다. 이번 블로그의 주제는 「CDK 로 SQS 구현해 보기」 입니다.
Clock Icon2025.02.22

안녕하세요 생산지원 그룹 리테일 어플리케이션부의 김승연입니다.

본 블로그는 당사의 한국어 블로그 릴레이의 2025년 다섯 번째 블로그입니다.
이번 블로그의 주제는 「CDK 로 SQS 구현해 보기」 입니다.

준비

빠르게 구축하기 위해 이전에 작성한 블로그 릴레이 - CDK 와 Serverless express 사용해 보기에서 이어서 SQS 리소스를 작성해 보겠습니다.

코드 작성

그럼 빠르게 CDK부분 부터 작성해 보겠습니다.
이전에 작성한 iac-stack.ts에 아래의 코드를 추가합니다.

lib/iac-stack.ts

...
    const queue = new cdk.aws_sqs.Queue(this, 'Queue', {
      queueName: `Queue`,
      visibilityTimeout: cdk.Duration.seconds(300),
    });

    const queueFunc = new cdk.aws_lambda_nodejs.NodejsFunction(
      this,
      'QueueFunc',
      {
        functionName: `QueueFunc`,
        architecture: cdk.aws_lambda.Architecture.ARM_64,
        runtime: cdk.aws_lambda.Runtime.NODEJS_20_X,
        entry: '../server/src/sqs/handler.ts',
      },
    );

    // Lambda 에 SQS 권한 부여
    queue.grantSendMessages(queueFunc);

    // SQS을 Lambda Event에 등록
    queueFunc.addEventSource(
      new cdk.aws_lambda_event_sources.SqsEventSource(queue),
    );

   // Lambda
...

다음으로 실행될 Lambda 함수를 작성해 줍니다.

server/src/sqs/handler.ts

import { SQSEvent, SQSRecord } from 'aws-lambda';

export const handler = async (event: SQSEvent) => {
  try {
    await Promise.allSettled(
      event.Records.map(async (record: SQSRecord) => {
        const body = JSON.parse(record.body);
        console.log('body:', body);
      }),
    );
  } catch (error: unknown) {
    throw error;
  }
};

이 과정까지 끝났다면 리소스 작성은 끝났습니다.
이후 디플로이후 리소스가 제대로 만들어졌는지 확인해 보세요.

여기까지만 해도 Dashboard 을 통해 어느 정도 동작 확인은 해볼 수 있습니다만,
추가로 기존의 Gateway + Lambda를 통해 SQS로 Message를 보내 queueFunc을 실행해 보도록 하겠습니다.

iac-stack.ts

...

    // Lambda
    const restApiFunc = new cdk.aws_lambda_nodejs.NodejsFunction(
      this,
      'RestApiFunc',
      {
        ...
        // 환경변수 설정
        environment: {
          SQS_ENDPOINT: queue.queueUrl,
          SQS_REGION: queue.env.region,
        },
      },
    );

    queue.grantSendMessages(restApiFunc); // Lambda 에 SQS 권한 부여

...

server/src/index.ts

...
import { SQS } from '@aws-sdk/client-sqs';

...

const sqs = new SQS({ region: process.env.SQS_REGION });

app.get('/', async (_req: Request, res: Response): Promise<void> => {
  try {
    await sqs.sendMessage({
      QueueUrl: process.env.SQS_ENDPOINT,
      MessageBody: JSON.stringify('my message'),
    });
    res.status(200).send('success send to message');
  } catch (error: unknown) {
    console.error(error);
    res.status(500).send('failed send to message');
  }
});

...

작성이 완료되었다면 실행 후 Cloud Watch에서 로그가 출력되어 있는지 확인해 보세요.
아래와 같은 로그 정보가 있다면 성공입니다.

... INFO my message

보충

여기까지 SQS을 구현해 보았습니다만, 추가로 Dead Letter Queue를 설정해 주면 좋습니다.

Dead Letter Queue를 설정해 주면 실패한 Message 처리에 대한 후속 처리를 추가로 구현할 수 있습니다.

이번에는 Queue와 별개로 Dead Letter Queue를 구현, 실패한 Message를 보관하는 것까지만 구현해 보겠습니다.

이후 후속 처리는 QueueFunc 와 같이 추가 Lambda를 연결하는 등 다양한 방법이 있습니다.

자세히는 Document를 참고해 주세요.

아래와 같이 코드를 작성 후 Dead Letter Queue 리소스가 추가로 생성되었는지 확인해 주시면 됩니다.

lib/iac-stack.ts

...
    const deadLetterQueue = new cdk.aws_sqs.Queue(this, 'DeadLetterQueue', {
      queueName: `DeadLetterQueue`,
      retentionPeriod: cdk.Duration.days(1),
    });

    const queue = new cdk.aws_sqs.Queue(this, 'Queue', {
      queueName: `Queue`,
      visibilityTimeout: cdk.Duration.seconds(300),
      deadLetterQueue: {
        maxReceiveCount: 1, // 1회 수신 후 실패했을 경우 DeadLetterQueue로 이동
        queue: deadLetterQueue,
      },
    });
...

마무리

이상, 한국어 블로그 릴레이의 2025년 다섯 번째 블로그 「CDK 로 SQS 구현해 보기」였습니다.
다음 여섯 번째 블로그 릴레이는 2월 넷째 주에 공개됩니다.

참고자료

블로그 릴레이 - CDK 와 Serverless express 사용해 보기

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.