냉메추

[냉메추] 멀티모듈로 구현을 한다는 것. 서버가 많이 필요하다는 것.

장아장 2024. 4. 29. 17:16

돈돈! 더 많은 돈!! 내가 싼 똥이다!!!!! 하하하하하하하하하하하ㅏ하하하하하하하하

이전에 이야기한 대로, 멀티모듈로 프로젝트를 만들기로 했다. 

멀티 모듈을 어떻게 배포하는 건지, 처음부터 다시 정리해보기 시작했다. 


settings.gradle, build.gradle설정해주기

물론 IDE 등에서 내부에 모듈을 추가하게 하면 자동으로 추가되지만, 그래도 알고 지나가는 것은 중요하다고 생각한다.

우리가 가지고 있는 모듈 내부에 이런 모듈들이 존재한다는 것을 명시해주었다. 

 

또한, build.gradle에서 이렇게 내부에 include된 모듈들에 대한 공통적인 dependencies를 추가해줄 수 있었다. 

subprojects {
    apply plugin: 'java'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    apply plugin: 'org.asciidoctor.jvm.convert'

    group = 'org.capstone'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = '17'

    repositories {
        mavenCentral()
    }

    configurations {
        compileOnly {
            extendsFrom annotationProcessor
        }
        asciidoctorExt
    }

    ext {
        set('snippetsDir', file("build/generated-snippets"))
    }

    dependencies {
        ....
    }

    tasks.named('test') {
        outputs.dir snippetsDir
        useJUnitPlatform()
    }
    ...
}

 

이렇게 내부 모듈들이 공통적으로 가질 의존성과 다른 build.gradle에 대한 설정들을 명시해줄 수 있었다.


Common 모듈이 필요했다. 

jwt 토큰에 대한 인증/인가를 확인하는 로직과, 공통적으로 설정해야 하는 CORS를 꾹꾹 눌러담은 모듈을 만들었다. 

common이라고 명명하기 전에 auth 모듈이라고 명명해두고 시작해둔 상태이다. 

 

이 모듈에서는 JPA와 OAuth2, jwt를 위한 데이터들을 yml파일에 담아두었다. 

로그인/로그아웃/토큰 재발행/토큰 인증&인가 등에 대한 로직도 담아둔 상태이다. 

(1차 MVP가 끝나면 로그인등의 로직은 분리해서 다른 모듈로 배포해야겠다는 생각이 든다. 이걸 모든 모듈이 가져가 사용하는것은 비효율적인 것 같다)

 

JPA등의 application.yml외에 이 모듈이 가장 중요한 이유는 이 어노테이션 하나다. 

이번에 Spring Security의 많은 시큐리티 체인 대신에, 간단하게 토큰을 복호화해 검증하는 로직 하나만을 쓰고싶었다. 

그래서 이런 어노테이션을 만들어, 다른 모듈에서 사용할 수 있게 하고 싶었다. 


Common 모듈을 가져다 썼다. 

auth 모듈을 가져다 쓰는 다른 모듈의 build.gradle속의 dependencies이다. (미리 스포된 것 같지만 코틀린으로 만들어져있다...이 고생도 블로깅해야지)

 

이렇게 세팅을 해주고 해당 모듈의 로직들이 import된 것 처럼 사용할 수 있었다. 

이렇게 하면 다른 모듈에서 auth 모듈의 코드를 사용할 수 있었고, 배포를 모듈 단위로 할 수 있었다. 


여기서 문제. 나는 몇 개의 모듈을 쓸까?

여기에서 커다란 문제에 봉착했다. 

생각해보니, 모듈 단위로 컨테이너를 분리해서 배포를 한다고 했을 때, 

내가 만들어야 할 모듈은 Auth, Member, Fridge, Recipe가 있었다. 

후에 머신러닝을 위한 모듈 또한 만들어야 하고, 컨테이너 외부에서는 레디스가 동작하는 중이다.(이것도 스포다)

 

이런 수많은 컨테이너를 서버에서 버틸 수 있을까가 가장 큰 문제였다. 

그래서 스왑을 늘려버렸다. 

서버비를 더 내기엔, 직업도 없는 학생의 신분에서 너무 어려운 일이었다. 

현재 Auth, Member, Fridge가 올라가 있는 상태이고, 3개의 모듈과 Redis가 켜져있다. 

 

스왑까지 총 4Gi를 가질 수 있는 서버의 현 상황에서, 1.6Gi만 남은 상태이다. 딱 컨테이너 두 개 정도 올릴 수 있는 수준이라고 판단했다. 

(돈 굳었다...!)


그래서, 이렇게 하면 좋음?

확실하게 멀티 모듈로 프로젝트를 진행해보면서 느낀점은, 

상황에 따라 이게 안좋게 보일 수 있겠다는 느낌이 들었다. 

 

나처럼 서버를 여러 대 사용할 수 없는 상황이라면 멀티 모듈로 인해 오히려 싱글모듈로 배포하는 것이 더 비용적으로 효율적일것이라는 생각이 들었다. 

 

나는 도메인 단위로 모듈이 간섭되지 않게 구현해 이정도지만, 각 도메인간의 이벤트로 연결이 많다면 오히려 멀티모듈 사용시 kafka나 Redis Pub/Sub을 사용해야 하는 소요가 발생할 수 있다는 생각이 든다. 

(하지만, 나도 Redis Pub/Sub을 사용하고 있다. 이벤트를 이용해야 할 상황이 있었다)


오늘의 키워드 : 체신기술, 고오급 기술이라고 다 막 쓰지는 말자.

주변에서 멀티모듈, MSA, kafka/Redis pubsub등이 트렌드라는 이야기를 듣고 이를 적용해보고 있지만, 

이런 것들이 마냥 좋겠다는 생각이 들지는 않았다. 

 

더 많은 서버와 같은 자원이 충분하다면 이를 통한 경험은 무시할 수 없을 것 같다. 

하지만, 현재 나의 상황을 알고 이를 활용해야 한다는 생각이 들었다.