본문 바로가기
웹 프로그래밍

[GCP] GCS(Google Cloud Storage) Bucket 버킷 사용하기 + spring boot 에서 사용하기

by CSEGR 2024. 6. 29.
728x90

오늘은 프로젝트를 하면서 배운 GCS Bucket 버킷을 사용하는 법에 대해서 포스팅 해보도록 하겠습니다.

 

1. GCS 버킷이 뭔지

2. GCS 버킷을 왜 사용하는지

3. GCS 버킷을 어떻게 사용하는지 

 

What?

GCS(Google Cloud Storage) 버킷은 Google Cloud Platform(GCP)에서 제공하는 객체 스토리지 서비스입니다.

이 서비스는 전 세계 어디에서나(설정에 따라 다름) 데이터를 저장하고, 검색하며, 사용할 수 있게 해줍니다.

 

 

Why?

저같은 경우에는 프로젝트에서 게시판 이미지를 저장하기 위해 사용하였습니다. 

바이너리 파일형태로 DB에 저장하거나, 로컬 상의 디렉토리에 이미지를 저장하는 등의 문제점이 있습니다. 이때,

1. 로컬 데이터 저장 시스템은 보통 한정된 용량과 처리 능력을 가지고 있어서 큰 규모의 데이터 처리가 필요한 경우 확장하기 어려울 수 있습니다.

2. 로컬 데이터 저장 시스템은 단일 위치에 데이터를 저장하기 때문에 데이터 손실 가능성이 높습니다.

 

이러한 단점을 보완하기 위해 사용을 해보았습니다 !

 

HOW!!!!!

 

1. menu 에서 Cloud Storage 에서 버킷 선택 

 

2. 버킷 옆에 만들기 버튼 클릭

3. 옵션 설정 

 

☑️ 버킷 이름은 유일무이 해야합니다 !

 

저는 그룹 프로젝트를 진행하였기 때문에, "✅ 이 버킷에 공개 액세스 방지 적용" 을 해제 해주었습니다.

 

4. 공개 엑세스 설정 

 

1) 권한 > 액세스 권한 부여 선택 

2) allUsers / 저장소 개체 뷰어 선택

 

 

 

이미지를 업로드하고 공개 액세스 > URL 복사 > 브라우저에 붙여넣기 를 하면, 브라우저에서 확인하실 수 있습니다 !!

 

 

5. 권한 설정 및 key 파일 설정

 

1) 서비스 이름 설정

2) 액세스 권한 부여 - 저장소 개체 관리자, 저장소 관리자, 저장소 개체 생성자

3) 키 관리 - key 생성( JSON 형태 )

 

이때 생성된 JSON key 파일은 노트북 폴더에 저장해둡니다!! 사용시 resource에 key 파일을 넣어야하니 꼭 위치를 기억해주세요 !

 

스프링 부트에서 사용하기

 

1. 의존성 추가

implementation group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter', version: '1.2.5.RELEASE'
implementation group: 'org.springframework.cloud', name: 'spring-cloud-gcp-storage', version: '1.2.5.RELEASE'

 

build.gradle 에 의존성을 추가해주세요.

 

2. resources 에 json 파일 추가해주기.

 

3. StorageConfig 작성 

Global config 에 storage config를 작성해주면 됩니다.

import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;

@Configuration
public class StorageConfig {

    @Bean
    public Storage storage() throws IOException {

        ClassPathResource resource = new ClassPathResource("[json 파일 이름]");
        GoogleCredentials credentials = GoogleCredentials.fromStream(resource.getInputStream());
        String projectId = "[json에 있는 project_id]";

        return StorageOptions.newBuilder()
                .setCredentials(credentials)
                .setProjectId(projectId)
                .build().getService();
    }

}

 

4. 서비스 내 설정

import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import webprogrammingTeam.matchingService.domain.program.entity.Program;
import webprogrammingTeam.matchingService.domain.Image.entity.Image;
import webprogrammingTeam.matchingService.domain.Image.repository.ImageRepository;
import org.apache.commons.io.FilenameUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

@Service
@Transactional
@RequiredArgsConstructor
@Slf4j
public class ImageService {

    private final Storage storage;

    private String bucketName = "[생성시 설정한 bucket 이름]";
    private final ImageRepository imageRepository;

    public List<Image> uploadImages(Program program, MultipartFile[] multipartFiles) throws IOException {

        List<Image> images = new ArrayList<>();

        for (MultipartFile multipartFile : multipartFiles) {
        	//각 이미지마다 고유한 UUID를 생성합니다.
            String uuid = UUID.randomUUID().toString();
            //업로드된 파일의 원본 파일명을 가져옵니다.
            String originalFilename = multipartFile.getOriginalFilename();
            //파일의 확장자를 추출합니다.
            String type = FilenameUtils.getExtension(originalFilename);

			//storage를 사용하여 GCS에 새로운 Blob을 생성합니다.
            storage.create(BlobInfo.newBuilder(BlobId.of(bucketName, uuid))
                    .setContentType(type) //Blob의 컨텐츠 타입을 설정합니다.
                    .build(), multipartFile.getInputStream());
                    //Blob을 생성하고 업로드할 파일의 입력 스트림을 전달합니다.

			//GCS에 업로드된 이미지의 공개 URL을 생성합니다.
            String fileUrl = String.format("https://storage.googleapis.com/%s/%s", bucketName, uuid);
            //업로드된 이미지 정보를 담은 새로운 Image 엔티티를 생성합니다.
            Image image = Image.builder()
                    .url(fileUrl)
                    .program(program)
                    .build();

            imageRepository.save(image);
            images.add(image);
            program.getImages().add(image);

            log.info("저장!");
        }

        return images;
    }
}

 

 

여기서 이미지마다 고유한 UUID를 생성해준 이유는 동일한 파일 이름이 있을 경우, 원하는 파일을 불러오지 못 하는 경우를 대비하기 위함입니다. 

728x90