동기와 비동기, 블로킹과 논블로킹은 웹 서버에서 중요한 개념이다.
이 둘에 대해 알아보자
동기 / 비동기
동기와 비동기는 작업을 순차적으로 수행할지, 들어오는대로 수행할지에 대한 관점이고,
동기 (Synchronous)
작업이 지정한 순서대로 실행되며, 이전 작업이 완료될 때까지 다음 작업이 대기하는 방식
- 작업 간 의존성이 높다.
- 앞선 작업이 시간이 길어질 경우, 다른 작업이 지연된다.
비동기 (Asynchronous)
작업이 독립적으로 실행되며, 다른 작업이 실행되는 동안 기다리지 않고 진행하는 방식
블로킹 / 논블로킹
블로킹과 논블로킹은 처리해야 하는 작업을 막을 것인지 아닌지에 대한 관점이다.
블로킹 (Blocking)
작업을 요청한 상태에서 응답이 올 때까지 현재 스레드를 멈추는 방식
응답이 늦어질 수록 CPU 자원을 낭비하고, 다른 작업도 지연 시키는 것
논블로킹 (Nonblocking)
작업을 요청한 후 즉시 결과를 반환하고, 작업이 완료되지 않아도 다른 작업을 수행하는 방식
요청한 작업을 완료하면 콜백 또는 이벤트를 보내 처리한다.
비동기와 논블로킹?
이러면 비동기와 논블로킹의 차이가 무엇인지 궁금해지기 시작한다.
이 둘은 개념이 비슷한 느낌이어서 종종 혼용되어 사용된다고 한다.
하지만 확실히 다른 개념인 것
두 개가 각자 어떤 맥락에서 사용되는지에 대해 알아야 한다.
- 비동기
작업이 독립적인 프로세스나 스레드에서 실행
작업의 실행 흐름에 초점을 둔다
- 논블로킹
현재 실행 중인 스레드가 응답을 기다리지 않고 바로 다른 작업 실행
현재 스레드의 상태에 초점을 둔다.
비동기
음식 주문을 하고, 다른 일을 하는 동안 음식이 준비되면 알림(콜백)을 받습니다. 알림이 올 때까지 음식 준비 상태를 신경 쓰지 않아도 됩니다.
논블로킹
음식 주문을 하고, 음식이 나올 준비가 안 되어 있으면 다른 일을 먼저 처리합니다. 음식이 준비된 상태를 직접 확인해야 합니다.
(사실 엄청 와닿지는 않는다...)
동작 방식
동기와 비동기, 블로킹과 논블로킹
이 네 개를 섞어서 네 가지의 동작 방식을 만들 수 있다.
하나하나 살펴보자
동기 + 블로킹
- 요청이 들어오면 작업의 실행 시간과 종료 시간은 요청 흐름에 따라 보장 (동기)
- I/O 작업이 발생하면 작업이 완료될 때까지 대기 (블로킹)
- 작업이 종료된 후 결과 반환
동기 + 논블로킹
- 요청이 들어오면 작업의 실행 시간과 종료 시간은 요청 흐름에 따라 보장 (동기)
- I/O 작업이 발생하면 작업의 상태를 반복적으로 확인 (논블로킹)
2-1. 반환 여부와 관계없이 Kernel은 작업을 진행하며, 작업 중간 상태를 즉시 Application에 반환
2-2. Application은 다른 작업을 계속 수행하면서, Kernel에서 상태를 지속적으로 확인
- I/O 작업이 종료되면 Application으로 반환됨
- 작업이 종료된 후 결과 반환
비동기 + 논블로킹
- 파랑색 요청이 들어오면 작업 실행 시간과 종료 시간은 보장 못 함 (비동기)
- I/O 작업이 발생하면 즉시 반환되며, 작업을 백그라운드에서 처리 (논블로킹)
2-1. 반환 여부와 상관없이 Kernel이 작업 상태를 Application에 바로 전달
- 주황색 요청이 들어오고, Application은 동시에 다른 작업을 수행
3-1. Kernel은 두 요청의 작업 상태를 지속적으로 확인
- I/O 작업이 종료되면 각각의 결과가 콜백이나 이벤트를 통해 Application에 반환
- 주황색 요청 결과 반환
- 파랑색 요청 결과 반환
비동기 + 블로킹
이 경우는 비효율적이어서 모델도 없다.
선택 기준
그러면 어떤 상황에서 무엇을 선택해야 할까
- 작업의 성격
작업 간 의존성이 높은 경우 - 동기
작업이 독립적이고 병렬 처리가 필요한 경우 - 비동기
- 성능 요구
응답 시간이 중요하지 않은 경우 - 블로킹
사용자 경험과 실시간 응답성이 중요한 경우 - 논블로킹
- 복잡도
코드 단순성 중요 - 동기 + 블로킹
성능 최적화 중요 - 비동기 + 논블로킹
상황에 맞는 조합을 잘 선택하면, 효율적이고 확장 가능한 애플리케이션 설계를 할 수 있다!
출처
비동기와 논블로킹