[WebFlux] publishOn과 subscribeOn

회사에서 WebFlux로 개발하면서 publishOn과 subscribeOn의 사용법이 매번 헷갈려서 최대한 간단하게 정리를 해봤다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Flux.range(1,3)
.subscribeOn(Schedulers.newBoundedElastic(1,1,"sub2"))
.doOnNext(i -> log.info("main 1: {}, number: {}", Thread.currentThread().getName(), i))
.publishOn(Schedulers.newBoundedElastic(1,1,"pub1"))
.doOnNext(i -> log.info("main 2: {}, number: {}", Thread.currentThread().getName(), i))
.subscribeOn(Schedulers.newBoundedElastic(1,1,"sub1"))
.subscribe();

// log
main 1: sub2-3, number: 1
main 1: sub2-3, number: 2
main 1: sub2-3, number: 3
main 2: pub1-2, number: 1
main 2: pub1-2, number: 2
main 2: pub1-2, number: 3

subscribeOn

subscribeOn은 호출된 곳의 앞쪽 publisher 체인과 뒷쪽의 subscriber 체인을 한꺼번에 별도의 스레드로 분리한다.
느린 publisher 와 빠른 subscriber 의 조합에서 쓰기 적합하다고 하는데… 무슨 말인지 잘 모르겠다. 외부서비스에서 데이터를 읽어올때 쓰기 좋다고 한다.

위 예시처럼 subscribeOn을 동일한 체인에서 중첩해서 사용할 경우
첫번째 subscribeOn 앞뒤 체인을 묶어서 sub2 스케줄러에서 담당하고
두번째 subscribeOn 앞뒤 체인을 묶어서 sub1 스케줄러가 담당해야 하지만 이미 sub2에서 담당해서 그대로 sub2로 돌게 된다.

publishOn

publishOn은 호출된 곳의 앞쪽 publisher 체인은 그대로 두고 뒷쪽 subscriber 체인만 별도의 스레드로 분리한다.
빠른 publisher와 느린 subscriber 일때 쓰기 좋다고 하고 외부서비스로 데이터를 쓰는 작업할 때 좋닫고 한다.
위 예시에서 subscribeOn으로 sub2 스레드에서 돌다가 publishOn을 만나면서 pub1 스케줄러에 작업을 할당하고 나머지 연산을 진행한다.

🔗 출처
Reactor Flux의 publishOn subscribeOn을 이용한 스케쥴링

Spring Framework란 무엇인가

기초가 부족한 관계로 기초부터 다시 정리도 하는 겸사겸사 첫주제는 spring framework로 정했다.

Srping Framework란

스프링 프레임워크(Spring Framework)는 자바 플랫폼을 위한 오픈 소스 애플리케이션 프레임워크로 간단히 스프링(Spring)이라고도 한다. 동적인 웹 사이트를 개발하기 위한 여러 가지 서비스를 제공하고 있다.

대한민국 공공기관의 웹 서비스 개발 시 사용을 권장하고 있는 전자정부 표준프레임우커의 기반 기술로서 쓰이고 있다.

특징

  1. 크기와 부하의 측면에서 경량 컨테이너로서 자바 객체를 직접관리한다.

    • 객체 생성, 소멸과 같은 라이프 사이클을 관리하며 스프링으로부터 필요한 객체를 얻어올 수 있다
  2. 제어 반전 혹은 제어 역행(IoC: Inversion of Control)을 지원한다.

    • 컨트롤의 제어권이 사용자가 아닌 프레임워크에 있어서 필요에 따라 스프링에서 사용자의 코드를 호출한다.
    • IoC는 DI와 DL에 의해 구현된다.
      • DL(Dependency Lookup) : 의존성 검색
        • 컨테이너에서는 객체들을 관리하기 위해 별도의 저장소에 빈을 저장하는데 저장소에 저장되어 있는 개발자들이 컨테이너에서 제공하는 API를 이용하여 사용하고자 하는 빈을 검색하는 방법
      • DI(Dependency Injection) : 의존성 주입
        • 의존성 주입이란 객체가 서로 의존하는 관계가 되게 의존성을 주입하는 것으로 객체지향 프로그램에서 의존성이란 하나의 객체가 어떠한 다른 객체를 사용하는 것을 의미한다.
        • IoC에선 각 클래스 사이에 필요로 하는 의존관계를 빈 설정 정보를 바탕으로 컨테이너가 자동으로 연결해 주는 것을 말한다.
  3. POJO(Plain Old Java Object) 방식의 프레임워크이다.

    • 직역하면 오래된 방식의 간단한 자바 오프젝트라는 말이다.

    • 일반적인 J2EE 프레임워크에 비해 구현을 위하여 특정한 인터페이스를 구현하거나 상속을 받을 필요가 없어 기존에 존재하는 라이브러리 등을 지원하기에 용이하고 객체가 가볍다.

    • 쉽게 이야기하면 getter/setter 메소드로 이루어진 Java Benas를 생각하면 된다.

    • 예를 들어 자바 서블릿 코드를 작성할 때는 보통 HttpServlet을 상속받아야 한다.

      1
      2
      3
      public TestServlet extends HttpServlet {
      ...
      }

      이처럼 서블릿 프로그래밍을 하는 것만으로 객체지향 프로그래밍의 가장 핵심적인 기능 중 하나인 상속을 할 수 없고 HttpServlet에서 제공하는 기능을 어떻게 재사용할 것인지 판단해야하는 부분도 생겼다.

    • POJO는 이러한 제약이 없는 일반적인 객체를 말하는데 여기서 상속이나 인터페이스 구현을 사용하지 않는 객체가 아니라 어떠한 라이브러리나 프레임워크 등 자바 언어 사양 외에 어떠한 제한을 강제받지 않는 자바 오브젝트를 뜻하는 것이다.

  4. 관점 지향 프로그래밍(AOP: Aspect Oriented Programming)을 지원한다.

    • 기존의 객체지향 프로그래밍(OOP: Object Oriented Programming) 에서는 객체의 재사용으로 인해 반복되는 코드의 양을 줄일 수 있었지만 여전히 많은 부분에서 중복된 코드가 발생한다.
    • 예를 들어 로그, 권한 체크, 인증, 예외 처리와 같은 소스상에서 반복될 수 밖에 없는 필수적인 요소들로 코드의 가독성이나 유지보수적인 측면에서 좋지 않았다.
    • AOP는 OOP를 대체하는 개념이 아닌 OOP를 좀 더 OOP처럼 사용하기 위하여 보완하는 개념으로 공통적으로 반드시 필요하지만 중복해서 작성해야하는 핵심 이외의 코드들을 외부로 분리하여 관리한다.
    • 이렇게 외부에서 관리하는 공통기능을 핵심 로직에 영향을 끼치지 않게 잘 끼워넣어 개발하면 무분별하게 중복되는 코드를 제거하면서 공통기능의 수정을 통해 모든 핵심 로직의 공통기능을 수정하여 효율적인 유지보수가 가능해지면서 재활용성이 극대화된다.
    • 즉, 위에서 예를 들었던 트랜잭션이나 로깅, 보안과 같이 여러 모듈에서 공통적으로 사용하는 기능의 경우 분리하여 관리할 수 있다는 것이다.
  5. MVC (Model2)

    • MVC는 Model, View, Controller 를 뜻하며 사용자 인터페이스와 비즈니스 로직을 분리하여 개발하는 것으로 웹 프로그래밍 개발에선 거의 표준처럼 사용되고 있으며 일반적으로 Model2를 지칭한다.
      • Model은 데이터를 처리하는 영역
      • View는 렌더링되서 실제로 보이는 화면
      • Controller는 사용자의 요청을 받고, 응답을 주는 로직을 담당
    • 이처럼 소스를 분리하여 각 소스의 목적을 명확히하면 모듈화를 통해 재사용성을 늘리고 유지보수를 쉽게 할 수 있으며 확정성도 좋은 장점이 있다.
    • 간단한 흐름을 살펴보면 요청 -> 컨트롤러 -> 모델 -> 컨트롤러 -> 뷰 의 흐름이라고 생각하면 된다.
      (MVC와 관련된 자세한 내용은 추후 기회가 된다면 별도로 포스트하겠다.)

이상으로 스프링 프레임워크의 특징에 대하여 대략적으로 정리를 해보았다.


Reference