728x90
findDateBetween(LocalDateTime arg1, LocalDateTime arg2)

 

 

이렇게 조회 했더니 안됐다. 이유를 찾아 보니

 

byte[], byte[] 로 인식한다고 한다.

 

해결 방법은

 

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-java8</artifactId>
    <version>${hibernate.version}</version>
</dependency>

 

 

이걸 추가 하면 된다고 한다.

 

그래서 추가 했더니 잘 됐다.

 

그러나 굳이 추가 해서 프로젝트 용량을 더 늘릴 필요성을 못느껴서 LocalDateTime을 Date 타입으로 컨버팅 하는 정적 유틸 메소드가 있어서 해당 메소드를 사용했다.

 

 

 

참조

https://developer-syubrofo.tistory.com/289 [공부는 관성이다.:티스토리]

 

728x90

배경

기존에 A 서버에서 B 서버로 호출 하면 써드파티 알림톡 발송업체로 호출 하고 다시 A 서버로 콜백 하는 방식이었다. (A 서버 에서는 해당 발송 결과 내역을 저장한다.) N번의 알림톡 발송 요청이 생기면 A서버가 즉시 N번의 콜백 요청을 받아 수행했었다. 이 부분에서 회사 트래픽이 올라가면서 cpu 사용량이 많이 올라가기 시작했다.

그래서 회사 동료분중 한 분이 해당 부분을 개선하기 위해 A 서버에서 콜백을 받고 바로 처리 하는게 아니라, 콜백을 받으면 카프카에 이벤트를 저장하는 방식으로 바꾸셨다. 그런데 여기서도 cpu 부하가 걸렸다. (A 서버에서 카프카로 이벤트를 발행만 하는데도 부하가 생겼다.) 그래서 내가 해당 이슈에 대해서 곰곰히 생각해 보았다. 처음에 해당 로직의 성격상 A 서버에서 처리를 하는게 맞는가를 따져 보았을 때, 그건 맞았다. 그래서 해당 레거시 코드를 작성하신 분을 어느정도 이해할 수 있었다. 
그러나 이미 A 서버는 무거워서 간당간당한 상황이었다. 이벤트를 발행 하는 역할은 AWS Lambda를 사용 해봐도 괜찮겠다는 생각이 들어 말씀 드렸었다. 이후 자연스럽게 내가 프로젝트에 참여하게 되었다. 

 

해결 방법 모색

처음에 이벤트 발행을 Lambda 에서 하는 것을 시작으로 생각을 이어 나갔다. 그 와중에 Produce/Consume 둘 다 람다에서 해도 되겠다는 생각이 들었다. 공유를 드리고 개발을 해보았다. 지금까지 나는 이 회사에 들어와서 카프카를 접해볼 시간이 없었다. 이번에 처음 접해 보니 회사 넥서스에 회사 전용 카프카 전용 객체가 있었고 기존에 카프카는 이와 함께 맞물려 돌아 가고 있었다. 이를 처음으로 node.js 환경에서 돌아갈 수 있게 새로 개발 해야 하는 공수를 들여야 했다. 하면 되겠지만 이미 할 일도 많고 굳이 이렇게 까지 할 필요가 있을까 라는 의견들이 있었다. 그리고 무엇 보다 더 크리티컬한 이유는 기존에 카프카를 사용할 때 실패한 이벤트에 대한 전략이 세워져 있지않아서 이 상태로 람다에다가 적용 할 npm 라이브러리를 만들면 기술 부채를 그대로 옮겨 놓는 것 이라고 판단 했다.
결론은 현재 트래픽으로는 굳이 카프카를 사용 할만한 처리량을 갖고 있지 않은 상태에서 적용 하는건 오버엔지니어링이고 실패한 이벤트에 대한 전략이 없는 상태에서 npm 라이브러리를 만들면 기술부채를 쌓는 격이라고 생각했다. 그래서 회사의 발전 상황에 따라 조금씩 발전 시키기로 결정 하여 버전으로 나누어서 청사진을 그려 보았다. 

 

- V1
    - Lambda 에서 바로 DB에 쌓기

 


- V2
    - Lambda 에서 Produce하기

 


- V3
    - Lambda 에서 Produce/Consume 하기

 


- V4
    - Transactional Outboxing Pattern 적용하기

 

 

마무리

이번 고민을 통해 여러 방면에서 퍼포먼스 개선을 고민할 수 있었다. 메시지 큐를 직접 다뤄본 적은 이번이 처음이었지만, 많은 회사에서 이를 사용하는 이유를 이해하게 되었다. '대용량'이라는 개념이 사람마다 다르고 회사의 서버 스펙에 따라 달라질 수 있어 명확히 정의하기 어려운 단어라는 점도 느꼈다. 카프카가 대용량 트래픽에 적합하다는 평가를 받지만, 현재 회사 상황에서는 오버엔지니어링이 될 수 있다는 고민을 많이 했다. 또한, 이번 기회를 통해 이벤트 관리의 중요성에 대해서도 깊이 생각해보게 되었다. 전체적으로 메시지 큐의 쓰임새에 대해 더 깊이 이해할 수 있는 유익한 시간이었다.

728x90

들어가며

개인 프로젝트에서 유닛 테스트를 짜고 있었다. SMS, 이메일 인증 로직을 테스트 하려고 하다가 고민에 빠졌다. 해당 로직은 외부 캐시 서비스를 사용 해서 인증번호 대조를 진행한다. 이를 테스트 하기 위한 방법론에 대한 고민에 빠진 것이다. 고민은 Spy 객체를 만들어서 코드로 로직을 검증할까, 아니면 실제 데이터를 가지고 검증을 할까 고민이었다. 해당 서비스는 외부 서비스를 의존하는 서비스라서 자바 코드로 검증하기엔 단지 flow만 검증하는 느낌이었다. 그래서 flow 뿐만 아니라 데이터도 검증 해서 더 정확히 검증 할 수 있게 실제로 Redis를 붙여서 검증하기로 결정 하였다. Mockist인 나로서는 고민이 되는 부분이었다.

 

해결

애플리케이션을 전부 올리는 SpringBootTest를 사용하기엔 테스트 시간을 너무 소비하는 느낌이어서 생산성이 떨어질 것 같았다. 그래서 test profile 전용 application yaml 파일을 만들고 테스트에 쓰일 Redis config 파일을 만들었다. 그 다음으로 Redis를 실행 시켜야 하는데 배포 전에 CI 가 실행 되는 github actions VM 에 매번 이러한 테스트가 생길 때마다 해당 하는 이미지를 올리는 등 이러한 관리 공수가 들것이라고 생각했다. 매번 CI script 코드도 수정 해야 하는데, 테스트 코드와 script 싱크를 맞추는 것도 추후 서비스가 더 커지면 귀찮은 일이라고 느껴질 수 있겠다고 생각했다. 그래서 이것도 자동화 하고싶었다. 그래서 github actions VM에 도커 환경을 세팅 해준 후 ./gradlew build 을 해주면 자동으로 @Testcontainer가 붙은 클래스에서 필요한 이미지를 세팅 해주는 테스트 환경을 구성했다.

 

기대할 수 있는 점

Testcontainer를 활용하면 앞으로 다양하게 테스트를 운영 환경이랑 최대한 비슷하게 해볼 수 있을거라고 기대한다. 지금까지 integration test는 H2 in-memory 디비로 했었지만 한계가 있었다. 호환하지 않은 문법 등 많아서 테스트를 위해 관리 해야 할 점들이 많았었다. 그런점에서 운영 환경이랑 비슷하다고 생각이 안되었다. (그렇다고 해서 도커를 띄워서 운영 환경을 만들 수 없다는건 아니긴 하다. 만들 수는 있지만 억지로 만들어주는 느낌으로 운영 코드랑 필요한 이미지를 싱크를 CI script로 맞춰 줘야 하는 단점이 있다.) 그러나 Testcontainer는 필요한 이미지를 코드단에서 관리가 가능하기 때문에 테스트에 더 집중할 수 있다고 생각한다. 그리고 코드로 운영 환경을 최대한 구성할 수 있어서 테스트를 실제 운영환경이랑 비슷하게 할 수 있다는 장점이 있었다.

+ Recent posts