
Reactive StreamsThe purpose of Reactive Streams is to provide a standard for asynchronous stream processing with non-blocking backpressure.출처: reactive-stream-jvm githubReactive Streams는 비동기 데이터 스트림을 Non-blocking 방식으로 처리하면서, 백프레셔(Backpressure)를 지원하는 표준으로 Publisher는 Subscriber에게 비동기적으로 이벤트를 전달한다. Reactive Streams를 구현한 구현체로 RxJava, Reactor, Akka Streams, Java 9 Flow API 등이 있다. Reactive Streams 구성 ..

DispatcherServlet vs DispatcherHandlerDispatcherServlet에서 Spring MVC의 핵심 구성 요소로 HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아 적합한 컨트롤러에 위임해주는 프론트 컨트롤러(Front Controller) 패턴을 기반으로 동작하는 서블릿이다. 그러면 DispatcherHandler는 무엇일까? DispatcherHandler는 Spring WebFlux에서 DispatcherServlet처럼 요청을 처리하는 역할을 하는 비동기(reactive) 프론트 컨트롤러이다. 둘을 자세히 비교해보자. DispatcherServletDispatcherServlet도 부모 클래스에서 HttpServlet을 상속받아서 사용하고, 모든 경로(urlP..

NettyNetty는 비동기 이벤트 기반 네트워크 애플리케이션 프레임워크로 고성능의 네트워크 프로그래밍을 지원하기 위해 이벤트를 활용해 비동기적으로 최소한의 리소스로 많은 연결을 처리할 수 있다. Spring 5.0에서 도입된 리액티브 프로그래밍 모델을 기반으로 동작하는 Spring WebFlux도 서버 구현을 위한 다양한 옵션을 제공하지만, Netty를 기본적으로 사용하는 서버 엔진이다.Netty가 어떻게 이벤트 루프를 통해 각 I/O 작업(예: HTTP 요청, 응답)을 비동기적으로 처리하는지 알아보자. Blocking I/O vs Non-Blocking I/O네티는 Java NIO 기반의 고성능 네트워크 프레임워크이다. Java NIO의 Channel과 Selector를 사용하여 비동기, 논블로킹을 ..

JPA회사에서 Spring Data JPA와 QueryDSL을 사용하고 있다... Spring Data JPA와 QueryDSL을 공부하기 전 JPA에 대해 알아보고자 한다. MyBatis와 달리 JPA이 무엇이고, JPA를 사용함으로써 얻을 수 있는 장점과 사용 시 주의사항들에 대해서 살펴보자. SQL 중심적인 개발의 문제점과 대안자바를 사용하는 이유 중 하나인 객체 지향 프로그래밍은 추상화, 캡슐화, 정보은닉, 상속, 다형성 등 시스템의 복잡성을 제어할 수 있는 다양한 장치들을 제공하여 객체 모델링으로 저장할 수 있다. 하지만 MyBatis와 같은 SQL 중심의 개발은 SELECT, INSERT, UPDATE, DELETE의 무한 반복과 위 사진처럼 객체의 필드가 테이블에 맞추어 모델링되므로 의존적이..

nGrinder를 사용한 성능 테스트: 비관적 락 vs 분산 락 분산 환경에서는 비관적 락과 분산 락의 성능이 비교해보려고 한다. 비관적 락과 분산 락 비즈니스 로직 성능 테스트를 위해 두 비즈니스 로직을 똑같게 만들기 위해서 상품을 조회한 후 재고를 차감할 후 있는지 확인한 후 가능하다면 재고를 차감시킬 수 있도록 구현했다. 비관적 락과 분산 락 로직 차이 SELECT * FROM product WHERE id = #{id} SELECT * FROM product WHERE id = #{id} FOR UPDATE 가장 먼저, 상품을 조회했을 때 비관적 락은 SELECT ... FOR UPDATE를 통해서 조회한 레코드에 대해 배타락을 획득하는 반면, 분산 락은 애플리케이션 단에서 락을 획득하고 반납하기..

MySQL Replication 데이터베이스를 사용하고 운영할 때 가장 중요한 두 가지 요소는 확장성(Scalability)과 가용성(Availability)이다. 이 두 가지 요소를 위해 가장 일반적으로 사용되는 기술인 MySQL 복제는 소스 서버의 데이터를 하나 이상의 레플리카 서버로 복제하여 읽기 작업을 분산시켜 성능을 향상시키는 것을 말한다. 원본 데이터를 가진 서버를 소스(Source) 서버, 복제된 데이터를 가지는 서버를 레플리카(Replica) 서버라고 부른다. 소스 서버에서 데이터 및 스키마에 대한 변경이 최초로 발생하며, 레플리카 서버에서는 이러한 변경 내역을 소스 서버로부터 전달받아 자신이 가지고 있는 데이터에 반영함으로써 소스 서버에 저장된 데이터와 동기화시킨다. 복제 장점 복제를 통..

분산 락 사용 시 상위 트랜잭션이 있으면 안되는 이유 주문 기능 중 재고 차감을 데이터 정합성을 위해 비관적 락으로 먼저 구현하고, 다음으로 Redisson을 사용하여 분산 락으로 구현하려고 했지만 주문 트랜잭션에서 상위 트랜잭션이 있는 경우에는 적용하지 못해 그 이유에 대해 작성해보고자 한다. Redisson을 사용한 분산 락 Redisson은 pub/sub 기반으로 Lock 구현을 제공한다. 채널을 하나 만들고 Lock을 점유중인 스레드가 Lock을 획득하려고 하는 스레드들에게 해제를 알려주고 안내를 받은 스레드가 Lock 획득 시도하는 방식으로 스핀락을 통해 계속해서 락을 획득할 수 있는지 요청해야 하는 Lettuce의 경우보다 부하를 덜 줄 수 있다. boolean tryLock(long wait..

페이징 성능 개선: offset vs no offset vs covering index 웹 서비스에서 페이징은 아주 흔하게 사용되는 기능이다. 일반적으로 페이징은 구현한다면 LIMIT ... OFFSET ...; 와 같은 패턴으로 OFFSET을 사용하는데 이는 점차 데이터가 많아짐에 따라 수십초 ~ 수분까지 조회가 느려질 수도 있다. 따라서 No offset과 Covering index를 통해서 페이징 기능을 개선하는 방법에 대해서 살펴보자. product 테이블에 대략 1,572만 건 상품 데이터가 있다. OFFSET LIMIT 쿼리는 결과에서 지정된 순서에 위치한 레코드만 가져오고자 할 때 사용된다. 위 쿼리는 다음과 같은 순서로 실행된다. ORDER BY id DESC: 일반적으로 최신에서 과거순으..

synchronized vs Pessimistic Lock vs Distributed Lock DB의 무결성을 보장하기 위해서는 다양한 방법이 있다. 물론 synchronized는 적합한 방법은 아니지만 왜 적합하지 않은지에 대해 살펴보고, 그 뒤 비관적 락(Pessimistic Lock)과 분산락(Distributed Lock)을 통해 성능 비교를 해보자. 재고 차감 로직을 통한 DB 부정합 문제 살펴보기 위 ProductService는 주문 관련 비즈니스 로직 중 하나로 "상품 조회 -> 상품의 재고 차감 가능 여부 확인 -> 재고 차감"의 순서로 이루어지는 로직이다. 해당 비즈니스 로직을 통해서 어떻게 DB 부정합 문제가 발생하게 되는지 테스트 코드를 작성해보자. 위 테스트 코드는 한 번에 100개..
- Total
- Today
- Yesterday
- spring session
- mdcfilter
- mono flux
- socket
- 구름톤챌린지
- 구름톤 챌린지
- redis session
- 리액티브 스트림즈
- 카프카
- transaction
- spring webflux
- nginx configuration
- Kafka
- postgresql
- sql
- nginx
- 웹플럭스 리액터
- jvm 메모리 구조
- 람다
- 분산 락
- TDD
- mysql
- Synchronized
- 비관적 락
- Java
- annotation
- pessimistic lock
- NeXTSTEP
- 넥스트스탭
- 트랜잭션
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |