-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: 모놀리틱 구조에서 멀티 모듈 구조로 전환 #116
Conversation
This reverts commit 4d2ab31.
f90c94b
to
e6ad641
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
올려준 글이랑 코드들 잘 읽었어 고생많아쓰!! 👍👍 모듈 구조도 괜찮은 것 같아!
메인 서비스 코드들을 어느 모듈에 둬야될지가 좀 고민이 드는 것 같아!
@@ -58,7 +59,8 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse | |||
|
|||
String email = jwtUtil.getEmail(token); | |||
try { | |||
Member member = memberService.findByEmail(email); | |||
Member member = memberRepository.findByEmail(email) | |||
.orElseThrow(NotFoundMemberException::new);; | |||
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
auth모듈이 api모듈에 의존하지 않기 위해 memberService를 거치지 않고 memberRepository를 직접 사용하신거군요! 이 부분을 보다보니까 Service계층 코드들은 api같은 상위 모듈이 아니라 core나 common같은 비교적 하위 모듈에 배치하는건 어떨까요? Service 컴포넌트들은 메인 로직이라 다른 모듈들에서 의존을 어쩔수 없이 하게될 것같아요.
근데 또 이렇게 되면 공통 모듈만 너무 커져서 올려주신 우테코 게시글 처럼 공통 모듈만 너무 커지는 문제도 생길 것 같긴하네요. Service계층 코드들을 어디다 놔야할지 고민이 되는것같아요.... 어떻게 생각하시나요??
package com.numberone.backend.domain.user.service; | ||
|
||
public class UserAuthService { | ||
// todo: api 모듈의 token service 를 auth 모듈로 이관 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
} | ||
|
||
tasks.bootJar { | ||
enabled = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
올려주신 글에서 봤던 내용이네요. 메인 메소드가 있는 api모듈 말고는 모두 bootJar enabled값을 false로 해주는군요!
@Service | ||
@Component |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
private void convertAndSave(SaveDisasterRequest saveDisasterRequest) { | ||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); | ||
LocalDateTime dateTime = LocalDateTime.parse(saveDisasterRequest.getCreatedAt(), formatter); | ||
Disaster savedDisaster = | ||
disasterRepository.save( | ||
Disaster.of( | ||
saveDisasterRequest.getDisasterType(), | ||
saveDisasterRequest.getLocation(), | ||
saveDisasterRequest.getMsg(), | ||
saveDisasterRequest.getDisasterNum(), | ||
dateTime | ||
) | ||
); | ||
log.info("재난 발생 이벤트 발행"); | ||
eventPublisher.publishEvent(DisasterEvent.of(savedDisaster)); // 신규 재난 발생 이벤트 | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
disasterService의 크롤링관련 부분을 아예 crawler모듈쪽으로 옮겨서 crawler모듈과 api모듈간의 독립성을 신경써주셨군요! 좋은것같아요!👍
include 'daepiro-api' | ||
include 'daepiro-core' | ||
include 'daepiro-common' | ||
include 'daepiro-redis' | ||
include 'daepiro-auth' | ||
include 'daepiro-crawler' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
글에서 봤던 내용이네요. 멀티모듈 구조로 만들때 하위 프로젝트들을 루트 프로젝트의 settings.grade에서 모두 include해주는거군요!
|
||
@SpringBootApplication | ||
@ServletComponentScan |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ServletComponentScan 어노테이션이 어디에 쓰이는건가용? 구글링해봤는데 저희 프로젝트에서는 쓰이는 곳을 잘 못찾겠네요!
- name: get Current Time | ||
run: echo "CURRENT_TIME=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_ENV | ||
|
||
- name: 🔔 Send Slack Message when deploy started | ||
uses: 8398a7/action-slack@v3 | ||
with: | ||
status: custom | ||
custom_payload: | | ||
{ | ||
"attachments": [ | ||
{ | ||
"title": "대피로 백엔드 배포를 시작합니다. 👻", | ||
"pretext": "Daepiro backend is deploying...", | ||
"fields": [ | ||
{ | ||
"title": "Author 💻", | ||
"value": "${{ github.actor }}", | ||
"short": true | ||
}, | ||
{ | ||
"title": "Deploy time 🕚", | ||
"value": "${{ env.CURRENT_TIME }}", | ||
"short": true | ||
} | ||
] | ||
} | ||
] | ||
} | ||
env: | ||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | ||
if: always() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
mkdir -p ./daepiro-api/src/main/resources | ||
cd ./daepiro-api/src/main/resources | ||
touch ./application.yml | ||
echo "${{ secrets.PROPERTIES_PROD }}" | base64 --decode > ./application.yml | ||
ls -la | ||
shell: bash | ||
|
||
- name: 🐧 create service-account.json | ||
run: | | ||
cd ./src/main/resources | ||
cd ./daepiro-api/src/main/resources | ||
touch ./service-account.json | ||
echo "${{ secrets.FCM }}" | base64 --decode > ./service-account.json | ||
ls -la | ||
shell: bash | ||
|
||
- name: Build with jib | ||
run: | | ||
./gradlew jib -x test \ | ||
./gradlew :daepiro-api:jib -x test \ | ||
-Djib.to.auth.username=${{ secrets.DOCKER_USERNAME }} \ | ||
-Djib.to.auth.password=${{ secrets.DOCKER_PASSWORD }} \ | ||
-Djib.to.image="${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE }}:latest" | ||
env: | ||
EC2_PUBLIC_IP: ${{ secrets.EC2_PUBLIC_IP }} | ||
JMX_PORT: ${{ secrets.JMX_PORT }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
main 메서드가 api모듈에 있기 때문에 api모듈 경로에서 빌드를 해주는거군요!
멀티 모듈 구조로의 전환
오랜만에 PR 을 올립니다~~~
(모놀리틱 구조와 멀티모듈 구조에 관한 이해가 필요한 PR 입니다)
1.기존의 모놀리틱 구조의 문제점
기존의 대피로 백엔드는 모놀리틱 구조로 이루어져 있었는데요,
짧은 시간에 많은 요구사항을 시스템에 담으려하다 보니
기능 변경에 따라 영향도를 예측하기 어려워졌고
결국 관리 포인트가 늘어나게 되면서 확장성이 좋지 않은 것 같습니다.
또한 순환 참조나 코드 중복이 곳곳에 일어나면서 가독성도 떨어지고 로직을 한눈에 파악하기 힘들어져
유지보수성이 낮은 상황입니다.
( 중복된 코드 로직은 곳곳에 아직 남아있으며, 제거해야합니다. )
이러한 문제를 해결하고자 멀티 모듈 구조로의 전환을 시도했습니다.
멀티 모듈로의 전환이 성공하면, 앞으로 정말 깔끔하게 코드 베이스를 유지해나갈 수 있을 거에요~~
2. 왜 멀티모듈 구조로?
멀티모듈 설계 이야기 이 글을 읽어보는 것도 좋을 것 같아요!
3. 대피로 멀티모듈 구조 설명
아래와 같이 멀티모듈을 설계해보았는데요,
개발하면서 조금씩 모듈 간 책임, 의존성을 조정하며 좋은 구조로 갈 수 있도록 같이 고민해보면 좋을 것 같습니다!
api 모듈
core 모듈
redis 모듈
common 모듈
auth 모듈
common 모듈
이외의 작업
아마 처음 멀티모듈 구조를 경험하면 많이 불편하고 낯설 것 같은데요,,
하다가 막히는 점이나 궁금한 점이 생기면 바로 공유해주세요~~