# spring webflux
transactional operator 커스텀해서 사용하기
Intro 개발을 하다보면 여러가지 문제를 마주칠 때가 많다. 그리고 내가 겪는 대부분의 문제들은 누군가 이미 겪었을 확률이 99% 이기에 검색만 해봐도 대부분의 문제를 금방 해결할 수 있다. 예를 들어 티켓팅, 좌석예매, 선착순 이벤트 등 굉장히 유명한 문제에 대해서는 다양한 상황에 대해 다양한 해결방법들을 조언해준다. ex... 만약 비슷한 문제를 마주하게 되고 충분히 적용가능한 상황이라면 누군가가 만들어 놓은 정답을 그대로 사용하는 것이 나쁘다고 생각하지 않는다. (물론 기술적인 고민을 충분히 한 상태에서) 하지만 이번에 내가 겪은 문제, 그리고 내가 원하는 것은 검색을 하기에도 애매했고 뭔가 맘에 드는 방법들이 딱히 없었다. 이 글은 굉장히 애매한 상황에 대해 해결한 방법에 대해 작성한 글이다. 문제 total_count 라는 필드를 가지고있는 테이블이 있다고 쳐보자. default 값은 0이다. 멀티쓰레드 환경에서 여러 트랜잭션이 total_count의
리액티브, 리액티브 시스템, 리액티브 프로그래밍, 리액티브 스트림즈......?! #1
Overview Spring Webflux에 대해 제대로 이해하고자 합니다. 스프링 웹플럭스가 그렇게 좋다던데,, 빠르다던데,, 언제나 Spring MVC보다 절대적으로 좋을까요? Spring Webflux 를 제대로 알고 사용하려면 왜 쓰는지를 알아야한다고 생각합니다. 자바 언어를 이용하여 Spring Webflux를 사용하고자 한다면 리액티브라는 키워드를 접하게 되며 대표적인 리액티브 스트림즈 구현체인Reactor를 사용하게 됩니다. 오늘은 스프링 웹플럭스를 제대로 알아보고자 먼저 명령형 프로그래밍 선언형 프로그래밍, 함수형 프로그래밍, 리액티브 프로그래밍, 리액티브 시스템 등 헷갈리는 용어를 정리해보려고 합니다. 1. 명령형 프로그래밍 / 선언형 프로그래밍 차이 자바는 객체지향 프로그래밍 언어로 대표적인 명령형 프로그래밍의 일종입니다. 명령형 프로그래밍이란 프로그램의 상태와 상태를 변경시키는 구문의 관점에서 연산을 설명하는 프로그래밍
Spring Web vs Spring Webflux
Spring Web : Servlet API 위에 만들어진 웹 프레임워크 blocking I/O synchronous communication 낮은 동시성을 요구하는 소규모 어플리케이션 응답을 받을 때까지 스레드가 막혀, CPU/메모리 사용량이 높다. Spring Webflux : Reactive Streams 위에 만들어진 반응형 웹 프레임워크 non-blocking I/O 스트리밍 웹, 실시간 데이터 프로세싱 높은 동시성을 요구하는 대규모 어플리케이션 응답을 받을 때까지 기다리지 않아, CPU/메모리 사용량이 낮다. Spring Web : Mono and WebClient Spring Webflux : RestTemplate and ResponseEntity 출처:https://medium.com/@burakkocakeu/spring-web-vs-spring-webflux-9224260c47b5
우리회사에서 spring webflux를 사용하는 이유
현재 회사에서 Spring Webflux를 사용중입니다. 시작하면서 웹플럭스를 사용하는 이유를 말하자면 Retrofit을 이용한 외부 시스템에 의한 요청이 필요한 시스템이기 때문입니다. > 장점 spring 과 완벽한 통합, netty 지원, 비동기 non-blocking 메세지 처리, Back Pressure spring mvc 와 spring webflux 의 차이 spring mvc 1 request : 1 thread sync + blocking spring WebFlux 1 request : 1 thread sync + blocking 그래서 우리회사가 WebFlux 쓰는 이유 가게노출 시스템에 WebFlux를 도입하였는데 내용을 보면 가게노출 시스템은 배달의민족,요기요,쿠팡이츠 서버 통신 내에서 가장 많은 트래픽을 소화하는 시스템으로, 다음과 같은 리소스 최적화가 반드시 필요합니다. 하나의 사용자 요청을 처리하기 위해 수십여개의

Webflux+Spring Security+JWT Simple하게 구현하기
Servlet기반의 Spring에서 Spring Security와 JWT을 연동하여 설정하여 사용했었다. Webflux에서도 동일하게 구현가능할까 알아보았고 메소드는 조금 달랐지만 기존에 구현하였던 기능들을 구현할 수 있었다. Spring Security 설정하기 아래와 같이 Spring Security 라이브러리를 gradle에 추가한다. 아래와 같이 Security 관련 메소드들을 선언할 클래스을 하나 생성해준다. @EnableWebFluxSecurity는 Security를 활성화하겠다고 선언하는 것이다. 그리고 해당 클래스에서 SecurityWebFilterChain을 아래와 같이 Bean으로 설정해준다. Servlet기반의 Security와 가장 달랐던 부분이 바로 Session 설정 부분인데 Servlet기반의 Security에서는 sessionManagement()는 메소드를 제공해서 거기서 Session 관련 설정을 하였다. 하지만 Webflux

블로킹과 논블로킹, 동기와 비동기 - 2
블로킹과 논블로킹, 동기와 비동기 - 1에서 이어진다. Spring Blocking/Sync로 동작하는 Spring MVC와 Non-Blocking/Async로 동작하는 Spring WebFlux를 다루기 전에 Spring에 대해 간단히 알아보자. Spring Framework란? 전 포스트에서 프레임워크와 라이브러리에 대해 정리한 것이 있다. 그 포스트에서 Java기반의 프레임워크로 Spring을 언급한 적이 있다. 그렇다면, Spring Framework는 무엇일까? > 자바 플랫폼을 위한 오픈소스 애플리케이션 프레임워크로서 엔터프라이즈급 애플리케이션을 개발하기

[spring webflux] 이벤트 버스 활용하기
Intro 회사에서 진행하고 있던 프로젝트의 기능 중 하나가 유저의 추천인 코드를 업데이트 하는 것이었고 이 로직을 구현하면서 eventBus를 활용해보았습니다. 이 글은 eventBus를 만들고 활용한 예시에 대한 글이고 느낀점을 담았습니다. EventBus란? https://kwonnam.pe.kr/wiki/java/guava/eventbus 이글에 내가 작성하고 싶은 내용이 정확히 적혀있어서 가져왔다. 이글에는 아래와 같이 적혀있다. > 개발을 하다보면 본질적인 비즈니스 로직(예: 사용자 가입. 사용자정보 검증 및 DB 저장)과 비본질적인 비즈니스에 대한 후처리 로직(예: 가입 축하 Email발송, 통계 서비스에 가입자 통지 등)이 강하게 결합(Tight Coupling)하는 경우가 발생한다. 실제 비즈니스 로직과 그 후처리 로직을 완전히 분리하여 비즈

[Section 4] Project Reactor
사진은 첫 런던 여행 첫날 첫 여행지 내셔널 갤러리 시작은 순조로웠지만... 가면갈수록 Publisher와 Subscriber가 주객전도되는 것 마냥 헷갈렸다... operator 종류가 너무 많아서 힘들다ㅠㅠ Project Reactor 웹 애플리케이션 + 'Reactor` => Spring Reactive Web Application Reactor Reactive Streams 표준 사양 구현한 구현체 리액티브 프로그래밍을 위한 라이브러리 완전한 Non-Blocking 통신(요청 스레드가 차단되지❌) 지원 Publisher로 Mono[0|1] & Flux[N] 두 타입 제공 (0/1건 데이터 emit & 여러 건 데이터 emit) MSA구조(Microservice Architecture)에 적합 (Non-Blocking통신 완벽지원해서) B

Spring WebFlux (2)
WebFlux WebFlux라는 용어는 Reactor의 타입인 Flux가 Web에서 사용된다라고 말할 수 있다. 더 넓게 생각해 보면 WebFlux는 리액티브 한 웹 애플리케이션을 구현하기 위한 기술 자체를 상징하고 있다고 보는게 적절할 것이다. Spring 5부터 지원하는 리액티브 웹 애플리케이션을 위한 웹 프레임워크입니다. Spring MVC VS Spring WebFlux Spring WebFlux의 경우 Non-Blocking 통신을 지원하지만 Spring MVC의 경우 Non-Blocking이 아닌 Blocking 통신 방식을 사용합니다. Spring WebFlux의 경우 Reactive Adapter를 사용해서 Reactor 뿐만 아니라 RxJava 등

[Section 4] 리액티브 프로그래밍
시내 Hanley 구경 나갔다가 장보러가는 길에 노을이 너무 예뻐서 찍은 사진 리액티브 시작했다... 용어랑 개념만 가볍게만 배웠는데도 벌써 생소하다... 리액티브 프로그래밍 리액티스 시스템에서 사용되는 프로그래밍 모델 Message Driven↔️Non-Blocking 통신 : 유기적인 관계 리액티브 프로그래밍 : Non-Blocking 통신을 위한 프로그래밍 모델 리액티브 프로그래밍 특징 declarative data streams & propagation of change automatic propagation of the changed data flow 선언형 프로

Spring WebFlux
리액티브 시스템이란? > 반응을 잘하는 시스템을 의미합니다. 리액티브 시스템을 이용하는 클라이언트의 요청에 반응을 잘하는 시스템. 리액티브 시스템 관점에서 반응은 스레드의 Non-Blocking과 관련있습니다. > 리액티브 시스템은 클라이언트의 요청에 대한 응답 대기 시간을 최소화할 수 있도록 요청 스레드가 차단되지 않게 함으로써(Non-Blocking) 클라이언트에게 즉각적으로 반응하도록 구성된 시스템입니다. 참고자료: https://www.reactivemanifesto.org/ 위 그림은 리액티브 시스템의 설계 원칙을 그림으로 표현한 것입니다. MEANS : 리액티브 시스템에서 사용하는 커뮤니케이션 수단을 의미합니다. Message Driven : 리액티브 시스템에서는

Webflux에서 Mongo Aggregation 사용하기
MongoDB에서 RDB에서 사용하는 것처럼 collection을 join 할 수 있도록 지원하는 aggregation 기능을 제공한다. 기존 JPA에서는 native Query를 spring에서 사용할 수 있도록 @Query annotation을 지원하고, QueryDSL이라는 별도 라이브러리도 존재한다. MongoDB도 Spring에서 Aggregation을 사용할 수 있도록 @Aggregation annotation을 지원한다. Webflux와 Reactive Mongo의 개발환경 설정이 되어 있다는 전제하에 Document Entity와 Repository를 생성한다. Document Entity Repository 테스트를 위한 샘플데이터를 생성해 준다. DB에도 정상적으로 저장되었다. 임직원과 부서정보를 join에서 가져오기 위해서는 아래와 같이 Aggregation을 사용해야한다.

코드스테이츠 백엔드 부트캠프 71일차 - Spring WebFlux
Spring WebFlux Spring WebFlux는 Spring 5부터 지원하는 리액티브 웹 애플리케이션을 위한 웹 프레임워크다. Spring WebFlux는 Spring MVC 방식의 `@Controller, @RestController, @RequestMapping` 등과 같은 애너테이션을 동일하게 지원한다. Spring WebFlux는 1차로 요청을 수신한 애플리케이션에서 외부 애플리케이션에 요청을 추가적으로 전달할 때 1차로 요청을 수신한 애플리케이션의 요청 처리 쓰레드가 Blocking 되지 않는다. > WebFlux Reactor의 타입인 Flux가 Web에서 사용되는 것 Spring WebFlux 애플리케이션 vs Spring MVC 애플리케이션 기술 스택 비교 Reactive StackServlet Stack<tb

코드스테이츠 백엔드 부트캠프 70일차 - [Spring WebFlux] Project Reactor
Reactor 공부 개꿀팁...(인텔리제이 사용) 메소드 위에 마우스 올려서 마블다이어그램 확인할 때 창 분리해서 볼 수 있다. Project Reactor > Reactor 리액티브 스트림즈(Reactive Streams)를 구현한 구현체 중 하나 리액티브한 애플리케이션으로 동작하는데 있어 핵심적인 역할을 담당하는 리액티브 프로그래밍을 위한 **라

코드스테이츠 백엔드 부트캠프 69일차 - [Spring WebFlux] 리액티브 프로그래밍
[Spring WebFlux] 리액티브 프로그래밍 > 리액티브 시스템(Reactive System) 클라이언트의 요청에 반응을 잘하는 시스템 클라이언트의 요청에 대한 응답 대기 시간을 최소화 할 수 있도록 요청 쓰레드가 차단되지 않게 함으로써(Non-Blocking) 클라이언트에게 즉각적으로 반응하도록 구성된 시스템 리액티브 시스템 특징 MEANS 리액티브 시스템에서 사용하는 커뮤니케이션 수단을 의미 Message Driven 리액티브 시스템에서는 메시지 기반 통신을 통해 여러 시스템 간에 느슨한 결합을 유지 FORM 메시지 기반 통신을 통해 리액티브

Kotlin + Spring WebFlux Functional Endpoint에서 ServerSentEvent 사용법
1. 서론 Spring WebFlux를 사용하더라도 Annotation 기반의 Request Mapping을 사용하는 사례가 많다. 기능이 문제되는 점은 없고 사실 IDE의 지원도 Annotation 기반 형식이 더 좋다. 아직도 Intellij에서 Functional Endpoint를 인식해주지 못한다! 하지만 Functional Endpoint를 사용하고 싶을 때는 구글링해도 예제가 많이 없다. 실제 코드는 간단하나 관련 문서를 찾기 힘든 관계로 메모를 겸해서 구성을 포스팅한다. 2. 구성 주요 기술 스택은 다음과 같다 Spring WebFlux Kotlin Kotlin coroutine Spring Initializer에서 Reactive Web으로 구성한다. ※ Spring boot 3.x 버전은 JDK 17 이상을 요구하기에 주의한다 
Spring WebFlux 프로젝트 CloneFlix (9) - File Encrypt
지난 글에서는 MP4 To Hls 작업을 진행한 후 Nginx을 통해 hls 스트리밍을 하였다. 지난 글에서 말했듯이 Hls 스트리밍은 http 통신에서 동영상들의 조각인 ts파일들을 주고받는데 이 ts파일들은 쉽게 브라우저에서 추출할 수 있으며 다운로드가 가능하다. NetFlix, wave같은 OTT 서비스들은 자신들의 컨텐츠가 유출되지 않게 암호화 된 파일들을 http 통신을 통해 주고받는다. DRM을 사용하고 싶었지만... 첫번째 글에선 동영상에 DRM을 적용하여 스트리밍 서비스를 구축하는 것을 목표로 하였지만 알아보니 개인이 DRM을 구현한다는 것은 거의 불가능 하단 것을 알게되었다. 위는 구글에서 인수한 Widevine DRM의 구조다. 나는 처음에 DRM이라함은 단순히 암호화 된

Spring WebFlux 프로젝트 CloneFlix (8) - FFMpeg Wrapper
서비스 할 MP4 동영상을 업로드하면 어떻게 처리하여 스트리밍 할지 고민하였다. 지난 포스팅 이후 다양한 방법을 시도하였고 마침내 틀이 잡혀서 오랜만에 포스팅을 이어간다. 결론은 MP4 -> HLS -> AES-256 Encrypt -> AWS OR LOCAL NGINX Deploy였다. 따라서 위 단계를 구현하였다. 먼저 여러가지 인코딩 방법을 찾아보았고 많이 사용되는 FFMpeg 라이브러리를 사용하고자 했다. Setting FFMpeg In Spring webflux FFMpeg는 OS에서 실행되는 프로그램이기 때문에 Java 환경에서는 FFMpeg Wrapper을 매개체로 OS JAVA 간의 통신을 하여 작업을 처리를 한다. ubuntu 환경에서 apt로 설치해주면 된다. build.gradle에는 위와 같은 의존성을 추가해주었다. ffmpeg-wrapper는 위에서 말했듯이 OS JAVA 간 통신을 해주는 매개체이므로 F

Spring WebFlux
Spring WebFlux Spring WebFlux는 Spring 5부터 지원하는 리액티브 웹 애플리케이션을 위한 웹 프레임워크이다. Spring WebFlux vs Spring MVC Reactive Stack : Spring WebFlux Servlet Stack : Spring MVC |Reactive Stack|Servlet Stack| |--|--| |(1) Netty, Servlet 3.1+ Containers|Servlet Containers |(2) Reactive Streams Adapters|Servlet API |(3) Spring Security Reactive|Spring Security |(4) Spring WebFlux|Spring MVC |Spring Data Reactive Repositories - Mongo, Cassandra, Redis, Couchbase, (5) R2DBC|Spring Data Re

Spring WebFlux 프로젝트 CloneFlix with chatGPT(6) - JWT Token with Redis
지난 포스팅에선 webflux 환경에서 spring security + jwt를 통한 인증구현을 진행했었다. 이번 포스팅에선 이 인증처리를 좀 더 다듬어 보았다. 로그인 시 accessToken 뿐만 아니라 refreshToken도 같이 발급해준다. 또한 refreshToken은 화이트리스트 방식을 이용하기로 하였고 토큰을 보관하기 위해 redis를 선택하였다. Redis Setting In Webflux build.gradle에 의존성을 추가해준다. 만약 redis-server가 localhost에서 돌아가고 있으며 포트가 6379면 아무런 설정을 할 필요가 없다. 만약 redis-server가 localhost가 아닌 외부 서버나 aws 같은 cloud가 제공하는 redis를 사용한다면 configuration 클래스를 만들어주면된다. 이러면 webflux에서 redis 사용하기 준비 끝이다. Redis CRUD In Webflux redi