티스토리 뷰
Sync/Async, Blocking/Non-Blocking
Multi Thread WAS vs Single Thread WAS
- 사전지식 : Process vs Thread
- 멀티 스레드로 잘 서비스하던 어느날, 갑자기 10k(1만명)를 동시에 서비스할 일이 생겼다. 일명 C10K Problem. 1만명 동접이 가능하려면 어떻게 해야할까? 자바의 대표 멀티 스레드 서버인 톰캣은 기본 max-thread가 200밖에 되지 않는다 !
- 10k를 멀티 스레드로 구현할 경우, 가장 큰 문제는 Context-Switching 비용
- -> Single Thread + Non-Blocking + Async 구조면 가능하지 않을까? 이들에 대해 알아보자.
애플리케이션 개발에서의 sync vs async
먼저, [애플리케이션 개발에서의 sync vs async]와 [Sync/Async, Blocking/Nonblocking에서의 sync vs async]는 다르다
물건 주문에 0.5초 메일발송에 2초 걸린다면, sync는
mailService.sendMail();
을 호출하고 기다려 0.5 + 2 = 2.5초 걸린다. 반면 메일발송을 async처리하면 기다리지않고 바로 리턴해 0.5+a초 걸린다.Spring의 비동기 처리 :
@Async
,@EnableAsync
void order() { // 주문 처리 코드 생략 mailService.sendMail(); }
public class MailService { @Async void sendMail() { // 메일 발송 } }
@Configuration @EnableAsync public class SpringAsyncConfig { @Bean(name = "threadPoolTaskExecutor") public Executor threadPoolTaskExecutor() { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); taskExecutor.setCorePoolSize(3); taskExecutor.setMaxPoolSize(30); taskExecutor.setQueueCapacity(10); taskExecutor.setThreadNamePrefix("Executor-"); taskExecutor.initialize(); return taskExecutor; } }
- 앞서 애플리케이션 개발에서의 Sync/Async가 애플리케이션 코드 관점이었다면, 이번엔 IO 처리 관점 (파일IO, 소켓IO 등...)
Socket IO의 발전과정
- 멀티 프로세스 서버 - Process vs Socket = 1 vs 1
- 멀티 쓰레드 서버 - Thread vs Socket = 1 vs 1
- I/O 멀티플렉싱(multiplexing) 기법 도입 - Thread vs Socket = 1 vs n
- select > poll > epoll/IOCP/Kqueue
- https://jongmin92.github.io/2019/02/28/Java/java-with-non-blocking-io/
- *"각 클라이언트 요청마다 별도의 스레드를 생성함으로써 프로세스를 생성하던 방법보다 리소스의 비용을 줄일 수 있었고, 스레드들이 서로 공유하는 메모리를 가질 수 있는 환경이 되었습니다. 그러나 I/O 멀티플렉싱(multiplexing) 기법을 사용한다면, 각 클라이언트 마다 별도의 스레드를 생성하는 것이 아닌 하나의 스레드에서 다수의 클라이언트에 연결된 소켓(파일 디스크립터)을 괸리하고 소켓에 이벤트(read/write)가 발생할 경우에만 별도의 스레드를 만들어 해당 이벤트를 처리하도록 구현할 수 있습니다."*
- 즉, Socket I/O를 송수신하는 부분과 I/O 데이터를 활용해 로직을 처리하는 부분을 분리하는 것이 가능해졌다. IO 모델을 어떻게 설계해야 다수의 socket을 처리하는 가장 좋은 효율과 성능을 낼 수 있을까?
Sync/Async, Blocking/Non-Blocking 차이
Boost application performance using asynchronous I/O 문서와 Blocking-NonBlocking-Synchronous-Asynchronous 문서를 기반으로 설명
Blocking/NonBlocking은 I/O를 담당하는 함수를 호출했을 때 바로 리턴하느냐 마느냐가 관심사다.
Synchronous/Asynchronous는 I/O를 담당하는 함수의 작업 완료 여부를 누가 신경쓰냐가 관심사다.
Blocking/NonBlocking은 직관적으로 와닿는데, Synchronous/Asynchronous는 바로 이해되진 않는다
- 호출되는 함수에게 callback을 전달해서, 호출되는 함수의 작업이 완료되면 호출되는 함수가 전달받은 callback을 실행하고, 호출하는 함수는 작업 완료 여부를 신경쓰지 않으면 Asynchronous다.
- 호출하는 함수가 호출되는 함수의 작업 완료 후 리턴을 기다리거나, 또는 호출되는 함수로부터 바로 리턴 받더라도 작업 완료 여부를 호출하는 함수 스스로 계속 확인하며 신경쓰면 Synchronous다.
- 아래 그림을 보면, Sync는 애플리케이션이 관심을 갖고 계속 확인하고 있는 반면, Async는 신경쓰지 않고 중간에 다른 일(other processing)을 하고 있다.
- 웹에서 Polling(Sync와 개념적으로 비슷)과 Push(Async와 개념적으로 비슷)
- Web Polling은 일정 주기로 서버에 변경사항이 생겼는지 주기적으로 체크하는 방식
- Web Push는 서버에 변경사항이 발생할 경우 서버에서 클라이언트로 응답
4가지 구분
- Blocking=Sync, Non-Blocking=Async가 아니다! 4가지는 다른 개념이다.
- Sync/Blocking IO
- Ex) 멀티 스레드 서버 (Thread vs Socket = 1 vs 1)
- Sync/Non-Blocking IO
- Ex) select(), epoll() 함수
- Ex) future.isDone()
- Async/Non-Blocking IO (AIO)
- Ex) Window IOCP
- Async/Blocking IO
- 이와 같은 사례는 거의 없어 무시 가능
- Ex) Node.js + MySQL 조합
- "Blocking-Async는 별다른 장점이 없어서 일부러 사용할 필요는 없지만, NonBlocking-Async 방식을 쓰는데 그 과정 중에 하나라도 Blocking으로 동작하는 놈이 포함되어 있다면 의도하지 않게 Blocking-Async로 동작할 수 있다."
참고자료
11.12 Pobi 강의자료 ★★★
Boost application performance using asynchronous I/O 문서와 Blocking-NonBlocking-Synchronous-Asynchronous 문서 ★★★
추가 읽을거리
본 주제와 관련한 예전 글들은 IBM 블로그를 기준으로 하는게 많은데, IBM 블로그의 정보가 더이상 정확하지 않아 애매한 부분이 있는듯 함.
Node.js vs Spring WebFlux
Node.js
- 싱글 스레드 기반 비동기 IO 서버
- (대충 풀어서 설명하면) 싱글 스레드인만큼 요청이 막 들어온다ㄱㄱ 중간에 오래걸리는 작업들(File, Network, DB 작업 등)은 워커로 보내 별도 스레드로 돌리고 다음 요청을 바로 이어 진행한다(비동기). 이벤트 루프는 계속 돌면서 완료된 작업은 이벤트 큐에서 콜백 함수를 하나씩 빼 실행한다.
- https://sjh836.tistory.com/79
- https://medium.com/@rpf5573/nodejs-event-loop-part-1-big-picture-7ed38f830f67
- 키워드
- 이벤트 루프, 이벤트 큐, 콜백 함수
- V8 엔진,
libuv
(Reactive) Spring WebFlux
- vs
Spring MVC
- Spring MVC는 Servlet기반의 본질적으로 sync/blocking 방식이다. 따라서 스프링도 Reactive Programming을 지원하기 시작
- 아직 Jdbc는 sync/blocking 방식으로 동작해서, 컨트롤러에서 비동기로 빠르게 받아도 뒷에서 DB작업 가면 성능 하락. 즉 Spring WebFlux를 통해 이제 스프링도 비동기를 지원하지만, 아직은 노드에 딸리는 현실. 따라서 앞쪽은 노드, 뒷쪽은 스프링으로 구성하기도. 나온지 얼마 안되었고 빠르게 성장하고 있다. R2DBC 등 나중에 스프링에서도 안정화되면 Reactive기반 개발이 활성화될듯함.
- 노드와의 비교
- node.js: single thread + event loop
- spring webflux: worker thread default size는 서버의 core 개수로 설정 + event loop
- CPU core 개수에 따라 node.js는 서버를 여러대(별도의 프로세스)를 동작시키는 방식으로 확장하고, Spring Webflux는 서버 한대(하나의 프로세스)에 여러 개의 worker thread를 생성하는 방식
- RestTemplate vs WebClient
- RestTemplate : Sync/Blocking
- WebClient : Non-Blocking
- 역시 점점 WebClient 사용 확대 추세
'Etc' 카테고리의 다른 글
비전공자를 위한 개발 입문 정보 (0) | 2021.02.15 |
---|---|
노션(Notion)을 활용한 개발자 이력서 관리 (0) | 2019.12.03 |
API vs Library vs Framework 차이 (0) | 2019.09.26 |
IntelliJ(인텔리제이) 한글 깨지는 이슈 (0) | 2019.09.19 |
Window SMTP Server 메일전송 (0) | 2019.09.11 |
- Total
- Today
- Yesterday
- brute-force
- graph
- 리버싱
- 해외여행
- Vo
- dfs
- webhacking.kr
- socket
- 프로그래머스
- 개발자
- Java
- Algorithm
- 우아한 테크코스
- OneToMany
- Stack
- mysql
- bfs
- sort
- Android
- C
- Data Structure
- 회고
- 웹해킹
- javascript
- reversing
- FRAGMENT
- Android Studio
- JPA
- queue
- git
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |