기존의 코드에서 비동기 처리를 고려한 이유 클라이언트가 ‘이메일 전송 요청’에 대한 기존의 시나리오는 다음과 같습니다. 먼저, 우리의 웹 서버와 DB에서 실행되어야 할 작업들이 실행됩니다. 그리고 외부 서버인 구글 SMTP 서버로 이메일 발송 요청을 한 후, 이메일 발송에 대한 응답이 온 후에야 클라이언트에게 완료했다는 응답을 보내주고 있습니다. 또 다른 시나리오는 푸시 알림 발송을 위한 firebase 서버로 요청하는 경우가 있습니다. 마찬가지로 사용자가 (대) 댓글을 작성했을 때 푸시 알림이 발송 완료될 때까지 응답을 기다리게 해야 하는 상황입니다. 현재는 비동기가 아니기 때문에, 하나의 스레드에서 일련의 작업을 진행하고 있습니다. 그러나 비동기 처리를 도입하게 되면, 작업이 완료되기를 기다리지 않습..
Spring AOP 기반의 @Async를 공부하다가, self-invocation(내부 호출)하는 경우에는 AOP가 걸리지 않는 이슈를 마주하게 되었습니다. 왜 내부 호출하는 메서드는 AOP 타겟이 되지 못하는 것인지, 그리고 이 문제를 해결할 수 있는 방법에는 어떤 것들이 있는지 알아보겠습니다. 내부 호출 시 왜 AOP 기능이 수행되지 않을까? 이 문제는 프록시 객체와 관련이 있습니다. 따라서, 먼저 프록시에 대해 간단하게 알아보겠습니다. 프록시 적용 전 실제 객체가 스프링 빈으로 등록됩니다. 빈 객체의 마지막 @x0..은 인스턴스를 의미합니다. 프록시 적용 후 스프링 컨테이너에 프록시 객체가 등록됩니다. 스프링 컨테이너는 이제 실제 객체가 아닌 프록시 객체를 스프링 빈으로 관리합니다. 실제 객체는 스..
도입한 이유 쿼리 튜닝을 하는 과정에서 나간 쿼리의 개수를 측정하는 과정에서 불편함이 있었습니다. 특히 아이돔 프로젝트에서는 Spring-Data-JPA를 사용합니다. 그로 인해 JPA N+1 문제와 같이 의도와 다르게 발생한 쿼리의 개수를 모니터링할 필요가 있었습니다. 문제 정의 1. API의 실행 시간 측정 2. 쿼리가 실행된 개수 카운트 3. 실행된 쿼리들을 리스트업 4. N+1 문제가 의심되는 쿼리를 체크 → 의심 조건 : 동일한 SELECT 문이 2개 이상 사용되었는가 구현 방식 일반적으로 쿼리 카운터를 구현하기 위해 고려하는 방법은 2가지 입니다. 두 가지 방식 모두 적용해 보겠습니다. 방식 1. 하이버네이트의 StatementInspector 인터페이스 먼저 ORM 프레임워크인 Hiberna..
도입한 이유 좋은 설계는 변경에 유연하게 대응할 수 있도록 도와줍니다. 기존의 코드는 계층형 아키텍처를 채택하면서 핵심 로직을 주로 도메인과 서비스에 몰아놓은 결과, 유지보수성이 낮았습니다. 특히, 일부 서비스는 많은 의존성 주입을 필요로 하며, 새로운 기능이 추가될수록 클래스가 점점 두꺼워졌습니다. 프로젝트가 확장되면서, 강하게 결합된 부분을 변경해야 하는 경우가 생기면서 여러 사이드 이펙트를 겪게 되었습니다. 따라서 큰 책임을 지닌 객체를 분리하고, 상속과 인터페이스 등을 활용하여 추상화를 도입하고, 다른 디자인 패턴을 적용함으로써 프로젝트의 유지보수성을 높이기로 결정했습니다. 물론, 기존의 계층형 아키텍처도 특정 기술에 대한 의존성을 인터페이스를 통해 분리할 수 있습니다. 실제로 확장성을 늘리기 위..