개발 일기

S3 에 파일 업로드 본문

Java&Spring/Project

S3 에 파일 업로드

flow123 2021. 12. 6. 10:57

S3 업로드 테스트를 보는데, 처음에 설정을 못해서 build.gradle의 dependency 설정을 하는 데만 1시간을 다 썼다. 

내가 잘못 하고 있는건가? 의심이 많이 들었는데, 튜터님께 여쭤보니 원래 그런것이라고 하셨다. 

내가 쓰고 있는 라이브러리와 어디가 호환이 되는지 모르기 때문에, 해보고, 빼보면서 쓰는 것이 당연하다. 

블로그에 돌아다니는 정보들도, 지금 내가 깔아놓은 설정들과 충돌할 수 있기 때문에 그대로 가져와도 안되는 경우도 많다. 블로그 + aws 의 튜토리얼 등을 적당히 조합해서 할 것!

 

에러케이스 

(1) aws access key id 가 인식이 안된다고 뜸. yml 파일이 제대로 안불려진 듯함. 

(2) aws access를 얻고 난 이후에는, db에 이미지 url은 찍히지만, s3에 업로드가 안됨 (따라서 이미지가 업로드 되어야 하는 페이지에도 엑박이 뜸)

 

#나는 테스트를 칠 때, aws.yml 에 credential을 넣었다. gitignore에 파일을 넣었음에도 누출이 되었다. 이렇게 파일에 중요 정보를 저장하게 되면 위험하다. 이럴 때는, 환경변수에 중요 Credentials를 저장해주는 것이 가장 간단하다. 

실무에서는 배포할 때는 각 개발자들이 자신의 AWS IAM Key를 환경변수에 넣고 사용한다. AWS 관리자는 이 IAM KEY들에게 S3 ACCESS 를 주는 방식으로 쓴다. 우리 프로젝트 같이 소규모 플젝에서는 아직 AWS ADMIN 관리를 안하고 있어서, 그냥 각자의 프로젝트에서 환경변수를 동일하게 설정해두면 된다. 

 

intelliJ 프로젝트에 edit configurations 를 누르면 아래와 같이 변수가 뜬다. 

 

AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY.
Application properties의 설정. 

#1)CLI 되어있는지 찾음 2) 환경변수가 있는지 인텔리제이의 라이브러리 읽고 체크 (가장 간단한 방법) 
#3) 없으면, AWS.YML찾음.
cloud.aws.credentials.use-default-aws-credentials-chain=true

#

퍼블릭 업로드 시, 

 

(1) 버킷의 모든 퍼블릿 액세스 차단 비활성

(2) 이후에도 객체 업로드가 안되었는데. 

 

객체 소유권  = 객체 라이터를 허용해줘야 한다. 

이유는, s3 생성은 아마존 콘솔에서 한 것이기 때문에, 로컬에서 서버를 돌릴 때는 (객체 라이터) 

객체 라이터가 객체 소유권을 갖고 있지 않다 (s3 에서는 사실 상 내 로컬서버를 다른 존재로 인식한다고 봐야한다).

이 편집 부분을 활성화 해야지 가능하다. 

 

이렇게 설정을 바꿔주니, 이미지가 h2 db에 잘 저장이 되었다. 글에도 이미지 반영이 되었고, url 을 직접 접속해도 이미지가 잘 보인다. 하지만 s3에 파일이 쌓이지 않는다. 퍼블릭 액세스가 되지 않아서 그렇다(url에는 액세스가 되어서 잘 받아오지만, s3 버킷 객체에는 접근이 막혀서 그랬었던 것 같다. 여기 객체에 나열(List) 권한을 주자. write 와 list 의 차이는 나중에 확인해보자. 

 

 

 

왜 s3 를 써야할까? 저장소로 s3 가 왜 인기가 많은 걸까?

우선 s3는 무제한 용량이며, aws 서비스 중에서도 합리적인 가격대를 자랑한다. AWS 에서 관리해주기 때문에 스토리지 성능을 관리할 필요가 없어서 생산성에도 좋다.

 

그냥 DB에 업로드하면 안되나? 

DB에 대량 파일을 업로드 하게 되면 DB 에 부하가 걸린다. 

DB 에 저장을 하게 되면, 그게 실물 파일로 존재하는 것이 아니다. 그러면 나중에 DB 를 없애거나, 옮길 때 그걸 또 DB에서 파일로 변환하는 처리를 해야한다. 이것 자체도 번거로울 뿐만 아니라 다시 파일을 읽어드리는 것 자체가 서버에 부하를 준다. 

 

S3를 사용하기 전에는 NAS 스토리지를 썼었다. 서버는 API 호출 마다 처리하기 때문에, NAS 스토리지는 서버에 각각 연결이 되어 있어야 한다. S3가 가격도 합리적이고 운영도 편리하기 때문에, S3의 등장이후로는 NAS 를 잘 쓰지 않는다. (적어도 클라우드 환경에서는 그렇다)

 

스토리지를 사용하는 방법은 대략 3가지다. 

 

(1) S3 쓰기

(2) NAS 스토리지 

(3) Application 서버에 저장하기

3의 경우는 기능 구현에 제약이 많다. 

사용자가 API 1번과 (글 저장) 2번을(이미지 저장) 요청한다고 했을 때, 서버 A가 1번을 맡고 B가 2번을 맡았다고 가정해보자. 만약 스토리지가 1번 서버와 연결이 되어 있다고 한다면, 이미지 업로드가 되지 않거나, 엑박이 뜰 것이다. 둘다 연결이 되어 있어야 제대로 작동한다. 즉, N개의 서버를 운영하면 일일이 연결을 해줘야 한다는 번거로운 이야기다. 하지만 S3 를 연결하면 이렇게 일일이 연결할 필요가 없기 때문에 훨씬 편리하다. 

 

Comments