Eureka와 API Gateway를 이용해서
게이트웨이의 port를 통해 microservice까지 이어지게끔 테스트 하던 도중
yml로 라우팅을 시도하면 안되고,
filterconfig 파일 생성 및 gatewayRoutes 함수로 자바단에서 라우팅하면 정상 작동하는 점을 발견,
왜안되지 삽질을 많이 했는데,
yml에서 spring 아래 indent로 cloud를 써야하는데,
예시 :
spring
application:
name:
cloud:
에러 예시:
spring
application:
name:
cloud:
이렇게 indent되어있는것을 확인 못하고 몇일을 삽질했다..
MSA 구성에는 마이크로 서비스가 각각 구성되어 빌드되고 배포되기 때문에,
실시간 처리가 가능하고, 스케일아웃에도 유연하게 대비되는 대규모 메시징 시스템이 필요.
우리는 유레카 서버를 이용해서 MSA를 구축했고, 유레카의 스케일아웃에도 대비해야하니 RabbitMQ보다 Kafka가 적합.
하지만 카프카를 구현하기 이전에 어디에 필요한지 알아야 하겠지?
이 대답을 하려면 내가 궁극적으로 어떤 시스템을 구현하고싶은지 정의해야한다.
나는 자동 매매 시스템, 모의 투자 시스템을 구현하고싶다.
원래 내가 구현하고싶은건 두가지였는데
예를 들어
crontab으로 1분마다 시세 조회 후 내가 설정한 가격 이하면 매수
급락 기준 설정, 바닥이 아니라 반등 기준 후 매수 설정
과 같은 로직?
음..아무리 사이드 프로젝트라고 하더라도 무작정 개발부터 하는게 맞나?
기획으로 먼저 정의되어야 하는것 아닐까..?
라는 생각이 자꾸 든다..
일단 실행에 옮기자!
화면 기획서든 문서든 하기 싫은거에 빠져서 포기하지 않도록.
구현해보고 아 이게 필요하겠다 라고 써둔 메모가 쌓여서 기획문서가 될 수 있잖아?
일단 코딩이 하고싶고 kafka가 찍어주는 로그를 얼른 보고싶으니까!
유저ms를 구현하던 중, Spring boot 디렉토리 구조라던지, DAO, DTO, VO, Entity, Repository
이런 엔티티에 대해서 확실하게 정리하고 넘어갈 필요가 있다고 생각이 들었다.
전에 회사에서는 VO를 DTO이자 Entity로 사용했기 때문에 좀 달라질 필요가 있다.
DTO Data Transfer Object
- 계층간 데이터 교환 위한 객체, 로직 미존재, getter setter만 존재.
VO Value Object
- Read only 속성을 가지며 값을 표현하기 위한 객체 (예시 private final int response_ok = 200)
DAO Data Access Object
- DB 데이터에 접근위한 객체
카프카를 통해 DTO, DAO, Entity, Repository 다 구현해야하고 직접 접해보니까 이해가 더 잘된다.
전 회사에서는 DAO와 VO만 존재했다. 사실 VO라고 써놓긴 했지만 Read only 속성도 없이 .setOOO()하면서 사용해서 다시 공부하면서 더 햇갈린것 같다.
그래서 이번엔 JPA를 사용하다보니 domain, repository, entity 등 잘 구분해서 쓸것이다!
하지만 각자 목적을 위해 비슷한 변수를 가지고 있는 OrderDto, OrderResponse, OrderRequest 등을 다루다 보면
이쪽에서 꺼내와서 저쪽에 넣고 setOrderId(order.getOrderID())를 평생 할 순 없다.
그래서 ModelMapper를 사용하더라!
주요 장점은 가독성 증가, 실수 방지!
완전 유용하자나.
ModelMapper는 의존성을 따로 추가해주어야 사용가능하다
dependencies{
...
implementation 'org.modelmapper:modelmapper:3.1.0'
}
UserMapDto userMapDto = mapper.map(user, UserMapDto.class);
하지만 때에 따라서 좋게 좋게 넘어가면서 매핑이 필요할때도,
또는 이름과 타입이 동일해야만 매핑이 필요할때도 있겠다. 따라서
3가지 전략이 존재한다.
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STANDARD) // STANDARD 전략
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.LOOSE)
// LOOSE 전략
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT)
// STRICT 전략
여기서 우리는 Strict를 사용한다. 타입과 필드명이 같으므로!
자세한건 여기서 찾아보면서 공부했다!
https://devwithpug.github.io/java/java-modelmapper/
인터넷을 찾아보면 찾아볼수록 햇갈리기 시작하지만.. 정보를 정제하고 이해하면서 명확해지기 시작한다. 관심사의 분리가 필요하니 DTO와 Entity는 분리가 필요하니 DTO는 따로 구현을 할 것이다.
Entity와 Domain에 대해서 햇갈리기도 하고, 블로그 마다 해석이 다르다. 둘다 DB 테이블과 1대1 매칭되는 객체이지만 명명 방식이 다른것 같다. 나는 프로젝트 구조와 연관이 있다고 이해했다.
도메인형 구조를 띄고 있다면 Entity, 계층형 구조를 띄고 있다면 해당 객체들이 한 폴더안에 몰려 있으므로 도메인의 집합이 맞다고 생각해서 Domain.
나는 규모가 크지 않고, 특히나 MSA로 구현되어 멀티레포로 관리되기 때문에 도메인형 구조를 택할 이유가 없어 계층형 구조를 선택했고, 따라서 Domain으로 명명 및 구현할 것이다!
config
controller
service
dto
ㄴ UserDto.java
repository
domain
ㄴ User.java
ㄴ BlackList.java
이렇게!!
프로젝트의 구조와 네이밍 규칙은 내 가치관에 따라 정의를 하고 해석을 해 두었으니! 이제 정말 카프카를 구현해야겠지...
다음 장에서 계속...