1. 스프링 @Transactional의 동작 방식에 대해 완벽하게 이해하기 [ parallelStream에서 @Transactional을 사용하는 예제 코드 ] 다음과 같은 간단한 JPA 엔티티가 있다. @Entity @Getter @NoArgsConstructor public class MyEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; private String name; public MyEntity(String name) { this.name = name; } } 그리고 해당 엔티티를 저장하는 서비스 계층에서 조건에 따라 런타임 예외를 던진다고 하자. @Service @Transactional(rea..
1. @PathVariable 또는 @RequestParam 등의 값을 변환하여 받기 (암호화된 @PathVaraible 값 복호화) [ 컨트롤러에서 받는 값 변환의 필요성 ] 애플리케이션을 개발하다 보면 리소스에 대한 고유한 값인 식별자(identifier)을 받아 요청을 처리하는 경우가 있다. 리소스의 식별자는 시스템 내부 정보이므로, 해당 값이 1씩 단순 증가하는 값이라면 암/복호화를 해서 사용해야 한다. 예를 들어 다음과 같이 특정 멤버의 포인트를 증가시키는 API가 있다고 하자. 이때 PathVariable로 받는 memberId 값은 암호화되어 있기 때문에 컨트롤러 혹은 이를 사용하는 하위 계층에 복호화 로직을 넣어주어야 한다. @RestController @RequiredArgsConstru..
1. 분산락의 필요성과 레디스의 분산락(RedLock) [ 분산락의 필요성 ] 분산 환경에서는 서로 다른 클라이언트가 공유 리소스를 사용하는 경우가 많이 있다. 기본적으로 레디스(Redis)는 싱글 스레드로 동작하기 때문에, 단일 레디스 노드를 구축해 사용해도 동시성 문제가 발생하지 않는다. 따라서 리소스에 대해 값을 설정하여, 값이 설정된 경우에는 다른 리소스의 접근을 차단할 수 있다. 이를 잠금이라고 표현할 것이며, 이를 위해 다음과 같은 명령을 사용할 수 있다. // key, value를 저장하는데 NotExists일 경우에만 저장하고, 30초(30000ms) 동안 유지해줘 SET key value NX PX 30000 리소스에 대한 잠금을 해제하는 것은 다음의 명령으로 가능하다. DEL key 하..
이번에는 서비스 메시(Service Mesh)가 무엇인지 알아보고, 서비스 메시가 갖는 문제와 이를 해결하기 위한 쿠버네티스(Kubernetes)의 SidecarContainers에 대해 알아보도록 하겠습니다. 1. 서비스 메시(Service Mesh)의 등장 [ MSA와 함께 부각되는 인프라 문제들 ] 기존의 모놀로식(Monolithic)에서 마이크로서비스 아키텍처(MicroService Architecture)로 전환하면서 많은 변화가 생겼다. 특히 기존에는 겪지 않았던 인프라와 관련된 문제(특히 네트워크)들이 더욱 중요해졌다. Client-side load balancing: 호출 가능한 엔드포인트 목록을 클라이언트에게 주고, 직접 결정하도록 함 Service discovery: 정상 상태인 서비스..
1. 가상 스레드의 도입 배경 [ 기존 자바 스레드 모델의 문제와 한계 ] 자바 개발자들은 약 30년 동안 서버 애플리케이션의 동시성 처리를 위해 스레드를 사용해왔다. 대표적으로 스프링 프레임워크는 멀티 스레드 모델을 사용하고 있으며, 1개의 요청을 1개의 스레드가 처리하는 thread-per-request 방식으로 동작하고 있다. 따라서 동시 요청이 많다면 스레드의 수 역시 증가해야만 이에 대응할 수 있다. 하지만 기존 JDK의 스레드는 운영 체제(OS) 스레드의 Wrapper이기 때문에, 사용 가능한 스레드의 수가 하드웨어 수준보다 훨씬 적게 제한되어 있었다. OS 스레드는 비용이 높아 요청량에 비례하여 늘릴 수 없기 때문이다. 가질 수 있는 스레드의 양은 제한적인데, 자바 스레드는 OS 스레드의 W..