문제멀티 모듈 구조에서 JpaRepository 빈을 읽어오지 못하는 문제가 있었다. 상황우리는 멀티 모듈을 채택했고, 스프링 앱, 도메인 코어, 데이터베이스 모듈로 3개를 분리했다. 스프링 앱에서 실행 시, 데이터베이스 모듈의 JpaConfig 설정을 읽어오지 못해서 도메인 코어의 repository에 JpaRepository를 빈이 없다고 주입을 못해주고 있었다. 간단하게 현제 문제인 것들만 정리하자면모듈payment-core : 결제 도메인의 핵심 부분 (서비스, 도메인, 리포지토리 포함)모듈 위치 : service:payment:core 패키지 시작점 : radiata.service.payment.corepayment-api : 결제 도메인의 외부 요청 부분 (스프링 애플리케이션, 컨트롤러, ..
Til
복제 가용성은 일정 기간 동안 서비스를 정상적으로 사용할 수 있는 시간의 비율을 뜻한다. 레디스에서 고가용성을 확보하기 위해서는 아래의 두 가지 기능이 필요하다. 복제 : 마스터 노드의 데이터를 복제본 노드로 실시간 복사하는 기능이다. 마스터 노드의 서버에 장애가 생겨 데이터가 유실되어도 복제본 노드에서 데이터를 확인할 수 있다. 자동 페일오버 : 마스터 노드에서 발생한 장애를 감지해 레디스로 들어오는 클라이언트 연결을 자동으로 복제본 노드로 리디렉션하는 기능이다. 이를 통해 자동으로 엔드포인트를 변경하여 빠른 장애 조치가 가능하다. 레디스에서의 복제 구조 서비스에서 복제본 노드를 추가하는 이유는 다음과 같다. 애플리케이션을 실행하는 하드웨어는 언제든지 고장날 수 있기 때문에, 마스터 DB가 다운됐을 때..
캐시란? 데이터의 원본보다 더 빠르고 효율적으로 접근할 수 있는 임시 데이터 저장소. 아래의 조건을 만족시킨다면 캐시를 도입했을 때 성능을 효과적으로 개선할 수 있다. 원본 DB에서 원하는 데이터를 찾기 위해 검색하는 시간이 오래 걸리거나, 매번 계산을 통해 가져온다. 캐시에서 데이터를 가져오는 것이 원본 DB의 데이터를 요청하는 것보다 빠르다. 캐시에 저장된 데이터는 잘 변하지 않는다. 캐시에 저장된 데이터는 자주 검색되는 데이터다. 캐시로서의 레디스 사용이 간단하다. 단순 키-값 형태로 저장하고, 다양한 자료 구조를 제공한다. 인메모리 데이터 저장소여서 데이터 접근 시간이 빠르다. 평균 읽기 및 쓰기 작업 속도가 1ms 미만이다. 자체적으로 고가용성 기능인 센티널 또는 클러스터를 제공한다. 캐싱 전략..
1. 일관된 데이터 모델링 - 정규화를 적용하여 중복을 최소화 하여 데이터 무결성을 유지 2. 비즈니스 로직 분리 - 데이터베이스에 직접적인 비즈니스 로직을 내장하는 것을 피하고, 서비스나 애플리케이션 레이어에서 비즈니스 로직을 처리 3. 조회 최적화 - 필요한 데이터만 조회하고, JOIN 등 복잡한 연산 최소화. 필요한 데이터를 미리 계산하여 캐싱하거나, 뷰를 활용하여 미리 계산된 결과 조회 4. 인덱스 활용 - 필요한 칼럼에 인덱스를 생성하여 검색 성능 향상, but 과도한 인덱스 생성은 쓰기 성능에 부정적 영향 끼칠 수 있음 5. 쿼리 캐싱 - 자주 사용되는 쿼리 결과를 캐시하여 반복 실행 줄이고 성능 향상 6. 트랜잭션 사용 최소화 - 트랜잭션은 데이터 일관성과 무결성을 유지하기 위해 필요하지만,..
@Configuration public class RedisConfig { @Value("${spring.data.redis.host}") private String host; @Value("${spring.data.redis.port}") private Integer port; @Bean public RedisConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(host, port); } @Bean public RedisTemplate redisTemplate() { RedisTemplate redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFact..
문제 스프링 시큐리티로 API 인가 설정 중, /api/boards/best 는 권한 검증 없이 전부 볼 수 있지만, api/boards/{id} 는 검증을 해야하는 상황에서, new AntPathRequestMatcher("/api/boards/best", HttpMethod.GET.name()) new AntPathRequestMatcher("/api/boards/{id}", HttpMethod.GET.name()) 위의 두 API에서 best 와 {id}를 구별하지 못하는 문제가 있었다. 해결 스프링 시큐리티는 정규표현식으로도 매칭을 할 수 있는 클래스를 제공한다. new AntPathRequestMatcher("/api/boards/best", HttpMethod.GET.name()) new Re..
팀 노션 회의록 및 기록 보관소 및 5분 기록 보드에 적어놓고 정작 TIL에는 제출하지 못한 내용을 적어본다.. 문제 RDS의 시간대가 기본값으로 UTC+0이어서 (EC2에는 Asia/Seoul 설정이 되어 있음) DB에 UTC+0 시간으로 삽입됨. 해결 우선 AWS RDS로 가서, 파라미터 그룹 생성을 클릭 후 MySQL 8.0을 선택하고 이름은 자유롭게 지은 뒤 생성. 다음으로 생성한 파라미터 그룹으로 들어가서 time_zone 파라미터의 값을 Asia/Seoul 로 수정. 그 다음으로, DB 인스턴스로 들어가서 편집 -> 추가 구성 -> 데이터베이스 옵션 중 DB 파라미터 그룹을 위의 파라미터 그룹으로 변경 이후 재부팅을 해주면 적용이 되는 것을 볼 수 있다. (설정 변경하고 즉시 적용하더라도, 재..
오늘은 주간 멘토링을 받았다. 오전 10시 10분에 받는 거였는데 팀원 한 분이 오전 6시까지 작업하시다가 졸아서.. 하마터면 멘토링 늦을 뻔했다 ㅋㅋ 멘토링을 고봉밥으로 받아서, 정리를 한다고 했는데 한번 더 정리를 해야할 것 같다. 크게 정리하면, 아키텍처 구상도 다시 하고, 기술 면접 준비를 잘 하자.. 이다 ㅋㅋ 우선 스프링 배치를 쓴다고 하니, 배치와 스케쥴링의 차이를 물어보셨다. 이건 단골 질문이니 알고 있었고, 정리를 하자면 배치는 특정 시점에 일괄 데이터를 처리하는 작업이고, 스케쥴링은 매 주기마다 특정 작업을 실행하는 작업이다. 또 팀원분이 스프링 쿼츠랑 스프링 배치에 대해 어느 것을 쓰는 지를 여쭤봤었는데, 스프링 배치라 쿼츠를 흡수하여 현재는 스프링 배치 라이브러리를 다운받으면 쿼츠도..
리액트 작업을 하다가 useEffect 의 deps 를 [] 로 설정했음에도, 함수 부분이 2번 실행되는 문제가 있었다. 코드는 다음과 같다. function BuyPage () { const navigate = useNavigate() const { productId } = useParams() const { state } = useLocation() const { nickname } = useUserInfoStore() useEffect(() => { if (state === null) { navigate(`/products/${productId}`) } }, []) useEffect(() => { if (nickname === '') { alert('로그인 후 접근 가능합니다.') navigate(..