I/O란 무엇인가?
- 운영체제에서 I/O는 컴퓨터 시스템과 외부 장치간의 데이터 통신을 의미
- 예시
- 디스크에서 프로그램 파일을 읽어 메모리에 올리는 것
- 파일에서 데이터를 읽거나 파일에 데이터를 쓰는 것
- 데이터베이스에서 데이터를 조회하거나 추가하는 것
- 네트워크를 통해 다른 애플리케이션과 통신하는 것
- I/O 작업은 애플리케이션의 성능과 효율성에 큰 영향을 미침
Blocking I/O
- I/O 작업이 완료될 때까지 현재 스레드가 차단되어 대기하는 방식
- 즉, 스레드는 해당 작업이 끝날 때까지 다른 작업을 수행할 수 없음

Blocking I/O 예시
- 클라이언트가 서버1에 요청을 보냅니다
- 서버1은 요청을 처리하기 위해 서버2와 서버3에 순차적으로 요청을 보냄
- 서버1의 스레드는 서버2의 응답을 받을 때까지 차단됨
- 서버2의 응답을 받은 후, 서버3에 요청을 보내고, 다시 응답을 받을 때까지 차단됨
Blocking I/O의 문제점
- 자원 낭비 : 스레드가 대기 상태로 인해 CPU 자원을 활용하지 못함
- 확장성 저하 : 많은 스레드가 차단되면 시스템 자원이 고갈될 수 있음
- 높은 응답 지연 : 전체 처리 시간이 길어져 사용자 경험이 나빠짐
멀티스레딩과 Blocking I/O
Blocking I/O의 단점을 완화하기 위해 멀티스레딩 기법을 사용
- 추가 스레드를 생성하여 다른 작업을 병렬로 처리함
- 스레드 풀(Thread Pool)을 사용하여 스레드를 관리함
멀티스레딩의 한계
- 컨텍스트 스위칭 오버헤드
- 스레드 전환 시 상태 저장 및 복원에 시간이 소요됨
- 스레드 수가 많을수록 컨텍스트 스위칭 빈도가 높아짐
- 이는 전체 시스템 성능 저하로 이어짐
- 메모리 사용 증가
- 각 스레드는 자체 스택 메모리를 필요로 함
- 스레드 수가 늘어나면 메모리 소비가 증가함
- 스레드 풀의 한계
- 스레드 풀의 크기는 제한적임
- 모든 스레드가 사용 중일 때, 추가 요청은 대기해야 함
- 이는 응답 지연 및 서비스 거부로 이어질 수 있음
Non-Blocking I/O
- I/O 작업이 진행되는 동안 스레드가 차단되지 않고 다른 작업을 수행할 수 있는 방식

Non-Blocking I/O의 예시
- 서버1은 서버2와 서버3에 요청을 보낸 후, 차단되지 않고 다른 작업을 수행함
- I/O 작업이 완료되면 콜백 또는 이벤트를 통해 결과를 처리함
Non-Blocking I/O의 장점과 고려사항
장점
- 높은 자원 효율성 : 적은 수의 스레드로 많은 작업을 처리함
- 확장성 향상 : 스레드가 차단되지 않으므로 동시 처리 능력이 향상됨
- 낮은 메모리 소비 : 스레드 수가 줄어들어 메모리 사용이 감소함
고려사항
- 복잡성 증가 : 비동기 프로그래밍은 동기 방식보다 복잡함
- CPU 집약적 작업 주의 : Non-Blocking I/O에서도 CPU를 많이 사용하는 작업은 성능에 영향을 줄 수 있음
- 전체 경로의 Non-Blocking 필요 : 요청부터 응답까지 모든 요소가 Non-Blocking이어야 최대 이점을 누릴 수 있음
Spring Framework에서의 Blocking I/O와 Non-Blocking I/O
Spring MVC와 Blocking I/O
- Spring MVC는 전통적인 서블릿 기반의 웹 프레임워크
- 요청당 하나의 스레드를 할당하여 처리함
- Blocking I/O 방식으로 동작함
- 한계점
- 높은 동시성 환경에서 성능 저하
- 스레드 수 증가로 인한 자원 고갈 위험
Spring WebFlux와 Non-Blocking I/O
- Spring WebFlux는 리액티브 프로그래밍를 지원하는 웹 프레임워크
- Non-Blocking I/O 방식으로 동작함
- Netty와 같은 비동기 서버를 사용함
- 장점
- 적은 수의 스레드로 많은 요청을 처리하며 효율적임
- 대규모 트래픽 처리 및 실시간 데이터 처리에 적합함
Non-Blocking I/O를 사용해야 하는 경우
대량의 요청 트래픽이 발생하는 시스템
- 많은 동시 연결을 효율적으로 처리해야 할 때 적합
- Non-Blocking I/O는 자원 효율성을 높여줌
마이크로서비스 아키텍쳐
- 서비스 간 통신이 빈번하여 I/O 작업이 많음
- Non-Blocking I/O는 자원 효율성을 높여줌
스트리밍 또는 실시간 시스템
- 실시간 데이터 처리나 지속적인 데이터 스트림을 처리할 때 효과적
- Non-Blocking I/O는 스레드 차단 없이 데이터를 처리함
결론
- Blocking I/O는 구현이 간단하지만, 높은 동시성을 요규하는 시스템에서는 한계가 있음
- Non-Blocking I/O는 복잡도가 높지만, 자원 효율성과 성능 면에서 이점을 제공함
- Spring WebFlux와 같은 프레임워크를 활용하면 Non-Blocking I/O를 보다 쉽게 구현할 수 있음
주의사항
- Non-Blocking I/O를 사용하려면 애플리케이션의 전체적인 아키텍쳐를 고려해야 함
- 비동기 프로그래밍에 대한 이해와 숙련도가 필요함
출처 : https://velog.io/@nefertiri/Blocking-IO%EC%99%80-Non-Blocking-IO