목록분류 전체보기 (102)
영호
들어가면서글로벌 캐시를 사용하다보니 분산환경에서 로컬캐시를 사용했을 때 어떻게 캐시 데이터 정합성을 맞출 수 있을지 고민해본 내용을 정리하려고 합니다. 실무에서 활용한 내용이 아닌 개인적으로 고민해본 내용이라 잘못된 부분이 있을 수 있습니다. 언제든지 댓글로 알려주시면 감사하겠습니다 ㅎ 글에서 다룰 내용로컬 캐시를 언제 활용할 수 있을지분산 환경에서 로컬 캐시의 정합성을 어떻게 맞출 수 있을지로컬 캐시를 언제 활용할 수 있을까저는 로컬캐시를 캐시 서버의 트래픽을 분산시킬 때 사용할 수 있을 것 같습니다. 혹은 조회 성능이 캐시 서버를 쓰는 것보다 빨라야 할 경우에 사용할 수 있을 것 같습니다. 데이터를 캐싱한다고 하면 redis 같은 별도의 캐시 서버를 많이 활용합니다. 하지만 글로벌 캐시만을 활용해 ..
들어가면서,최근에 같이 우테코를 수료한 지인과 각자 실무를 하면서 기본기를 다시 다지기 위해 Spring 스터디를 시작했습니다. 스터디원이 ConfigurationProperties 관련해 흥미로운 점을 알려줬고, 관련해서 조금 더 파본 내용을 간단하게 정리한 글입니다.실험을 진행한 환경은 Spring Boot 3.x 버전입니다. 궁금한 점꼭 설정 파일의 key 값과 java 코드의 필드명이 같아야 될까? HikariConfig 를 보면 maxPoolSize 란 필드가 있습니다. 그러나 설정파일 에서는 maximum-pool-size 키 값을 사용해 우리가 원하는 값을 주입 해줍니다. 즉, 설정 파일의 key 값과 자바 코드의 필드명이 달라도 매핑이 됩니다. 그래서 이를 확인해보기 위해 직접 코드를 쳐봤..
PR 링크: 링크들어가면서진행했던 프로젝트에서 이벤트를 기반으로 핵심 도메인 로직과 이에 따른 부가로직을 이벤트로 분리하였습니다. 그러나 기존의 구조에선 도메인 완료 이벤트에 따른 부가로직의 수행까진 보장하지 못합니다. 핵심 도메인 로직: 쿠폰에 스탬프 적립부가 로직: 스탬프 적립 시 방문 기록 저장기존 구조2번 과정(방문 기록 저장)이 실패하면 스탬프는 적립 되었지만 이에 해당하는 방문 기록이 없어져 데이터 정합성이 틀어집니다. 즉, 스탬프 적립 이벤트가 유실됩니다.문제 상황[도메인 로직 완료 이벤트 유실]위에서 설명했듯이 스탬프 적립 이벤트에 따른 부가기능을 수행하는 로직 실패 시 데이터 정합이 틀어지는 문제가 존재합니다. 스탬프 적립 시 부가로직은 스탬프 적립 알림, 방문 기록 추가 등이 있습니다..
멀티모듈로 분리한 이유 기존 프로젝트는 단일모듈로 구성되어 있어 코드 변경 시 전체 코드가 컴파일, 배포되는 구조입니다. 현재 프로젝트에서는 크게 2가지 영역이 있습니다. 주기적으로 외부 api 를 호출해 주차장 잔여 좌석을 갱신하는 스케줄러 spring mvc 를 활용한 어플리케이션 코드 스케줄러의 코드 변경은 어플리케이션 코드에 전혀 영향이 없습니다. 그러나 단일 모듈 구조에서는 스케줄러 코드가 변경되어도 전체 코드가 컴파일, 배포 됩니다. 현재 단일 모듈의 단점 스케줄러 코드의 변경으로 전혀 영향이 없는 어플리케이션 코드도 재배포 됩니다. 변경 주기가 다른 스케줄러, 어플리케이션 코드가 항상 같이 재배포되는 구조입니다. CI 속도가 불필요하게 오래 걸린다. 스케줄러 코드 변경으로 인해 전체 코드 테..
들어가면서 프로젝트를 진행하면서 인증코드를 redis 로 관리했습니다. 인증코드는 3분이란 유효시간이 있고 유효시간이 지난 인증코드로 인증 요청을 하면 실패해야 합니다. redis 는 메모리 기반이기 때문에 유효하지 않은 데이터는 제거하여 유효한 데이터만 저장하고 싶었기 때문에 만료된 인증코드를 어떻게 바로바로 제거할지 고민한 과정을 포스팅 할 예정입니다. redis 의 Set ex 파라미터 활용 redis 에는 다양한 command 가 있고, 그 중 key 를 저장하면서 만료시간을 설정할 수 있습니다. redis 의 ttl 만료된 키 삭제 메커니즘 redis 는 만료된 키를 삭제하는 2가지의 메커니즘이 있습니다. 만료된 key 접근 시 삭제 일정 주기로 ttl 이 설정된 키를 선정해 만료된 key 를 ..
들어가며,전에 참여했던 카페 쿠폰 서비스의 쿠폰에 스탬프를 적립하는 로직에서 동시성 이슈를 발견하여 이를 해결하기 위해 고민한 과정을 정리하려고 합니다.현재 문제점방어로직이 없다스탬프 적립 요청 시 {어느 쿠폰}에 {몇 개의 스탬프}를 적립 할지, 인증 토큰에 대한 인자만 받고 있습니다. 이로 인해, 네트워크 지연 등에 대한 재시도로 인해 동일한 쿠폰에 대한 스탬프 적립 요청이 2번 들어오면 2배의 스탬프가 적립됩니다. 즉, 중복 적립 문제가 발생합니다.기존 API 대략적인 구조POST coupon/{couponId} BODY int: stampCount원하는 결과흔히 말하는 동시성, 따닥 이슈 발생 시 하나의 요청만 유효하게 처리하길 원했습니다. 이를 만족하기 위해 어떤 고민을 했는지 작성해보겠습니다..
들어가면서 이전 포스팅에서 구현한 namedLock 에 이어서 multi-datasource 와 AOP 를 적용하는 과정에 대해 적어보겠습니다. 전체 코드 github입니다. Multi-datasource 가 필요한 이유 namedLock 을 얻는 datasource 와 다른 비즈니스 로직을 수행하기 위한 datasource가 동일한 경우 커넥션이 부족할 수 있습니다. 만약, namedLock 을 얻으려는 요청이 갑자기 몰린다고 생각해봅시다. 그러면 해당 요청에 할당된 커넥션은namedLock 을 얻기 위해 기다릴 것입니다. 물론 timeout 을 설정해서 대기 시간을 조절할 수 있지만, 해당 시간 동안 비즈니스 로직 수행에 필요한 커넥션을 사용한다는 사실은 변하지 않습니다. 이러한 이유로 namedLo..
들어가면서 분산서버에서 발생하는 동시성 문제를 어떻게 해결할 수 있을까 고민하다가 namedLock 이란 개념에 대해 알게되어 이를 간단하게 구현해본 과정을 정리하려고 합니다. 혹시 잘못된 부분 있으면 언제든지 댓글 달아주시면 감사하겠습니다~ 전체코드 주소입니다. 다음 포스팅 (AOP, multi-datasource 적용) 예제 상황 수강신청 상황을 예제로 사용할 예정입니다. 정원이 있는 강의에 여러 명의 사용자가 수강신청 요청을 보낼 때, 강의 정원 만큼만 수강신청이 가능한 상황입니다. 물론 수강신청은 순서도 중요하지만 이번 포스팅에선 동시성 제어에만 초점을 맞춰주시면 감사하겠습니다. Lecture 는 강의 엔티티이고 강의 정원 (restCount) 필드를 가지고 있습니다. LectureStudent ..