LabHub
배우기 러닝패스 코스

요청 하나가 아니라 전부가 느려졌다 · 한 줄에 선 일감 · 실습

루프가 멈춘 시간을 재는 자를 만든다

LabHub 에서 이어서 보기

목표

이벤트 루프가 얼마나 오래 멈춰 있었는지를 재는 자를 직접 만들고, 동기
작업 한 번이 그 프로세스의 모든 요청을 어떻게 함께 늦추는지 숫자로 확인합니다.

왜 중요한가

"API 가 느려요" 라는 신고가 들어오면 대개 그 API 의 코드를 먼저 봅니다. 그런데
Node 에서는 범인이 다른 곳에 있는 경우가 잦습니다. 자바스크립트를 실행하는
줄은 하나뿐이라, 어떤 요청 하나가 그 줄을 300ms 붙잡으면 그 시간 동안 도착한
모든 요청이 함께 300ms 늦습니다. 느려진 API 의 코드에는 아무 문제가 없습니다.

그래서 이 코스의 첫 도구는 프로파일러가 아니라 입니다. 일정한 간격으로
울리게 해 둔 타이머가 얼마나 늦게 울렸는지를 보면, 그 사이에 루프가 남의 일에
붙잡혀 있던 시간이 나옵니다. 평균은 거의 움직이지 않고 꼬리만 움직인다
것이 이 분포의 핵심이고, 평균만 보는 대시보드가 이 사고를 못 잡는 이유입니다.

단계

1. /root/work/loop/lag.mjspct(samples, p) 를 만듭니다.
2. 같은 파일에 sample({durationMs, intervalMs}) 를 만듭니다.
3. 아무 일도 시키지 않고 재어 /root/work/loop/report.jsonruns.idle 에 적습니다.
4. blockFor(ms) 를 만들고, 재는 도중에 한 번 막아 runs.blocked 에 적습니다.
5. 100ms 를 넘긴 표본의 개수와 비율, 그리고 평균을 runs.blocked 에 더합니다.
6. queue({n, serviceMs, blockAt, blockMs}) 로 요청 여럿을 한꺼번에 처리해
runs.queue 에 적습니다.
7. verdict(run, budgetMs) 로 예산을 넘긴 표본을 세는 규칙을 만듭니다.

참고

단계 7개

  1. 백분위부터 못 박는다
  2. 타이머가 늦은 만큼이 루프가 멈춘 시간이다
  3. 아무 일도 없을 때의 기준선
  4. 한 번 막고 다시 잰다
  5. 평균은 왜 아무 말도 하지 않는가
  6. 느려진 것은 한 요청이 아니었다
  7. 잰 것을 판단으로 바꾼다