도서 문장 공유 서비스 "스피딧"을 개발하던 중 도서 문장 피드를 조회하는 API가 있었다.
도서 피드 조회 API는 피드 전체 조회, 팔로우한 유저 피드 조회, 선택한 직업별 피드 조회, 선택한 도서별 피드 조회가 가능하였다.
스피딧 서비스의 피드 조회와 관련된 엔티티는 팔로우, 도서, 책, 유저 엔티티가 있다.
따라서 위의 조회 API를 사용시 JPA의 N+1문제가 발생한다는 것을 알게 되었다.
한번의 API를 사용할때마다 연관된 엔티티와 관련된 쿼리가 너무 많이 나갔다.
처리속도 개선 등 성능 개선을 하던 중에 트랜잭션 처리속도 시간을 측정하는 것도 필요하다고 느껴서 Spring AOP를 이용해서 트랜잭션 처리 속도까지 측정하도록 구현하였다.
다음은 이 과정에 대해서 포스팅하고자 한다.
Spring AOP를 이용해서 트랜잭션 처리 시간 측정하기
AOP를 적용하려는 타켓은 서비스 단의 메서드들이다.
1. AOP 관련 클래스를 하나 만든다.
해당 클래스가 AOP로 동작하게 하려면 스프링 컨테이너에 빈으로 등록되어 있어야 하므로 @Component 어노테이션을 적용해준다.
@Around("execution(* speedit.bookplate.service..*.*(..))")
@Around 안에 포인트컷 표현식을 작성해준다. 위의 코드에서는 service단 안에 모든 메서드에 적용한다는 뜻이다.
@Around는 메서드 실행전, 후에 모두 적용된다는 뜻이다.
Stopwatch 클래스를 사용해서 시간을 측정한다.
조인 포인트 호출 전에 시작 시간을 측정하고(stopWatch.start(); 코드)
어드바이스가 적용되는 위치인 조인 포인트(서비스단의 해당 메서드)를 동작하도록 한다.(joinPoint.proceed(); 코드)
조인 포인트 호출 뒤에 끝난 시간을 측정한다(stopWatch.stop(); 코드)
아래는 해당 코드이다.
아래와 같이 해당 메서드의 트랜잭션 처리 시간이 찍히는 것을 볼 수 있다.
참고
- https://jie0025.tistory.com/507
- https://velog.io/@dhk22/Spring-AOP-%EA%B0%84%EB%8B%A8%ED%95%9C-AOP-%EC%A0%81%EC%9A%A9-%EC%98%88%EC%A0%9C-%EB%A9%94%EC%84%9C%EB%93%9C-%EC%8B%A4%ED%96%89%EC%8B%9C%EA%B0%84-%EC%B8%A1%EC%A0%95
'프로젝트' 카테고리의 다른 글
조회 API 성능 개선하기 (0) | 2023.05.13 |
---|---|
JPA Pagination, 그리고 N+1 문제 (0) | 2023.05.03 |
서버 간 통신시 HTTP API와 Rabbit MQ 사용 성능 테스트 (0) | 2023.04.23 |
JPA에서 동시성 이슈 해결하기 (0) | 2023.04.05 |
서버 scale out으로 인한 특정 빈 중복 작동으로 인한 이슈 해결기 (0) | 2023.04.02 |