코딩성장스토리

aws CloudFront + S3 본문

기타

aws CloudFront + S3

까르르꿍꿍 2023. 2. 14. 17:39

이번에 프로젝트를 하면서 Security, Swagger 서버에 배포하기 , S3 등등 다양한 걸 많이 접하게 된다.

 

그러다가 S3를 이용할 때 CloudFront 라는 CDN 서비스를 같이 사용하면 비용 + 성능 면에서 좋아지는 것을 지인을 통해 알게 되었다.

 

CloudFront란

- AWS에서 제공하는 CDN(Content delivery network) 서비스

 

CDN이란?

 콘텐츠 전송 네트워크로써 지리, 물리적으로 떨어져 있는 사용자에게 컨텐츠를 더 빠르게 제공하는 시스템

(사용자와 가까운 곳에 위치한 Cache Server에 해당 Content를 저장(캐싱)하고 Content 요청시에 Cache Server가 응답을 주면서 속도 개선)

* 데이터 접근할 때  쓰이는 캐시 메모리나 웹페이지에 송수신 할 떄 쓰이는 캐시와 비슷한 개념이다.

 

위의 사진 처럼 세계 곳곳에 서버를 설치해 거리가 먼 사용자라도  가까운 CDN을 통해 정보를 제공 받게 한다. 

 

동작 방식

  1. 사용자로부터 요청이 발생합니다.
  2. 요청이 발생한 Edge Server는 요청이 발생한 데이터에 대하여 캐싱 여부를 확인합니다.
  3. 캐싱 데이터가 존재하면 사용자에 요청에 맞게 응답하고 존재하지 않으면 Origin Server로 요청합니다.
  4. 요청 받은 데이터에 대해 Origin Server로부터 전달 받은 Edge Server는 캐싱 데이터를 생성하고 사용자에게 응답합니다.

 

CDN의 장단점

장점:

  • 데이터 제공 받는 속도 빠름
  • 트래픽 급증 처리 가능
    하나의 Origin Serve로 수많은 사용자가 몰리는 것 방지

단점:

  • 단일 장애 지점
    시스템 하나가 잘못되면 전체 시스템을 사용 못 할 수 있음
  • 불필요한 여러개의 네트워크 연결
    특정 지역에서 서비스하는 즉, 타겟팅이 분명한 곳은 불필요하게 연결해야하는 네트워크 수가 많아 오히려 데이터 제공 시간이 지연될 수 있음

 

그럼 이제 cloudfront와 s3를 이용해보자

 

나는 Iam을 통해 S3권한을 받은 사용자를 만들 었다.

 

그럼 accessKey와 SecretKey를 받을 수 있고 이 값들이 있어야 S3 접근에 대한 권한이 생긴다.( 보안적으로 좋아짐)

 

그리고 S3를 만들고 cloudFront를 만든다. (저는 일단 기본값으로 세팅했습니다) -더 구체적인 것은 공부가 필요해 보이네요

 

cloudFront를 생성할 때 원본도메인에 내가 만들었던  S3 주소가 나오게 된다.

 

그럼 cloudfront가 s3에 연동되고 cloudFront의 도메인이 나온다.

 

그럼 기존에 S3Service 만들때 버킷 주소를 cloudFront 도메인으로 수정하면 끝!

 

내가 작성한 S3Service 코드

@Service
@NoArgsConstructor
public class S3Service {
    private AmazonS3 s3Client;

    public static final String CLOUD_FRONT_DOMAIN_NAME = "{cloudFront 도메인 주소}";

    @Value("${cloud.aws.credentials.access-key}")
    private String accessKey;   //S3접근할 키

    @Value("${cloud.aws.credentials.secret-key}")
    private String secretKey;  //S3접근할 키

    @Value("${cloud.aws.s3.bucket}")
    private String bucket;

    @Value("${cloud.aws.region.static}")
    private String region;

    @PostConstruct
    public void setS3Client() {
        AWSCredentials credentials = new BasicAWSCredentials(this.accessKey, this.secretKey);

        s3Client = AmazonS3ClientBuilder.standard()
            .withCredentials(new AWSStaticCredentialsProvider(credentials))
            .withRegion(this.region)
            .build();
    }

    public String upload(MultipartFile multipartFile) throws IOException {
        String fileName = UUID.randomUUID().toString();
        String extension = StringUtils.trimToNull(FilenameUtils.getExtension(multipartFile.getOriginalFilename()));
        String s3FileName = (extension != null) ? (fileName + "." + extension) : fileName;

        //파일 사이즈를 s3에 알려줌
        ObjectMetadata objMeta = new ObjectMetadata();
        objMeta.setContentLength(multipartFile.getInputStream().available());
        objMeta.setContentType(multipartFile.getContentType());  //컨텐트타입 지정해줘야 안드로이드 단에서 사진을 사용가능 
        //안알려주면 사진이 크롬에 띄워지는게 아니라 다운을 받게됨

        s3Client.putObject(bucket, s3FileName, multipartFile.getInputStream(), objMeta);

        return CLOUD_FRONT_DOMAIN_NAME + "/" + s3FileName;  //저장경로 반환
    }

    public void deleteFile(String fileName) {
        s3Client.deleteObject(new DeleteObjectRequest(bucket, fileName));
    }
}

'기타' 카테고리의 다른 글

AWS 서비스들 알아보기 1(API GateWay,S3,ELB,CloudFront,Secret manager)  (0) 2023.05.02
CI/CD(Github action)  (1) 2023.03.27
Swagger + Security 적용  (2) 2023.01.26
Spring Security 공부 + Jwt 적용  (1) 2023.01.26
R data 연습 다루기  (0) 2022.10.25