[Spring AOP] 로그 추적기 개발(ThreadLocal)
·
Spring/AOP
요구사항 분석만약, 새로운 회사에 입사했는데, 수 년간 운영중인 거대한 프로젝트에 투입되었다. 전체 소스 코드는 수 십만 라인 이고, 클래스 수도 수 백개 이상이다.나에게 처음 맡겨진 요구사항은 로그 추적기를 만드는 것이다. 하물며, 애플리케이션이 커지면서 점점 모니터링과 운영이 중요해지는 단계이다. 특히 최근 자주 병목이 발생하고 있다. 어떤 부 분에서 병목이 발생하는지, 그리고 어떤 부분에서 예외가 발생하는지를 로그를 통해 확인하는 것이 점점 중요해지고 있다. 기존에는 개발자가 문제가 발생한 다음에 관련 부분을 어렵게 찾아서 로그를 하나하나 직접 만들어서 남겼다. 로그를 미리 남겨둔다면 이런 부분을 손쉽게 찾을 수 있을 것이다. 이 부분을 개선하고 자동화 하는 것이 나의 미션이다.  요구사항모든 PU..
[SpringBoot] OSIV와 성능 최적화
·
Spring/JPA
OSIV는 Open Session In View의 약자이다. OSIV는 Spring에 spring.jpa.open-in-view: true 기본값으로 설정되어 있다. OSIV 전략은 최초 데이터베이스 커넥션 시작부터 API 응답(View에 전송 및 DTO 반환 등)이 끝날 때 까지, 영속성 컨텍스트와 데이터베이스 커넥션을 유지한다. 그렇기 때문에 View Template 또는 Controller에서 지연 로딩이 가능하다. 따라서, 개발자로 하여금 어느 곳에서도 데이터베이스 커넥션을 신경쓰지 않고 개발할 수 있게 해준다는 장점이 있다. 하지만, 해당 전략은 너무 오랜시간동안 데이터베이스 커넥션을 사용하기 때문에 실시간 트래픽이 중요하고 많은 애플리케이션에서는 커넥션 쓰레드 풀이 모자랄 수 있다. 이는 곧 ..
[SpringBoot] JPA Collection 페이징 처리
·
Spring/JPA
앞 JPA Collection 페치 조인 최적화 방법은 데이터가 뻥튀기 되기에 페이징 처리에 어려움이 있었다. 하지만, 다른 방법을 사용하면 Collection 페이징 처리가 가능한데 다음과 같은 방법을 따르면 된다. 방법 1. @XToOne(OneToOne, ManyToOne) 관계에 대해선 기존의 페치 조인을 활용한다. (컬렉션은 지연 로딩) @Override public List findAllWithMemberDelivery(Pageable pageable) { QOrder order = QOrder.order; QMember member = QMember.member; QDelivery delivery = QDelivery.delivery; return jpaQueryFactory .select(..
[SpringBoot] JPA Collection 페치 조인 최적화
·
Spring/JPA
Collection은 @ManyToOne가 아닌 @OneToMany를 사용하는 변수에 사용된다. 하지만, @OneToMany. 즉, 일대다 관계에서 Collection을 조회하면 데이터가 뻥튀기가 된다. 예를 들어, Order(주문), OrderItem(주문된 아이템)이 있다고 했을 때 관계의 주인은 OrderItem이다. 하지만, 관계의 주인(외래키)은 N인 OrderItem이 갖고 있으므로, Order를 기준으로 조인을 진행하면 데이터가 늘어난다. 그렇기에 반환시 중복된 데이터가 나오게 된다. 따라서, 기존의 페치 조인 최적화 쿼리와는 달리 jpql 혹은 querydsl에서 distinct를 추가 해주어야 한다. @Override public List findAllWithItem() { QOrder ..
[SpringBoot] Repository에서 DTO로 바로 조회
·
Spring/JPA
앞 글에서 살펴보았던 페치 조인보다 조금 더 성능적으로 좋은 방법은, Repository에서 DTO로 바로 조회하는 방법이다. 코드 @Query("select new jpabook.jpashop.repository.OrderSimpleQueryDto(o.id, m.name, o.orderDate, o.status, d.address)" + "from Order o" + " join o.member m" + " join o.delivery d") public List findOrderDtos(); 페치 조인 사용시 나가는 쿼리 select o1_0.order_id, d1_0.delivery_id, d1_0.city, d1_0.street, d1_0.zipcode, d1_0.status, m1_0.membe..