Skip to content

Commit

Permalink
✨ feat: s3 환경변수 수정 및 최신 라이브러리로 교체 (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
yanggwangseong committed Jan 16, 2025
1 parent 64dfbfd commit 365aef4
Show file tree
Hide file tree
Showing 8 changed files with 3,673 additions and 2,159 deletions.
2 changes: 1 addition & 1 deletion k6/scripts/signup-performance.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,5 @@ export default function () {
requestFailRate.add(1);
}

sleep(1);
sleep(0.01);
}
18 changes: 13 additions & 5 deletions k6/scripts/upload-image-performance.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,18 @@ const imageFiles = [
];

export const options = {
stages: [
{ duration: "30s", target: 300 }, // 최대 부하 유지
{ duration: "30s", target: 0 }, // 빠르게 부하 감소
],
scenarios: {
ramping_requests: {
executor: "ramping-arrival-rate",
timeUnit: "1s",
stages: [
{ duration: "2m", target: 100 },
{ duration: "1m", target: 0 },
],
preAllocatedVUs: 50, // 초기 VU
maxVUs: 100, // 필요에 따라 동적으로 추가
},
},
tags: {
testName: "prod-spike-upload-image-15",
testType: "spike",
Expand Down Expand Up @@ -67,5 +75,5 @@ export default function () {
requestFailRate.add(1);
}

sleep(1);
sleep(0.01);
}
5,728 changes: 3,616 additions & 2,112 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
"clinic:bubbleprof-signup": "cross-env NODE_ENV=development clinic bubbleprof --on-port 'docker-compose -f docker-compose-dev.yml run --rm k6 run /scripts/signup-performance.js' -- node dist/main.js"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.726.1",
"@aws-sdk/s3-request-presigner": "^3.726.1",
"@nestjs-modules/mailer": "^2.0.2",
"@nestjs/common": "^10.4.8",
"@nestjs/config": "^3.3.0",
Expand All @@ -53,16 +55,14 @@
"@nestjs/serve-static": "^4.0.2",
"@nestjs/swagger": "^8.0.7",
"@nestjs/typeorm": "^10.0.2",
"aws-sdk": "^2.348.0",
"bcrypt": "^5.1.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"cross-env": "^7.0.3",
"dotenv": "^16.4.7",
"express": "^4.21.1",
"jsonwebtoken": "^9.0.2",
"multer": "^1.4.5-lts.1",
"multer-s3": "^2.10.0",
"multer-s3": "^3.0.1",
"mysql2": "^3.11.4",
"nodemailer": "^6.9.16",
"reflect-metadata": "^0.2.2",
Expand All @@ -80,7 +80,7 @@
"@types/jest": "^29.5.14",
"@types/jsonwebtoken": "^9.0.7",
"@types/multer": "^1.4.12",
"@types/multer-s3": "^2.7.12",
"@types/multer-s3": "^3.0.3",
"@types/node": "^22.9.0",
"@types/nodemailer": "^6.4.17",
"@types/supertest": "^6.0.2",
Expand Down
57 changes: 30 additions & 27 deletions src/common/builders/multer.builder.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import { S3Client } from "@aws-sdk/client-s3";
import { BadRequestException, Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { MulterModuleOptions } from "@nestjs/platform-express";
import { MulterOptions } from "@nestjs/platform-express/multer/interfaces/multer-options.interface";
import AWS from "aws-sdk";
import multerS3 from "multer-s3";
import { extname } from "path";

import {
ENV_N_ACCESS_KEY,
ENV_N_BUCKET_NAME,
ENV_N_ENDPOINT,
ENV_N_REGION,
ENV_N_SECRET_KEY,
ENV_AWS_ACCESS_KEY_ID,
ENV_AWS_REGION,
ENV_AWS_S3_BUCKET_NAME,
ENV_AWS_SECRET_ACCESS_KEY,
} from "../constants/env-keys.const";
import { MAX_FILE_SIZE } from "../constants/number.const";

@Injectable()
export class MulterBuilder {
private readonly s3: AWS.S3;
private readonly s3: S3Client;
private readonly bucketName: string;

private options: Partial<MulterModuleOptions>;
Expand All @@ -32,22 +31,21 @@ export class MulterBuilder {
fileFilter: this.defaultFileFilter,
};

this.s3 = new AWS.S3({
endpoint:
this.configService.get<string>(ENV_N_ENDPOINT) || "Endpoint",
region: this.configService.get<string>(ENV_N_REGION) || "Region",
this.s3 = new S3Client({
region: this.configService.get<string>(ENV_AWS_REGION) || "Region",
credentials: {
accessKeyId:
this.configService.get<string>(ENV_N_ACCESS_KEY) ||
this.configService.get<string>(ENV_AWS_ACCESS_KEY_ID) ||
"AccessKey",
secretAccessKey:
this.configService.get<string>(ENV_N_SECRET_KEY) ||
this.configService.get<string>(ENV_AWS_SECRET_ACCESS_KEY) ||
"SecretKey",
},
});

this.bucketName =
this.configService.get<string>(ENV_N_BUCKET_NAME) || "BucketName";
this.configService.get<string>(ENV_AWS_S3_BUCKET_NAME) ||
"BucketName";
}

private defaultFileFilter: MulterOptions["fileFilter"] = (
Expand Down Expand Up @@ -107,19 +105,24 @@ export class MulterBuilder {
acl: "public-read",
contentType: multerS3.AUTO_CONTENT_TYPE,
key: (_req, file, cb) => {
const splitedFileNames = file.originalname.split(".");
const extension = splitedFileNames.at(
splitedFileNames.length - 1,
);

const env =
this.configService.get<string>("NODE_ENV") || "default";

const filename = this.path
? `${env}${this.path}/${new Date().getTime()}.${extension}`
: `${env}${new Date().getTime()}.${extension}`;

cb(null, encodeURI(`${this.resource}/${filename}`));
try {
const splitedFileNames = file.originalname.split(".");
const extension = splitedFileNames.at(
splitedFileNames.length - 1,
);

const env =
this.configService.get<string>("NODE_ENV") ||
"default";

const filename = this.path
? `${env}${this.path}/${new Date().getTime()}.${extension}`
: `${env}${new Date().getTime()}.${extension}`;

cb(null, encodeURI(`${this.resource}/${filename}`));
} catch (error) {
cb(error);
}
},
}),
};
Expand Down
13 changes: 6 additions & 7 deletions src/common/constants/env-keys.const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ export const ENV_MAIL_PORT = "MAIL_PORT" as const;
export const ENV_MAIL_USER = "MAIL_USER" as const;
export const ENV_MAIL_PWD = "MAIL_PWD" as const;

// ncloud
export const ENV_N_ACCESS_KEY = "N_ACCESS_KEY" as const;
export const ENV_N_SECRET_KEY = "N_SECRET_KEY" as const;
export const ENV_N_ENDPOINT = "N_ENDPOINT" as const;
export const ENV_N_REGION = "N_REGION" as const;
export const ENV_N_BUCKET_NAME = "N_BUCKET_NAME" as const;
export const ENV_N_BUCKET_URL = "N_BUCKET_URL" as const;
// aws
export const ENV_AWS_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID" as const;
export const ENV_AWS_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY" as const;
export const ENV_AWS_REGION = "AWS_REGION" as const;
export const ENV_AWS_S3_BUCKET_NAME = "AWS_S3_BUCKET_NAME" as const;
export const ENV_AWS_S3_BUCKET_URL = "AWS_S3_BUCKET_URL" as const;
2 changes: 1 addition & 1 deletion src/common/typeorm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const TypeOrmModuleOptions = {
...(configService.get("NODE_ENV") === "development"
? {
retryAttempts: 10,
logging: ["query", "error", "warn"] as LogLevel[],
logging: ["error", "warn"] as LogLevel[],
}
: { logging: ["error", "warn"] as LogLevel[] }),
};
Expand Down
4 changes: 2 additions & 2 deletions src/services/articles.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ConfigService } from "@nestjs/config";

import {
ENV_API_BASE_URL,
ENV_N_BUCKET_URL,
ENV_AWS_S3_BUCKET_URL,
} from "@APP/common/constants/env-keys.const";
import { BusinessErrorException } from "@APP/common/exception/business-error.exception";
import { ArticleErrorCode } from "@APP/common/exception/error-code";
Expand All @@ -28,7 +28,7 @@ export class ArticlesService {
private readonly configService: ConfigService,
) {
this.bucketUrl =
this.configService.get(ENV_N_BUCKET_URL) || "BUKET_URL";
this.configService.get(ENV_AWS_S3_BUCKET_URL) || "BUKET_URL";
this.env = this.configService.get<string>("NODE_ENV") || "default";
}

Expand Down

0 comments on commit 365aef4

Please sign in to comment.