Replication Lag?현대 많은 대규모 서비스들에선 단일 장애 포인트를 없애고 서비스에 일관된 수준의 빠른 응답을 보장하기 위해 데이터베이스를 Master-Slave 구조의 Replication 형태로 구축한다.서비스에서 발생하는 모든 데이터 변경 작업(CUD)을 Master 데이터베이스에서 처리하도록 하고, 처리완료된 데이터를 Slave 데이터베이스들에 싱크하는 구조이다. 위와 같은 구조를 통해 Master 데이터베이스 장애 시 Slave 데이터베이스를 통한 Failover 전략을 가능하게 하고, Slave 데이터베이스의 Scale Out을 통해 서비스 쿼리의 대부분을 차지하는 조회 작업을 일관된 품질로 제공할 수 있도록 해준다. 그러나 동시에 데이터의 일관성이 깨지는 케이스가 발생하기도 하는데..
그 외 공부
깃헙 이슈를 둘러보다가 재미있는 글을 발견했다.https://github.com/mockito/mockito/issues/1013 Enable mocking static methods in Mockito · Issue #1013 · mockito/mockitoStatic methods mocking with Mockito This is a placeholder ticket for enabling mocking static methods in Mockito. Example action items that are totally negotiable and can ran in parallel. We're look...github.com 해당 이슈는 2017년 3월 Mockito 깃헙에 올라온 이슈로 당시엔 Mo..
HTTP의 표준 메서드HTTP 표준 메서드를 하나씩 떠올려보자. 아마 대부분의 사람들이 GET, POST, PUT, PATCH, DELETE 이렇게 5가지 메서드를 생각할 것이다. (그 외에도 HEAD, OPTIONS 등..) 위 5가지 메서드들은 마치 일종의 불변상수와도 같아서 HTTP라는 녀석이 처음 세상에 나올때부터 함께 존재했던 것과 같은 착각을 불러일으킨다. 하지만 HTTP는 1990년대 초에 처음으로 명세되어 거진 30년이 가까운 시간동안 끊임없이 발전해왔고, 특히 PATCH 메서드는 비교적 최근인 2010년에야 RFC5789를 통해 HTTP의 표준 메서드로 채택되었다. HTTP 스펙 살펴보기 위 두 이미지는 순서대로 HTTP/1.0과 HTTP/1.1의 스펙에 명시된 Method Defini..
문제상황@TransactionalEventListner를 사용하는 코드에서 문제가 발생했다. 문제를 유발한 코드는 아래와 유사했다.@Service@RequiredArgsConstructorpublic class GroupService { private final GroupRepository groupRepository; private final ApplicationEventPublisher applicationEventPublisher; @Transactional public void deleteGroup(long groupId) { groupRepository.deleteById(groupId); applicationEventPubl..
문제 상황 Spring Batch를 공부하며 이것저것 시험해보던 중, 처음 보는 예외가 발생했다. Caused by: java.lang.IllegalArgumentException: Job name must be specified in case of multiple jobs 여러 개의 Job이 있을 때, Job name이 명시되어있어야한다는 메시지를 뿜었다. 처음엔 이게 Job 객체를 생성할 때 입력하는 name 파라미터에 관한 것이라고 생각하고, 뭔가 명시가 되지 않았거나 중복된 게 있는 것인지 확인했지만 그런 것은 없었다. 원인 원인은 구글링을 통해 쉽게 확인할 수 있었다. 해당 문제는 Spring Boot 3 버전에서부터 Spring Batch 사용 시 업데이트 된 내용 때문이었다. 해당 내용을 정..
서론 사내에서 나를 포함한 소수의 사람들에 의해 Spring Boot 3 버전대의 도입이 서서히 준비가 되면서, 관련 의존성이 있는 모듈 및 프로젝트 역시 새 버전과 호환시켜주는 작업이 필요했다. 사실 사내에서 유용하게 사용되고 있는 공통 모듈들은 우리 팀에서 만든 것들이 많았는데, 대부분 내가 직/간접적으로 참여했다거나 혹은 본인이 부트 3 버전 도입에 적극적으로 임한 것을 이유로 어쩌다보니 거의 대부분 내가 하고 있게 되었다. 😂 (물론 너무 좋은 경험이기도 하다) 정식 마이그레이션 가이드를 기반으로 연관있는 클래스들의 변경사항을 참고하여 작업을 진행했고, 와중에 놓친 것들이 있으면 발생하는 예외 로그를 통해 확인하면서 하나씩 고쳐갈 수 있었다. 하지만, 오류 발생 원인을 찾기 힘들었던 상황도 많았고..
문제 상황 사내 프로젝트의 스프링 부트 및 자바 버전을 업데이트하면서 Deprecated된 클래스들 또한 새롭게 업데이트하고 있었다. 그 중, Spring Security의 WebSecurityConfigurerAdpater가 스프링 부트 2.7 버전부터 Deprecated 되었고 이를 대신해 SecurityFilterChain을 사용하도록 권고했다. 교체하는 것 자체는 어렵지 않았다. 기존 WebSecurityConfigurerAdpater를 상속하는 것 대신 SecurityFilterChain 빈을 등록해주면 되는 형태였다. // 기존 @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override p..
문제상황 실서버에서 Deadlock이 발생했다는 리포트가 올라왔다. Deadlock found when trying to get lock; try restarting transaction 로그를 확인해보니 1초 이내의 짧은 시간 동안 동일한 벌크성 POST 요청이 두 번 연속으로 들어왔다. 아마 우리 서버를 사용 중인 모바일 UI상에서 따닥 두 번 클릭을 한 모양이다. 원인 분석 코드단에서 먼저 분석했을 때, 데드락을 유발한 코드는 아래와 같았다. public void updateMailboxId(String mailboxIdToUpdate, List mailNoList) { jpaQueryFactory.update(mail) .set(mail.mailbox.id, mailboxIdToUpdate) .w..