AWS 검색 결과

3개 발견
  1. 미리보기
    2022.01.09 - mr.november11

    NestJS에서 AWS S3로 파일 업로드하기

  2. 미리보기
    2020.03.19 - mr.november11

    [AWS] Aurora RDS에서 ' Too many connections' 에러 발생 시 원인과 해결방법

  3. 미리보기
    2020.03.03 - mr.november11

    [AWS] RDS 데이터 백업 및 복구 방법

NestJS에서 AWS S3로 파일 업로드하기

2022. 1. 9. 08:55 - mr.november11

1. nest cli로 컨트롤러,서비스 생성하기

  • 파일 업로드 서비스의 이름은 upload 로 생성한다.
nest g mo uploads
nest g co uploads
nest g s uploads

2. 업로드 컨트롤러 구현

Nest는 파일 업로드 처리를 위해 Express의 multer 미들웨어를 제공한다.

multer는 POST 메소드로 multipart/form-data 컨텐츠 타입을 지원한다.

업로드 컨트롤러를 구현하기 앞서 Multer 라이브러리를 설치한다.

$ yarn add --dev @types/multer

이번 예제는 단일 파일 업로드를 처리한다.

@Controller('uploads')
export class UploadsController {
  @Post()
  @UseInterceptors(FileInterceptor('file'))
  uploadFile(@UploadedFile() file: Express.Multer.File) {
    console.log(file);
  }
}

업로드 컨트롤러에서 단일 파일 입력을 받도록 설정한 후 포스트맨으로 API를 테스트한다.

포스트맨으로 테스트 한 결과 console.log(file) 에 다음과 같은 정보가 출력된다.

{
  fieldname: 'file',
  originalname: 'test.png',
  encoding: '7bit',
  mimetype: 'image/png',
  buffer: <Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 01 46 00 00 01 3e 08 06 00 00 00 f1 a6 b9 5c 00 00 0c 6d 69 43 43 50 49 43 43 20 50 72 6f 66 69 ... 36041 more bytes>,
  size: 36091
}

이제 컨트롤러의 file을 서비스로 전달하여 S3로 업로드하는 작업을 구현한다.

2. 업로드 서비스 구현

먼저 업로드 컨트롤러에서 업로드 서비스의 uploadFile 함수를 호출하도록 코드를 수정한다.

@Controller('uploads')
export class UploadsController {
  constructor(private readonly uploadService: UploadsService) {}
  @Post()
  @UseInterceptors(FileInterceptor('file'))
  uploadFile(@UploadedFile() file: Express.Multer.File) {
    return this.uploadService.uploadFile(file);
  }
}

업로드 서비스에서는 AWS S3로 파일을 업로드하기 위해 aws-sdk 라이브러리를 사용한다.

$ yarn add --dev aws-sdk

업로드 서비스에서 aws-sdk를 사용하기 위해 클래스에 S3 멤버 변수를 추가한다.
(실행 환경에 S3 업로드 권한을 가진 Access Key가 설정되어 있어야 한다.)

import { Injectable } from '@nestjs/common';
import * as AWS from 'aws-sdk';
@Injectable()
export class UploadsService {
  s3 = new AWS.S3();
}

실제 파일 업로드를 수행하는 uploadFile 함수를 구현한다.

async uploadFile(file: Express.Multer.File) {
    const AWS_S3_BUCKET = 'nestjs-upload-test-bucket';
    const params = {
      Bucket: AWS_S3_BUCKET,
      Key: String(file.originalname),
      Body: file.buffer,
    };
    try {
      const response = await this.s3.upload(params).promise();
      return response;
    } catch (e) {
      throw new Error('Failed to upload file.');
    }
  }

업로드가 성공했다면 AWS.S3.ManagedUpload.SendData 타입의 결괏값이 반환된다.

export interface SendData {
        /**
         * URL of the uploaded object.
         */
        Location: string;
        /**
         * ETag of the uploaded object.
         */
        ETag: string;
        /**
         * Bucket to which the object was uploaded.
         */
        Bucket: string;
        /**
         * Key to which the object was uploaded.
         */
        Key: string;
    }

응답 객체의 Location은 업로드 된 객체의 URL을 포함한다.

{
    "ETag": "\"fff730c0a3f344034854117aaf88d9ac\"",
    "Location": "https://nestjs-upload-test-bucket.s3.ap-northeast-2.amazonaws.com/test.png",
    "key": "test.png",
    "Key": "test.png",
    "Bucket": "nestjs-upload-test-bucket"
}

업로드 시 별도의 ACL을 설정하지 않았기 때문에 해당 URL로 접속할 경우 AccessDenied 가 발생한다.

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>BJNMX4V6S5NHCN9Q</RequestId>
<HostId>
gW79WxeQfreLOY+bmPKSxrRBaOUJ/girPZsMev1icrU5foITkTwdF8njH6VnkKJVZRjibxm0P/I=
</HostId>
</Error>

외부에서 접속 가능한 ACL로 파일을 업로드하려면 params 변수에 public-read로 ACL을 설정해야 한다.
이 경우 해당 S3 버킷의 ACL도 퍼블릭 액세스가 허용된 상태여야 한다.

S3 버킷의 퍼블릭 액세스를 허용하는 방법은 다음 문서를 참고한다.

const params = {
      Bucket: AWS_S3_BUCKET,
      Key: String(file.originalname),
      Body: file.buffer,
      ACL: 'public-read',
    };

 

다른 카테고리의 글 목록

AWS 카테고리의 포스트를 톺아봅니다

문제 현상

DBeaver로 RDS 접속 시 아래와 같은 에러 메시지가 발생하며 SQL 쿼리 실행이 불가능한 상황이 발생했다. 

 Too many connections

 

분석

CPU 나 메모리 상으로는 큰 부하가 없는 상태이며 DB 연결은 45개에 근접한 상태이다. 

확인 결과 현재 사용중인 Amazon Aurora DB의 max connection 제한에 근접하여 발생한 문제였다. 
(db.t2.small 타입의 인스턴스 기준으로 최대 45개)

Instance Class

max_connections Default Value

db.t2.small

45

db.t2.medium

90

db.r3.large

1000

db.r3.xlarge

2000

db.r3.2xlarge

3000

db.r3.4xlarge

4000

db.r3.8xlarge

5000

RDS 설정 확인 시 max_connections 파라미터의 값은 아래와 같은 계산식을 통해 도출된다. 

GREATEST({log(DBInstanceClassMemory/805306368)*45},{log(DBInstanceClassMemory/8187281408)*1000})

해결방법

문제 해결을 위해 DB 클러스터 파라미터 그룹과 일반 파라미터 그룹의 max_connections의 값을 현재 값인 45에서 90으로 상향했다.

상향 후에는 connection 문제 없이 SQL 쿼리에 성공한다. 

 

AWS Console 상에서 수정한 max_connection 값은 아래 쿼리로 확인할 수 있다. 

show variables like 'max_connections'; 

관련 문서 : https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Managing.Performance.htm

'AWS' 카테고리의 다른 글

NestJS에서 AWS S3로 파일 업로드하기  (0) 2022.01.09
[AWS] RDS 데이터 백업 및 복구 방법  (0) 2020.03.03

다른 카테고리의 글 목록

AWS 카테고리의 포스트를 톺아봅니다

[AWS] RDS 데이터 백업 및 복구 방법

2020. 3. 3. 16:19 - mr.november11

진행하다보면 

 

ERROR 1227 (42000) at line 18: Access denied; you need (at least one of) the SUPER privilege(s) for this operation

ERROR 1215 (HY000) at line 239: Cannot add foreign key constraint.

 

등 자잘한 에러가 많이 발생하는데요.

 

관련 에러들이 발생하지 않는 검증된 명령어로 정리했습니다. 

 

- 백업 명령어 

mysqldump \                                                                                                                                             
--host= <백업할 Host> \
--column-statistics=0 \
--user=<유저 아이디> --password=<패스워드> \
--default-character-set=utf8mb4 --set-charset \
--compact --extended-insert --quick --hex-blob \
--single-transaction \
--events --routines --triggers \
--databases <데이터베이스> --set-gtid-purged=OFF > <덤프 파일명>

- 복구 명령어

mysql -u <유저 아이디> -h <복구할 Host> -p -D <데이터베이스> < <덤프 파일명>

 

RDS 복구 시 아래와 같이 SUPER 권한 문제가 발생할 수 있습니다. 

 

ERROR 1227 (42000) at line 2: Access denied; you need (at least one of) the SUPER privilege(s) for this operation

 

이 경우 RDS 의 파라미터 설정에서 log_bin_trust_function_creators 값을 1로 설정한 후 변경 사항을 저장해야 합니다.

 

다른 카테고리의 글 목록

AWS 카테고리의 포스트를 톺아봅니다