본문 바로가기

분류 전체보기

(332)
[끄적끄적] 결제 중복 롤백 방지하기 현재 진행중인 프로젝트에서는 분산환경에서 데이터 정합성을 맞추기 위해, 유저의 결제로직이 중간에 실패할경우, 보상트랜잭션을 발행하도록 구성되어 있는데요. 이때, 보상트랜잭션 처리중 메시지가 유실되면 해당 메시지를 일정 시간후에 재처리 하게 됩니다. 주문의 상태를 "FAILED" 처럼 바꾸는 멱등한 API의 경우 메시지를 재처리해도 문제가 되지 않습니다. 그러나, "유저가 결제한 포인트를 복구" 하는것과 같이 멱등하지 않은 API는 유저에게 포인트가 중복해서 더해질 수 있으므로 재처리 과정중 멱등성을 보장해줘야 합니다. 실제로, 주문 - 결제 로직을 spike test 해보면, 아래 사진과 같이 (서버 다운 등의 이유로) 유실된 메시지를 재처리하게 되어서, 유저가 원래 갖고있던 1000 포인트 보다 더 많..
[Reactive stack] Reactor pool로 Lettuce Connection 조절하기 프로젝트에서 pool(커넥션 풀 같은..)을 직접 구현해줘야할 일이 생겼습니다. GitHub - rooftop-MSA/Netx: Distributed transaction and Event streaming framework based on saga pattern / Supports redis-stream / Distributed transaction and Event streaming framework based on saga pattern / Supports redis-stream / Fully async - rooftop-MSA/Netx github.com 하지만, 프로젝트가 Reactor기반으로 되어 있었기 때문에.. pooling되고있는 리소스를 획득하기 위해서 스레드가 블로킹 되면 안되는 상황..
[끄적끄적] @Transactional 안에서 retry 사용을 주의하세요 TL;DR이것외에도, 트랜잭션 안에서 retry를 할 경우 여러가지 문제가 발생할 수 있는데요. 저와 마찬가지로 jitter 방식의 retry정책을 구현할 경우, 해당 스레드는 커넥션을 든채 jitter 시간만큼 대기하게됩니다. 즉, 동시성 처리에 안좋은 영향을 끼칠 수 있어요. (이것은 Webflux와 같은 reactive 프로그래밍에서도 마찬가지입니다. 비동기환경에서도 context에 커넥션이 묶인채로 jitter시간동안 대기하게되어요.) 반면, retry로직을 로컬 트랜잭션 밖으로 빼줄경우, 해당 이벤트가 jitter 만큼 대기할때, 다른 이벤트가 커넥션을 재사용할 수 있다는 이점이 있습니다. 또한, MySQL InnoDB의 Isolation level을 REPEATABLE READ 이상으로 설정할..
[Reactive Stack] webflux, R2DBC 환경에서 Event 사용하기 최근 webflux + R2DBC 스택으로 되어있는 프로젝트에서 스프링 Event를 사용할일이 있었습니다. MVC + JPA 환경에서는 어렵지 않게 사용하던 이벤트를 webflux + R2DBC 환경에서 사용하려고 하니까, 많은 부분이 생각대로 동작하지 않더라구요. reactor는 lazy하게(최종 호출 메소드가 나오기전까지 실행되지 않음) 실행된다는 특징 때문에, Event 호출에서 고려해야 할 부분이 좀 있었습니다. R2DBC와 Webflux에 대한 이해가 있지 않으면 실수 할 수 있는 부분이 있다고 생각이 들어서, 케이스 별로 테스트를 해봤습니다.시나리오 설명시나리오는 간단한데, PayRollbackEvent가 발행되면, 저장된 payment를 찾아서 state를 PaymentState.FAILED..
[끄적끄적] ProtocolBuffer로 API 문서 작성기 최근에, 강남언니 기술블로그에 기술된 글을 재미있게 본 적이 있습니다. 강남언니 블로그에서는, 프론트엔드와 백엔드 간의 api를 protocol buffer로 정의 하면서 아래와 같은 이점을 얻을 수 있었다고 합니다. 1. API 문서를 유지보수하지 않아도 되게 되었습니다. 기존에는 api가 변경되면, api 문서도 업데이트 해줘야했는데, protocol buffer로 관리하면서, api 변경이 곧 문서의 변경으로 바로 이어졌습니다. 2. 단일 진실 공급원(Single Source Of Truth) 환경이 구축됩니다. 프론트엔드와 백엔드가 각각 똑같은 IDL(protocol buffer) 를 공유하면서, 휴먼에러가 발생할 확률이 줄어듭니다. 저 또한 이런 이점에 공감해, 새롭게 진행하고 있는 프로젝트에 ..
[Reactive stack] MVC에서 WebTestClient로 테스트 하기 최근 프로젝트를 webflux 환경에서 진행하면서, Restassured나 MockMVC 이외의 WebTestClient를 사용해서 테스트를 해보았습니다. 이미, WebClient를 사용하고 있어서 인지 WebTestClient가 Restassured와 MockMvc보다 직관적으로 느껴졌고 좋은 기억으로 남아있어서 다른 (MVC기반)프로젝트에서도 WebTestClient로 테스트를 해보고자 했습니다. TL;DR MVC에서 WebTestClient를 사용하는데는 성공했습니다. 하지만, WebTestClient는 Interceptor와 같은 MVC의 구성요소를 사용하기 힘듭니다. (Webflux에는 interceptor가 없어요.) 추가적으로, 자동구성이 아니라면기본적으로 등록되는 resolver (Page..
[Reactive Stack] R2DBC 연관관계 재가공하고 내용을 추가한 글 을 미디엄 에서 읽어 보실 수 있습니다. https://medium.com/@develxb/how-to-relation-entity-on-r2dbc-72e7dd4acdb2 기술 스택 r2dbc의 경우 드라이버에 따라 동작방식이 다른경우가 있습니다. 연관관계의 경우 spring 추상화 기술을 통해서 동작하기 때문에 이런 문제가 발생하지는 않을것 같지만, 같은 데이터베이스를 사용하더라도 다른 드라이버를 사용하는 경우가 있어서.. 시작전에 이 포스팅에서 사용한 기술스택과 버전을 정의하도록 하겠습니다. spring data r2dbc version: 3.1.1 JDK version: 21 Database: H2(테스트), MySQL(운영) R2DBC Driver: io.r2dbc:r..
[Reactive stack] Spring data R2DBC 커넥션 유지 방법 재 가공한 글을 medium에서도 읽을 수 있습니다. 이전 글 https://dlwnsdud205.tistory.com/359 을 읽고오시면 더 이해하기 쉽습니다. [Reactive stack] R2DBC with mysql 삽질기 최근 진행하고있는 프로젝트를 MVC에서 Web flux로 변경함에 따라 DB 통신기술또한 비동기로 변경해야 했습니다. 때문에, 더이상 Spring data jpa 를 사용할 수 없었고 Database와 비동기로 통신할 수 있는 dlwnsdud205.tistory.com webflux와 spring data r2dbc 를 사용하면서 다음과 같은 의문이 들었습니다. 스프링 문서에는 R2DBC에서도 선언적 트랜잭션을 지원한다고 나와있는데, webflux에서 이게 어떻게 가능한거지?..