기록하며 성장한다 - 개발, 회고

개발 회고록 20

[ 개발 회고록 ] 조회 성능을 높이기 위해선 어떻게 해야 할까

서론 필자가 만들던 Food-Delivery 프로젝트가 마무리되었고, 나의 코드를 돌아보다보니 문득 조회 성능에 대한 생각이 들었다. 한 번에 여러 스레드의 접근을 통한 조회 성능은 테스트 해보았지만, 데이터가 수백 수천만개가 있을 경우 조회성능이 어떨까를 고민하게 되었다. 특히, 필자는 Redis 로 캐싱을 하는 방식으로 조회 성능을 올리는 방법을 택하였는데, 페이징 처리를 해줘야하는 서비스라면 이걸 또 어떻게 하는 것이 좋을까를 고민하게 되었다. 이를 해결하기 위해서는 큰 수정이 필요하고, 이미 프로젝트가 마무리 되었기 때문에, 우선 개별적으로 조회 성능에 대하여 코드를 만들어봐야겠다는 생각이 들었다. ( 물론 추후 프로젝트 전체를 한 번 고쳐 볼 예정이다. ) 필자가 기존에 만들었던 프로젝트 : h..

개발 회고록 2024.01.31

[ 개발 회고록 ] Redis 와 @Cacheable 을 적용하여 응답속도 개선하기 ( + Redis keys 대신 scan 을 사용하는 이유 )

서론 현재 배달과 관련 된 토이프로젝트를 진행하고 있다. 토이 프로젝트 링크 { String awsImagePathURL = fileService.getFilePath(store.getImageFileName()); return StoreResponse.toStoreResponse(store, awsImagePathURL); }) .toList(); } 아래와 같이 Redis 에 캐싱된 내용이 저장된다. 4. [참고] key 값을 조회할 때 Keys 말고 Scan 을 사용하는 이유 필자는 로그아웃을 할 경우, 해당 memberId 로 만들어진 모든 캐싱 데이터를 삭제하는 로직을 만들었다. 이 때 Key 값들을 가져와야 되는데, 처음에는 아래와 같은 코드를 만들었다. public void evictCach..

개발 회고록 2024.01.24

[ 개발 회고록 ] 공통 인프라 로직인, 로그인 확인 기능을 AOP로 분리하기

아, 로그인 체크 로직이.. 너무 중복되서 들어가는데.. 유지보수도 힘들고, 가독성도 안좋네.. 방법이 없나...? 서론 현재 배달과 관련 된 토이프로젝트를 진행하고 있다. 토이 프로젝트 링크 checkMemberLevel(currentMember, MemberLevel.RIDER); } } private Member getCurrentMember() throws HttpClientErrorException { Member member = loginService.getCurrentMember(); if (member == null) { throw new HttpClientErrorException(HttpStatus.UNAUTHORIZED); } return member; } private void ch..

개발 회고록 2024.01.24

[ 개발 회고록 ] Self - Invocation 에 대한 간단한 이야기

서론 현재 배달과 관련 된 토이프로젝트를 진행하고 있다. 토이 프로젝트 링크 Transaction 정리 2. 해결 방법 사실 AspectJ 나, 클래스 내 로직을 AOP로 완전히 묶는 방법등이 있지만, 둘 다 추천하는 방식은 아니다. 그래서 제일 좋은건 Self-Invocaton 이 발생하는 경우 자체를 막는 것이다. 그래서 필자는 OrderTransactionService 라는 별도의 서비스 클래스를 만들었고, 위의 order 나 payment 와 같은 메서드를 해당 서비스로 분리해내었다. @Service public class OrderService { // ... @Transactional public void registerOrder() { orderTransactionService.order()..

개발 회고록 2024.01.23

[ 개발 회고록 ] Redis INCR 를 활용하여 선착순 쿠폰 발급 기능 만들기

쿠폰은 100개인데, 왜 104명한테 발급이 됐지...??? 서론 현재 배달과 관련 된 토이프로젝트를 진행하고 있다. 토이 프로젝트 링크 capacity.getDescription() ) { throw new ApiException(COUPON_END); } try { Coupon coupon = Coupon.builder() .memberId(memberId) .couponType(couponType) .status(Status.DEFAULT) .expireDateTime(LocalDateTime.now().plusYears(1)) // 쿠폰은 발급 후 1년 안에 사용해야 하는 정책이 있는 거로 설계. .build(); couponRepository.save(coupon); } @Repository @..

개발 회고록 2024.01.23