serversim
학습시뮬레이터템플릿가격
…
…
메뉴 열기
학습↗시뮬레이터↗템플릿↗가격↗
내 Documents문서
목차/16단원16 / 16

종합 — 같은 일, 네 가지 방법

같은 일을 네 가지 방법으로 시키면 무엇이 얼마나 달라질까요? 같은 손님 24명을 창구 하나에서 네 가지 방식으로 받아 보고, 걸린 시간과 치른 비용을 나란히 적어 둔 표입니다.

기초에서 먼저 보기서버가 바쁘면 왜 요청이 밀릴까?→

아래 표의 숫자는 손으로 쓴 값이 아니라, 이 시리즈가 사용한 시뮬레이터를 실제로 실행해 얻은 결과입니다. 스레드 하나(7단원의 세계)에서 시작해 스레드풀 4개와 64개(10단원), 그리고 이벤트루프(11단원)까지 같은 조건에서 비교합니다.

① 무엇을 보면 되나

총시간(makespan)은 24개를 전부 끝내는 데 걸린 시간, 갈아타기는 컨텍스트 스위치 횟수, 메모리는 스레드 스택이 차지한 양, CPU 활용률은 코어가 실제로 일한 비율입니다. 스레드 1개는 압도적으로 느리고, 4개로 늘리면 크게 좋아지며, 64개로 늘려도 총시간은 더 이상 줄지 않지만 메모리는 16배가 됩니다.

② 그래서 무엇을 골라야 하나

요청당 계산이 가볍고 동시 접속이 아주 많다면 이벤트루프 계열이 메모리에서 압도적으로 유리합니다. 반대로 무거운 계산이 섞이거나 블로킹 라이브러리를 피할 수 없다면 스레드풀이 훨씬 안전합니다(13·14단원의 함정을 피할 수 있으니까요). 정답은 하나가 아니라 워크로드에 달려 있습니다.

③ 총시간만 보면 놓치는 것

표의 총시간은 스물네 개를 전부 끝내는 데 걸린 시간입니다. 하지만 사용자는 전체가 아니라 자기 요청 하나만 경험합니다. 그래서 실무에서는 요청별 지연시간의 분포를 봅니다. 먼저 도착한 요청은 큐를 거치지 않아 빠르고, 뒤에 온 요청은 큐에서 기다린 시간이 그대로 더해집니다. 평균만 보면 이 차이가 사라지기 때문에 꼬리 쪽, 즉 p99를 따로 보는 것입니다.

④ 스레드를 64개로 늘려도 총시간이 거의 그대로인 이유

동시에 처리 중인 요청 수는 처리율과 응답시간의 곱과 같습니다. 여기서 처리율의 상한을 정하는 것은 코어입니다. 코어가 이미 포화라면 스레드를 늘려도 처리율은 그대로이고, 늘어난 것은 동시에 대기 중인 요청 수뿐입니다. 그 결과 응답시간만 길어집니다. 표에서 스레드 4개와 64개의 총시간이 거의 같은데 메모리만 16배인 것이 정확히 이 현상입니다.

⑤ 그래서 실무에서는 이렇게 고른다

세 가지를 봅니다. 첫째, 요청 하나가 CPU를 얼마나 쓰는가. 계산이 가볍고 기다림이 대부분이면 이벤트루프 계열이 유리합니다. 둘째, 피할 수 없는 블로킹 라이브러리가 있는가. 있다면 스레드풀이 안전합니다. 셋째, 팀이 그 모델을 관측하고 디버깅할 수 있는가. 스택 추적이 끊기는 비동기 코드는 장애 시간에 비용을 청구합니다.

modelmakespan갈아타기(스위치)스레드 메모리CPU 활용률
스레드풀 · 1192.0 tu01.025%
스레드풀 · 465.8 tu454.073%
스레드풀 · 6462.1 tu4764.077%
이벤트루프 · 148.0 tu01.1100%

시뮬레이터에서 해보기

  1. 1.'3-tier 기본' 프리셋으로 이 시리즈를 마무리합니다. client 노드의 RPS를 1,000(Spring CPU 63%) → 1,700(CPU 99%, KPI 패널 p99 291ms) → 2,000(queue-full, Success 89.2%)으로 올려 보세요 — 지금까지 배운 CPU·메모리·스레드·대기가 전부 이 슬라이더 하나 위에서 겹쳐 일어납니다.
  2. 2.MySQL은 같은 mix로 ≈8,800 RPS까지 버팁니다(앱 상한의 5배) — Spring의 Instances를 6으로 늘려야 비로소 MySQL 카드의 CPU가 100%에 닿습니다. 병목이 어디서 다음 병목으로 넘어가는지, 지금까지 본 단원들이 카드 하나하나에 다 들어 있습니다.
시뮬레이터에서 실험해보기 →

이 단원의 용어

makespan
주어진 작업 전부를 끝내는 데 걸린 총 시간.
CPU 활용률
전체 시간 중 코어가 실제로 계산에 쓰인 비율.
리틀의 법칙
동시 처리 수 = 처리율 × 응답시간. 적정 동시성을 계산하는 근거.
p99
가장 느린 1%의 지연시간. 평균이 숨기는 사용자 경험이 여기 있다.

왜 이렇게 발전했나

이 표의 네 행은 사실 서로 다른 네 가지 기술이 아니라, 하나의 질문에 대한 네 가지 답입니다 — 기다리는 동안 무엇을 붙잡아 둘 것인가. 스레드 하나는 아무것도 겹치지 않으니 가장 단순하지만 가장 느립니다. 스레드풀은 기다림마다 스택 한 벌을 붙여서 겹칩니다 — 코드가 그대로라는 것이 장점이고, 메모리가 대가입니다. 이벤트루프는 기다림에 아무것도 붙이지 않고 커널의 통지 목록에 등록만 합니다 — 메모리가 거의 들지 않는 대신, 모두가 빨리 양보한다는 약속을 지켜야 합니다. 코루틴과 가상 스레드는 이 세 번째 답을 유지하면서 코드 모양만 첫 번째로 되돌린 것입니다. 그래서 이 선택은 성능 비교가 아니라 비용 구조의 선택입니다. 무엇이 비싼 팀인지, 무엇이 비싼 서비스인지가 답을 정합니다.

모델 선택 = 기다림을 어디에 둘 것인가, 그리고 무엇을 지불할 것인가.

← 이전 단원

15단원. 어떻게 여기까지 왔나 — 60년의 발전사