네이버 클라우드 캠프/Spring Boot & React

[Spring Boot & React] DB서버를 Object Storage로 변경하기

graph-dev 2023. 8. 11. 16:57
728x90

Object storage

 

Object Storage

네이버 클라우드에는 object storage라는 서비스가 있습니다. 홈페이지에서 다음과 같이 정의합니다.

 

모든 종류의 데이터를 인터넷상에 저장하고 검색할 수 있는 객체 스토리지

 

해당 서비스에 대해서는 다른 글에서 자세히 정리해보겠습니다. 자세한 내용은 아래 네이버 클라우드 홈페이지를 참고해주세요.

https://www.ncloud.com/product/storage/objectStorage 

 

NAVER CLOUD PLATFORM

cloud computing services for corporations, IaaS, PaaS, SaaS, with Global region and Security Technology Certification

www.ncloud.com

 

 

로컬 DB에서 클라우드 저장소로 전환하기

 기존에 Spring Boot와 React로 게시판 사이트를 만들고 파일 업로드를 수행하면, 첨부파일을 각 PC에 있는 로컬 서버 저장소에 저장하는 방법을 사용했습니다. 이 과정을 먼저 간단히 살펴보겠습니다.

 

로컬 DB에서 파일 업로드

아래는 Spring Boot와 React를 활용해서 만든 게시판 앱입니다. 먼저 두가지 이미지파일을 선택하고, 새 글 등록 버튼을 눌러보겠습니다. 

 정상적으로 저장되었다는 알림과 함께, 게시글이 등록됩니다. 이제 DB에도 저장이 잘 되었는지 확인해보기 위해, MySQL DB를 열어서 확인해보겠습니다. 두 가지 방법이 있습니다. 

 

 먼저, IntelliJ를 쓰시면 우측 Database 탭을 누르고, 저장된 테이블 t_board_file에서 해당 파일명이 있는지 확인해봅니다. 존재하고 있음을 알 수 있씁니다. 잘 등록이 된 것입니다.

intelliJ database

 다음은 MySQLWorkbench를 사용해서 확인해보겠습니다. 경로에 해당하는 스키마로 접속해서, 마찬가지로 t_board_file 테이블을 확인해보겠습니다. board_file_origin에 두 이미지 파일이 잘 들어가 있습니다. 이제 실제 경로로 들어가서 파일이 있는지 확인하겠습니다.

 

mysql workbench database

 

파일 경로는 board_file_path에 나온대로 Documents/upload/ 경로를 확인해보겠습니다. 실제로도 폴더 내에 잘 들어가있는 것을 알 수 있습니다.

 

 클라우드 DB에서 파일 업로드를 한다면 어떨까요? 사실 거의 동일하게 작동하지만 로컬 PC에서 확인할 수 없고 클라우드 저장소에 나타날 것입니다. 간단하게 실습해보겠습니다.

 

Object Storage Bucket 생성

 네이버 클라우드 플랫폼은 클라우드 저장소 중 Object Storage를 제공하고 있습니다. 이 서비스는 API 등을 사용해서 파일을 업로드하고, 권한에 따라 다운로드하는 기능을 가집니다. 먼저 버킷(Bucket)이라는 것을 생성해야 합니다. 버킷 생성을 누르고, "리전 내 유일한" 이름으로 설정해야 합니다. 이 점에 유의하고 이름을 지어줍니다. 암호화, 잠금 설정은 필요하면 하시되 잠금 설정은 조금 유의해주시면 되겠습니다. 탈퇴가 불가능해지는 경우가 있어서 주의하면 되고, 권한 관리도 우선 공개로 설정하겠습니다.

버킷 생성
생성후 최초 화면

 graph-bucket이라는 이름으로 버킷이 잘 생성되었고, 비어있는 것을 알 수 있습니다. 여기에 위에서 올린 두가지 파일을 업로드하는 과정을 진행할 것입니다.

 

Cloud DB for MySQL 서버 생성

 이 버킷 저장소는 쿼리문을 통해 내부 데이터를 접근하고 조작할 수 있습니다. 이 작업을 위해서 네이버 클라우드 플랫폼에서 제공하는 Cloud DB for MySQL상품으로 DB 서버를 생성해보겠습니다.

 

Ncloud 콘솔에서, Database > Cloud DB for MySQL을 선택하고, DB Server를 선택합니다. DB Server 생성을 하고 아래와 같이 입력하겠습니다. VPC는 기존에 만든 것을 사용하고, 고가용성은 체크하지 않았습니다. 단일 DB 서버로 우선 진행하고, 차후 필요하다면 변경도 가능하다고 하니 필요하신 분은 그때 수정하셔도 되겠습니다.

 

mysql 서버 생성화면(1)
mysql 서버 생성화면(2)

위와 같이 작성하고, DB Server는 호스트명의 중복을 방지하는 것도 알아두면 좋겠습니다. DB 서비스는 자유롭게 설정하시면 되고, HOST(IP)는 %로 모두 허용하고 빠르게 진행하겠습니다.

mysql 서버 설정

 

서버 생성이 완료되어 운영중으로 표기되면 다음 작업으로 넘어가겠습니다. 먼저 외부 접근을 위해서는 public 도메인을 신청해서 할당받아야 합니다. DB 관리 > Public 도메인 관리로 들어가서, 아래와 같이 Public 도메인 신청을 진행합니다.

public 도메인 신청

 

그리고 3306 포트를 ACG에서 열어주겠습니다. 아래 ACG 우측 버튼을 누르면 ACG 화면으로 넘어갑니다.

 

DB 서버 화면

 

ACG 설정을 누르면 규칙을 변경할 수 있습니다. TCP 접근 소스를 0.0.0.0/0, 허용 포트를 3306 으로 추가 설정해주고, ICMP도 0.0.0.0/0으로 설정후 적용합니다.

ACG 설정

추가로 하나 더 수행할 것이 있습니다. DB 서버 > DB 관리 > DB Service 초기화를 누릅니다. DB Service 초기화 탭에서 Config Name 중 lower_case_table_names에 해당하는 Config Value를 0에서 1로 변경하겠습니다.

mysql config value 변경
확인사항

 이후에는 다시 설정중이며, 운영중으로 DB 서버가 바뀌면 아래 작업을 수행하겠습니다. 먼저 DB Server 상세보기 > Database 관리에서,  studydb라는 데이터베이스를 추가하고 저장 버튼을 누릅니다.

 

Database 추가

 

 그 다음 MySQL Workbench로 접속합니다. New connection을 아래와 같이 생성해주겠습니다. 중요한 부분은 Hostname이 localhost말고 mysql db서버에서 public 도메인 값을 입력해줘야한다는 점입니다. 나머지 username, password 등은 기존에 mysql 서버에서 사용하던 것을 사용해주시면 됩니다.

 

mysql workbench new connection 생성

생성 후 Test connection을 누르면, 아래처럼 성공적으로 연결되었다고 뜨면 OK를 누르고 적용합니다.

success test connection

 

Spring Boot Configuration 수정

이렇게 완료시키고, 다음으로 Spring Boot 파일을 수정해보겠습니다. 먼저 build.gradle에서 dependencies 의존성 값을 하나 추가하겠습니다. 

implementation 'io.awspring.cloud:spring-cloud-starter-aws:2.4.4'​

 

그 다음, application.properties 파일로 이동해서 아래 값을 추가합니다.

# datasource 설정 정보
spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.jdbc-url=jdbc:mysql://[DB 서버 Public 도메인 값]:3306/studydb?serverTimezone=Asia/Seoul
spring.datasource.hikari.username=[DB서버 사용자 이름]
spring.datasource.hikari.password=[DB서버 사용자 비밀번호]

 

 여기서 인증키 값들을 살펴보겠습니다. 네이버 클라우드 플랫폼 홈페이지에서 마이페이지 > 계정 관리 > 인증키 관리로 들어갑니다. API 인증키 관리 탭에 Access Key ID, Secret Key를 저장해서 넣어주면 됩니다.

인증키 관리

다시 application.properties 하단에 아래 코드를 입력해줍니다.

# naver cloud objectstorage
ncp.accessKey=[인증키 Access Key ID]
ncp.secretKey=[인증키 Secret Key]
ncp.regionName=kr-standard
ncp.endPoint=https://kr.object.ncloudstorage.com

 

 그 다음 configuration > NaverConfiguration.java 클래스 파일을 생성하고 아래와 같이 입력합니다. @Value 어노테이션 값은 아래 String 변수에 할당된다는 의미입니다. 즉, String 선언된 변수에는 application.properties에 있는 ncp.변수명으로 위에서 선언된 값들이 저장된다고 생각하면 됩니다.

//NaverConfiguration

@Configuration
@PropertySource("classpath:/application.properties")
@Getter
public class NaverConfiguration {
    @Value("${ncp.accessKey}")
    private String accessKey;
    @Value("${ncp.secretKey}")
    private String secretKey;
    @Value("${ncp.regionName}")
    private String regionName;
    @Value("${ncp.endPoint}")
    private String endPoint;
}

 

마지막으로, FileUtils.java 클래스 파일을 아래와 같이 작성합니다. 자동으로 객체가 생성되며 AmazonS3 메서드를 활용합니다.

@Component //자동으로 객체 생성되도록 만든다.
public class FileUtils {
	private final AmazonS3 s3;

	//생성자 생성
	public FileUtils(NaverConfiguration naverConfiguration) {
		s3 = AmazonS3ClientBuilder.standard()
				.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(
						naverConfiguration.getEndPoint(), naverConfiguration.getRegionName()
				))
				.withCredentials(new AWSStaticCredentialsProvider(
						new BasicAWSCredentials(
								naverConfiguration.getAccessKey(), naverConfiguration.getSecretKey()
						)
				))
				.build();
	}

 

마지막으로 bucket 설정을 하고, 저장한 다음에 Java Application을 실행합니다.

public BoardFile parseFileInfo(MultipartFile file, String directoryPath) throws IOException {

		String bucketName = "graph-bucket";

//...

}

그 다음 React에서도 Files.js에서 일부 값을 바꾸겠습니다. src 값을 localhost:9090에서 http://kr.object.ncloudstorage.com/[버킷 이름] 으로 변경합니다.

        {boardFileList && boardFileList.map(boardFile => (
            <div style={{display: 'inline-block', position: 'relative', width: '150px', height: '120px',
                margin: '5px', border: '1px solid #00f', zIndex: 1}}>
                <input type="file" style={{display: 'none'}} id={`changeFile${boardFile.boardFileNo}`} 
                	onChange={(e) => changeBoardFile(e, boardFile.boardFileNo)}></input>
                        <img style={{width: '100%', height: '100%', zIndex: 'none',
                                        cursor: 'pointer'}} className="fileImg"
                                        id={`img${boardFile.boardFileNo}`} 
                                        src={`http://kr.object.ncloudstorage.com/[bucket 이름]/board/${boardFile.boardFileName}`} 
                                        onClick={() => openFileInput(boardFile.boardFileNo)}

 

다시 React에서 npm start를 수행합니다. 게시글 등록을 수행하고 동일한 두 가지 이미지를 업로드하겠습니다.

 

이제 Bucket Manangement에서 graph-bucket을 보시면 두개의 이미지가 올라온 것을 확인할 수 있습니다. 잘 연동된 것입니다.

object storage bucket 파일 업로드 후 화면

 

이렇게 Object Storage를 로컬 DB 대신하여 사용하는 실습을 진행해봤습니다.

 

 

결론

 여러모로 잘 배워두면 나중에 활용하기 좋겠습니다. 저장이 잘 되고 언제든 접속이 가능한 점이 마음에 듭니다. 다만, AWS S3 오픈소스를 활용하는 것은 편할 수 있지만 장기적으로는 네이버 클라우드 자체 코드가 제공된다면 AWS S3에 대한 의존성을 어느정도 완화하며 발전하지 않았을까 생각이 듭니다.