ElastiCache과 Redisson을 통해 스프링 부트에서 무형 객체 캐싱하기
·
스프링 부트/Java
원격 웨이팅 서비스에서 가장 많이 동작하는 API는 무엇일까? 놀랍게도 조회 API이다. 하루에도 수천 명의 사용자는 수십 개의 매장을 살펴보며 메뉴를 구경하고, 마음에 드는 곳을 발견하면 웨이팅을 걸고는 한다. 라인업지도 그랬다. 만약, 서비스를 접속했는데 주점 목록을 가져오는 데 수 초 이상이 걸린다면 어떻게 될까? 물론 서비스 사용자 수가 적을 때에는 문제가 없겠지만, 축제 기간에 수 백~수 천 명의 사용자가 초 단위로 접속하면 당연히 DB에는 부하가 갈 것이고, 부하가 가면 랜딩 페이지를 가져오는 데에는 오랜 시간이 걸릴 것이다. 사람들이 웹사이트를 처음 보고 해당 웹사이트가 어떤지 평가하는 데 걸리는 시간은 50m/s 이내(20분의 1초)라고 한다. 따라서 랜딩 페이지에서 데이터 로딩이 지연되는..
AuroraDB와 @Transactional 어노테이션을 통한 간단한 CQRS 구현하기
·
스프링 부트/Java
또 라인업지다. 혹시 라인업지가 무엇인지 궁금하신 분들을 위해 간단히 설명하자면, 2024년 가천대학교 가을 축제에 사용된 원격 웨이팅 서비스이다. 그리고 이 서비스를 구현하기 위해 경험했던 기술적 도전들을 차례차례 풀어나가고 있으며, 이번 글은 AuroraDB와 @Transactional 어노테이션을 통한 간단한 CQRS를 구현하는 내용이 될 것이다! CQRSCQRS(Command and Query Responsibility Segregation)는, 데이터 저장소(DB)로부터 발생하는 읽기 작업과 쓰기 작업을 분리하는 것을 뜻한다. 간단히 말해, 조회(R)와 명령(CUD) 작업을 분리한다는 것이다. 대부분의 서비스는 쓰기 작업보다 조회 작업이 압도적으로 많이 발생하기 때문에, 저장소를 분리하여 조금이..
@Valid 검증 예외 처리를 통한 공통 응답 보내기
·
스프링 부트/Java
현재 리드를 역임하고 있는 가천대학교 IT학술동아리 Leets의 5기 새 단장(?)을 맞아, 랜딩 페이지에 신기능을 도입하는 중이다.신기능이라고 해봤자 거창한 것은 아니고, 모집 알림 신청 기능을 메일링을 통해 구현해주는 것이 목표이다! 이번 글은 해당 기능을 구현하면서 DTO에서 필드 검증 시에 발생하는 예외를 어떻게 처리하여 프런트에게 공통 응답을 보내줄 수 있었는지에 대한 내용이 될 것이다.덕분에 오늘도 프런트랑 행복한 협업을 진행할 수 있게 되었다..>_ DTO에서 필드 검증하기DTO를 통해 필요한 값을 전달 받을 때, 프런트에서도 검증을 해주지만 혹시 모를 경우에 대비해 서버 단에서도 검증을 해주는 것이 좋다.이를 위해서 우리는 @Valid 어노테이션을 사용해야 한다. @Valid@Valid 어..
AOP 로깅을 통한 효율적인 로깅 로직 구현하기
·
스프링 부트/Java
이번에도 라인업지 서비스를 진행하면서 적용했던 기술적 도전을 간단하게나마 풀어보려 한다.매번 라인업지 서비스를 가져와서 '또 라인업지야?'라고 느끼실 수 있을 것 같다고 생각한다.하지만 그만큼 해당 프로젝트가 필자로 하여금 수많은 기술적 도전을 통해 한층 더 성장하게 만들어 주었기에, 다양한 문제를 해결하며 얻은 교훈과 성장의 흔적들을 여러 글에 걸쳐 정리해보려고 하는 것이니 이해해 주시면 정말 감사하겠다ㅎㅎ 🥹 그럼 각설하고, AOP 로깅을 적용하게 된 계기를 우선 말씀드리면서 시작하겠다. AOP 로깅의 적용 계기와 기존 로깅 로직의 한계점우리가 보통 로깅을 비즈니스 로직에 적용한다고 하면, @slf4j 어노테이션을 통해 비즈니스 로직에 다음과 같은 코드를 끼워 넣어 다음과 같이 구현한다. 해당 코드..
[JPA] 양방향 매핑을 지양해야 하는 이유
·
스프링 부트/Java
관습적으로 개발한 결과물무심코 스프링 부트와 JPA를 통해 개발을 하다 보면, 편리함에 녹아들어 테이블 간 연관관계를 막무가내로 설정하고는 한다.당장 본인도 그랬다..주로 양방향 매핑을 통해 개발하는 이유는 다음과 같다.개발의 편의성을 증진시키기 위해비즈니스 로직을 작성할 때, 양쪽 엔티티에서 원하는 객체를 쉽게 가져올 수 있어서물론 양방향 매핑을 통해, 개발하는 데 있어서 정말 많은 이점을 가져갈 수 있다고 생각했다. 특정 객체와 연관된 객체들을 손쉽게 가져온다거나, 단순 조회를 위해 여러 객체들을 가져올 때 덕분에 시간을 정말 아낄 수 있었다. 그러면 왜 그러한 이점을 버리면서까지 양방향 매핑을 지향한 걸까? 양방향 매핑이 가져다주는 문제점순환 참조만약 두 엔티티가 서로를 참조하게 될 경우, JSON..
스프링 이벤트와 비동기 처리를 통한 알림톡 발송 성능 개선하기
·
스프링 부트/Java
최근에 학교 축제의 주점 입장에 활용되는 원격 웨이팅 서비스를 개발하던 중, 사용자 입장에서 무척 아쉬운 문제를 발견했다. 바로 웨이팅을 신청하는 데 걸리는 시간이 평균적으로 2~3초 정도 걸린다는 것이 그 원인이었다.이를 스프링 이벤트와 비동기 처리를 통해 관심사를 분리시킴으로써 평균적으로 10~30ms 정도 소요되도록 개선하였다. 대략적으로 소요 시간을 약 100배 정도 개선한 것이다! 어떤 부분에서 해당 문제가 대두되었고, 이를 어떻게 해결하였는지 적어보려고 한다. 기존 로직의 문제점기존 로직은 웨이팅 신청, 그리고 알림톡 전송 로직이 강하게(분산 락을 통해) 결합되어 있는 상황이었다. 강하게 결합된 로직들은 단 하나의 로직이 실패하면 트랜잭션 자체가 롤백되어 정합성을 보장한다는 특징을 지닌다. 하..
커스텀 예외 처리를 @RestControllerAdvice를 통해 프런트에게 잘 전달하는 법
·
스프링 부트/Java
서버 로직을 개발하다 보면, 분명히 예외 처리를 해야 하는 순간이 다가오고는 한다.이때 우리는 대부분 커스텀 예외처리를 사용하고는 하는데, 필자가 작성한 코드를 참고하자면 다음과 같다.ServiceException.javaExtendedServiceException.java 근데 왜 굳이 이렇게 귀찮게 별도로 커스텀 예외처리를 우리가 따로 명시해주어야 하는 걸까? 커스텀 예외 처리를 사용하는 이유당연하게도, 스프링 부트는 기본적으로 예외가 발생하는 모든 부분에 대해 기본적인 예외 처리를 지원해 준다.그리고 이런 예외가 발생하면 대부분의 백엔드 개발자들은 디버깅과 구글링을 통해 문제의 원인을 파악하고, 예외 발생 지점을 특정 짔고, 고친다. 우리가 백엔드 개발을 희망하여 혼자 프로젝트를 공부하는 거라면, ..