본문으로 바로가기
반응형

안녕하세요! 오늘은 최근에 많이 이야기되는 '스프링 웹플럭스'에 대해 함께 알아보려 합니다.
비전문가 분들도 이해할 수 있도록, 쉽고 자세하게 설명해보려 합니다.
그럼 시작해볼까요?

1. 스프링 웹플럭스의 기본 개념
웹플럭스는 스프링 5에 도입된 반응형 웹 프레임워크입니다. 주로 '비동기'와 '논블로킹' 방식으로 데이터를 처리합니다. 여기서 비동기와 논블로킹이라는 단어가 나왔는데, 이게 무슨 뜻인지 간단하게 설명하겠습니다.

비동기(Asynchronous): 작업을 순차적으로 기다리지 않고, 여러 작업을 동시에 진행하는 방식을 의미합니다. 예를 들어, 집에 있는 두 개의 전화기로 동시에 두 명의 친구에게 전화를 걸 수 있는 상황을 생각해보세요. 두 전화기로 동시에 전화를 걸면서 대화를 할 수 있는 것처럼, 비동기는 여러 작업을 동시에 처리합니다.

논블로킹(Non-blocking): 한 작업이 완료될 때까지 다른 작업이 기다리지 않는 방식을 의미합니다. 예를 들어, 커피를 주문하고 바로 옆의 빵가게에서 빵을 사는 것처럼, 한 작업을 기다리지 않고 다른 작업을 진행합니다.

2. 스프링 웹플럭스의 특징: 왜 사용할까?
전통적인 웹 애플리케이션은 요청이 들어오면 그 요청을 처리하기 위해 스레드를 사용합니다. 그러나 동시에 많은 요청이 들어올 경우, 스레드의 수가 제한되어 있기 때문에 효율적인 처리가 어려울 수 있습니다. 이러한 문제점을 해결하기 위해 스프링 웹플럭스는 비동기와 논블로킹 방식을 통해 효율적으로 자원을 활용하려 합니다.

3. 데이터 스트리밍 이해하기: 1000개의 데이터 예제
이해하기 쉽게 예를 들어보겠습니다. 클라이언트가 서버에 1000개의 데이터를 요청한다고 가정해봅시다.

전통적인 방식에서는:

서버는 데이터베이스에서 1000개의 데이터를 모두 가져옵니다.
그 후 클라이언트에게 한 번에 1000개의 데이터를 전송합니다.
반면, 웹플럭스의 리액티브 방식에서는:

서버는 데이터베이스에서 데이터를 100개씩 조각내어 가져옵니다.
첫 100개의 데이터를 클라이언트에게 즉시 전송합니다.
클라이언트는 그 데이터를 받자마자 화면에 표시하거나 처리합니다.
서버는 다음 100개의 데이터를 가져와 클라이언트에게 전송합니다.
이 과정이 1000개의 데이터를 모두 전송할 때까지 반복됩니다.
이 방식의 장점은 클라이언트가 모든 데이터를 기다리지 않고, 조각난 데이터부터 빠르게 화면에 표시하거나 처리할 수 있다는 것입니다.

다음은 간단한 예제입니다.

1. 도메인 클래스: Member

public class Member {
    private String id;
    private String name;
    private int age;
    
    // getters, setters, constructor
}

2. 리포지토리 인터페이스: MemberRepository

public interface MemberRepository extends ReactiveCrudRepository<Member, String> {
    Flux<Member> findByName(String name);
}

3. 서비스 클래스: MemberService

@Service
public class MemberService {
    private final MemberRepository memberRepository;

    @Autowired
    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    public Flux<Member> findAll() {
        return memberRepository.findAll();
    }

    public Mono<Member> findById(String id) {
        return memberRepository.findById(id);
    }

    public Mono<Member> save(Member member) {
        return memberRepository.save(member);
    }

    public Mono<Void> delete(String id) {
        return memberRepository.deleteById(id);
    }
}

4. 컨트롤러 클래스: MemberController

@RestController
@RequestMapping("/members")
public class MemberController {
    private final MemberService memberService;

    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }

    @GetMapping
    public Flux<Member> list() {
        return memberService.findAll();
    }

    @GetMapping("/{id}")
    public Mono<ResponseEntity<Member>> get(@PathVariable String id) {
        return memberService.findById(id)
            .map(member -> ResponseEntity.ok(member))
            .defaultIfEmpty(ResponseEntity.notFound().build());
    }

    @PostMapping
    public Mono<Member> create(@RequestBody Member member) {
        return memberService.save(member);
    }

    @DeleteMapping("/{id}")
    public Mono<ResponseEntity<Void>> delete(@PathVariable String id) {
        return memberService.delete(id)
            .then(Mono.just(ResponseEntity.ok().<Void>build()))
            .defaultIfEmpty(ResponseEntity.notFound().build());
    }
}

이 예제에서는 웹플럭스를 사용하여 회원 관리 시스템의 주요 기능인 회원 목록 조회, 회원 상세 조회, 회원 추가 및 회원 삭제 기능을 구현했습니다. 각 함수는 Mono 또는 Flux 리액티브 타입을 반환합니다. 이를 통해 데이터가 비동기적으로 스트리밍될 수 있습니다.

스프링 웹플럭스는 현대의 빠르게 변하는 웹 환경에서 높은 효율과 성능을 제공하기 위해 탄생한 기술입니다. 오늘 포스트를 통해 그 기본적인 개념과 특징, 그리고 실제 예제를 통해 이해하셨길 바랍니다.

Random Photo

반응형