문제의식
처음 s3를 접한 뒤, 블로그를 통해 단순 구현을 하다 보면 s3에 불규칙하게 파일들이 저장되어 가는 것을 본 적이 있을 것이다.
S3에 이미지를 업로드하는 예제를 제공하는 여러 코드들에서 대부분 amazonS3.putObjcet 메서드의 부분의 fileName를 랜덤 UUID로 작성하는 경우가 많다.
물론 여러 장의 사진이 아니고, 단순하게 s3에 이미지를 업로드하는 코드를 알려주는 것이기 때문에 큰 문제는 안 될 수 있다.
하지만 실제 코드를 작성하고, 유지보수를 하는 관점에서 살펴보았을 때 여러 가지 문제가 발생할 수 있다.
1. 하나의 서비스 로직을 작성해 두고 모두 동일하게 사용한다.
-> 장점이 될 수도 있으나, 단점이 될 수도 있다. 여러 API가 동일한 하나의 서비스 로직을 바라보고 있다면 다양한 상황에서 문제가 생길 수 있다. 또한, 문제가 생긴다 해도 추적이 힘들다.
2. s3에 접속하여 사진에 대한 관리를 할 수 없다.
-> 특정한 사진을 찾기 위해서 db에 검색한 뒤 접근하여야 할 것이다. 이 경우 db 접근을 하는 것 자체가 복잡하거나, 불필요한 작업을 거쳐야 할 수 있다.
3. 파일 이름을 통해 확인이 불가능하다.
-> 여러 개의 파일이 난잡하게 위치하고 있기 때문에, 원하는 파일을 찾는 것이 사실상 불가능하다.
결과적으로, 말이 안 된다!!
s3의 여러 기능이 있지만, 파일을 저장한다는 관점에서 바탕화면과 동일하다고 느꼈다.
우리는 수십만 장의 파일을 바탕화면에 그대로 보관하지는 않는다.
즉, 폴더 구조를 만들어보자!
S3에 대한 간단한 이해
AWS S3 버킷에는 객체가 저장된다. 이미지 파일을 업로드하는 경우에도 이미지 파일뿐만 아니라 파일에 대한 메타데이터도 함께 객체로서 저장되는 것이다. 저장된 객체는 객체 키(이름)로 고유하게 식별할 수 있다.
사용 가능한 문자
- UTF-8 문자
- 0~9
- a-z
- A-Z
- 느낌표(!)
- 하이픈(``)
- 밑줄(_)
- 마침표(.)
- 별표(``)
- 작은따옴표(')
- 여는 괄호(()
- 닫는 괄호())
인코딩이 필요한 문자
- 세미콜론(";")
- 슬래시('/')
- 콜론(":")
- 더하기("+")
피해야 하는 문자
- 억음 악센트 기호("`")
- 오른쪽 대괄호("]")
- 인용 부호
- '보다 큼' 기호(">")
- 왼쪽 대괄호("[")
등의 문자를 사용할 수 있다. 이 외에도 몇 가지가 더 있으니 본인이 쓰고자 하는 문자가 해당하는지 궁금하다면 공식 문서를 살펴보자.
S3 폴더 구조
그래서 이제 s3의 폴더 구조는 어떻게 만드는 것인지 궁금할 것이다. 하지만 s3의 경우 폴더구조가 없다.
이제까지 무슨 소리를 했나 싶겠지만, 실제로 s3에는 폴더 구조가 존재하지 않는다.
s3의 폴더 만들기 버튼을 누르면 나오는 화면이다.
폴더 만들기 있구먼!이라는 생각보다는 문장을 잘 이해해 보자.
폴더를 사용하여 버킷에서 객체를 그룹화합니다. 폴더를 생성하면 S3가 슬래시(/) 뒤에 지정한 이름을 사용하여 객체를 생성합니다. 그러면 이 객체가 콘솔에서 폴더로 표시됩니다.
즉, 폴더! 를 만들겠다는 것이 아니라 -> 폴더처럼 보이게 해주겠다는 소리인 것이다.
결과적으로, 폴더처럼 보이게 만드는 것이긴 하지만 실제 폴더와 유사하게 사용할 수 있다.
코드는 다음과 같이 작성해 주면 된다.
public String uploadImage(MultipartFile file, String fileName) {
try {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(file.getSize());
metadata.setContentType(file.getContentType());
amazonS3.putObject(bucketName, fileName, file.getInputStream(), metadata);
return amazonS3.getUrl(bucketName, fileName).toString();
} catch (IOException e) {
throw new S3Exception(S3ErrorCode.FILE_UPLOAD_ERROR);
}
}
이 전에는 매개변수로 MultupartFile만 받고 있었다. 하지만 fileName를 추가해 주자.
그럼 fileName로는 어떤 것이 넘어올까?
String uuid = UUID.randomUUID().toString().replace("-", ""); // 하이픈 제거
String shortUuid = uuid.substring(0, 8); // 앞 8자리만 사용
String fileName = "Market/" + marketId + "/marketImage/" + shortUuid;
imageUrlService.uploadImage(uploadImage, fileName);
실제 uploadImage를 호출하는 메서드에서는 다음과 같이 작성되어 있다.
API 경로에 따라 파일의 폴더 구조에 대한 이름을 작성해 준 뒤, 업로드하는 형식인 것이다.
최종적으로 다음과 같이 폴더 구조를 형성한 것을 볼 수 있다!
'지식 정리 > AWS' 카테고리의 다른 글
[AWS] EC2 + Docker 을 이용한 Spring Boot 배포(2) (0) | 2025.01.21 |
---|---|
[AWS] EC2 + Docker 을 이용한 Spring Boot 배포(1) (0) | 2025.01.21 |
[AWS] CI/CD 배포 전략 (0) | 2025.01.20 |
[AWS] AWS ELB (0) | 2025.01.15 |
[AWS] Amazon EFS (1) | 2025.01.03 |